Пример #1
0
 def init_args(self, arg_str, fh):
   # Tripos makes the input line available as buffered input for ReadItem()
   fh.setbuf(arg_str)
   # alloc and fill arg buffer
   self.arg_len  = len(arg_str)
   self.arg = self.ctx.alloc.alloc_memory(self.bin_basename + "_args", self.arg_len + 1)
   self.arg_base = self.arg.addr
   self.ctx.mem.w_cstr(self.arg_base, arg_str)
   log_proc.info("args: '%s' (%d)", arg_str[:-1], self.arg_len)
   log_proc.info(self.arg)
Пример #2
0
 def init_args(self, arg_str, fh):
   # Tripos makes the input line available as buffered input for ReadItem()
   fh.setbuf(arg_str)
   # alloc and fill arg buffer
   self.arg_len  = len(arg_str)
   self.arg = self.ctx.alloc.alloc_memory(self.bin_basename + "_args", self.arg_len + 1)
   self.arg_base = self.arg.addr
   self.ctx.mem.w_cstr(self.arg_base, arg_str)
   log_proc.info("args: '%s' (%d)", arg_str[:-1], self.arg_len)
   log_proc.info(self.arg)
Пример #3
0
 def init_stack(self, stack_size):
   self.stack_size = stack_size
   self.stack = self.ctx.alloc.alloc_memory( self.bin_basename + "_stack", self.stack_size )
   self.stack_base = self.stack.addr
   self.stack_end = self.stack_base + self.stack_size
   log_proc.info("stack: base=%06x end=%06x", self.stack_base, self.stack_end)
   log_proc.info(self.stack)
   # prepare stack
   # TOP: size
   # TOP-4: return from program
   self.stack_initial = self.stack_end - 4
   self.ctx.mem.w32(self.stack_initial, self.stack_size)
   self.stack_initial -= 4
Пример #4
0
 def init_cwd(self, cwd, cwd_lock):
   self.cwd = cwd
   if cwd is not None and cwd_lock is None:
     lock_mgr = self.ctx.dos_lib.lock_mgr
     dos_list = self.ctx.dos_lib.dos_list
     entry = dos_list.get_entry_by_name('root')
     lock = entry.locks[0]
     self.cwd_lock = lock_mgr.create_lock(lock, cwd, False)
     log_proc.info("current dir: cwd=%s create lock=%s", cwd, self.cwd_lock)
     self.cwd_shared = False
   else:
     self.cwd_lock = cwd_lock
     self.cwd_shared = True
     log_proc.info("current dir: cwd=%s shared lock=%s", cwd, self.cwd_lock)
Пример #5
0
 def init_cwd(self, cwd, cwd_lock):
   self.cwd = cwd
   if cwd is not None and cwd_lock is None:
     lock_mgr = self.ctx.dos_lib.lock_mgr
     dos_list = self.ctx.dos_lib.dos_list
     entry = dos_list.get_entry_by_name('root')
     lock = entry.locks[0]
     self.cwd_lock = lock_mgr.create_lock(lock, cwd, False)
     log_proc.info("current dir: cwd=%s create lock=%s", cwd, self.cwd_lock)
     self.cwd_shared = False
   else:
     self.cwd_lock = cwd_lock
     self.cwd_shared = True
     log_proc.info("current dir: cwd=%s shared lock=%s", cwd, self.cwd_lock)
Пример #6
0
def run_command(scheduler,
                process,
                start_pc,
                args_ptr,
                args_len,
                stack_size,
                reg_d1=0):
    ctx = process.ctx
    alloc = ctx.alloc
    new_stack = Stack.alloc(alloc, stack_size)
    # save old stack
    oldstack_upper = process.this_task.access.r_s("pr_Task.tc_SPLower")
    oldstack_lower = process.this_task.access.r_s("pr_Task.tc_SPUpper")
    # activate new stack
    process.this_task.access.w_s("pr_Task.tc_SPLower", new_stack.get_upper())
    process.this_task.access.w_s("pr_Task.tc_SPUpper", new_stack.get_lower())
    # NOTE: the Manx fexec and BPCL mess is not (yet) setup here.

    # setup sub task
    sp = new_stack.get_initial_sp()

    # new proc registers: d0=arg_len a0=arg_cptr
    # d2=stack_size.  this value is also in 4(sp) (see Process.init_stack), but
    # various C programs rely on it being present (1.3-3.1 at least have it).
    set_regs = {
        REG_D0: args_len,
        REG_D1: reg_d1,
        REG_A0: args_ptr,
        REG_D2: stack_size,
        REG_A2: ctx.odg_base,
        REG_A5: ctx.odg_base,
        REG_A6: ctx.odg_base,
    }
    get_regs = [REG_D0]
    task = Task("RunCommand", start_pc, new_stack, set_regs, get_regs)

    # run sub task
    scheduler.run_sub_task(task)

    # return value
    run_state = task.get_run_state()
    ret_code = run_state.regs[REG_D0]
    log_proc.info("return from RunCommand: ret_code=%d", ret_code)

    # restore stack values
    process.this_task.access.w_s("pr_Task.tc_SPLower", oldstack_lower)
    process.this_task.access.w_s("pr_Task.tc_SPUpper", oldstack_upper)

    # result code
    return ret_code
Пример #7
0
def run_sub_process(scheduler, proc):
  log_proc.info("start sub process: %s", proc)

  task = proc.get_task()

  scheduler.add_task(task)

  # return value
  run_state = task.get_run_state()
  ret_code = run_state.regs[REG_D0]
  log_proc.info("return from sub process: ret_code=%d", ret_code)

  # cleanup proc
  proc.free()

  return ret_code
Пример #8
0
def run_sub_process(scheduler, proc):
    log_proc.info("start sub process: %s", proc)

    task = proc.get_task()

    scheduler.add_task(task)

    # return value
    run_state = task.get_run_state()
    ret_code = run_state.regs[REG_D0]
    log_proc.info("return from sub process: ret_code=%d", ret_code)

    # cleanup proc
    proc.free()

    return ret_code
Пример #9
0
    def __init__(
        self,
        ctx,
        bin_file,
        arg_str,
        input_fh=None,
        output_fh=None,
        stack_size=4096,
        shell=False,
        cwd=None,
        cwd_lock=None,
    ):
        """bin_file  Amiga path to binary for process
        arg_str   Shell-style parameter string with trailing newline
        """
        self.ctx = ctx
        if input_fh == None:
            input_fh = self.ctx.dos_lib.file_mgr.get_input()
        if output_fh == None:
            output_fh = self.ctx.dos_lib.file_mgr.get_output()
        self.init_cwd(cwd, cwd_lock)

        self.ok = self.load_binary(self.cwd_lock, bin_file, shell)
        if not self.ok:
            return
        # setup stack
        self.stack = Stack.alloc(self.ctx.alloc, stack_size)
        log_proc.info(self.stack)
        # thor: the boot shell creates its own CLI if it is not there.
        # but for now, supply it with the Vamos CLI and let it initialize
        # it through the private CliInit() call of the dos.library
        if not shell:
            self.shell = False
            self.init_args(arg_str, input_fh)
            self.init_cli_struct(input_fh, output_fh, self.bin_basename)
        else:
            self.arg = None
            self.arg_base = 0
            self.shell = True
            self.init_cli_struct(None, None, None)
        self.shell_message = None
        self.shell_packet = None
        self.shell_port = None
        self.init_task_struct(input_fh, output_fh)
        self.set_cwd()
        self._init_task()
Пример #10
0
def run_command(scheduler, process, start_pc, args_ptr, args_len, stack_size, reg_d1=0):
  ctx = process.ctx
  alloc = ctx.alloc
  new_stack = Stack.alloc(alloc, stack_size)
  # save old stack
  oldstack_upper = process.this_task.access.r_s("pr_Task.tc_SPLower")
  oldstack_lower = process.this_task.access.r_s("pr_Task.tc_SPUpper")
  # activate new stack
  process.this_task.access.w_s("pr_Task.tc_SPLower", new_stack.get_upper())
  process.this_task.access.w_s("pr_Task.tc_SPUpper", new_stack.get_lower())
  # NOTE: the Manx fexec and BPCL mess is not (yet) setup here.

  # setup sub task
  sp = new_stack.get_initial_sp()

  # new proc registers: d0=arg_len a0=arg_cptr
  # d2=stack_size.  this value is also in 4(sp) (see Process.init_stack), but
  # various C programs rely on it being present (1.3-3.1 at least have it).
  set_regs = {
      REG_D0: args_len,
      REG_D1: reg_d1,
      REG_A0: args_ptr,
      REG_D2: stack_size,
      REG_A2: ctx.odg_base,
      REG_A5: ctx.odg_base,
      REG_A6: ctx.odg_base
  }
  get_regs = [REG_D0]
  task = Task("RunCommand", start_pc, new_stack, set_regs, get_regs)

  # run sub task
  scheduler.run_sub_task(task)

  # return value
  run_state = task.get_run_state()
  ret_code = run_state.regs[REG_D0]
  log_proc.info("return from RunCommand: ret_code=%d", ret_code)

  # restore stack values
  process.this_task.access.w_s("pr_Task.tc_SPLower", oldstack_lower)
  process.this_task.access.w_s("pr_Task.tc_SPUpper", oldstack_upper)

  # result code
  return ret_code
Пример #11
0
 def init_cli_struct(self, input_fh, output_fh, name):
   self.cli = self.ctx.alloc.alloc_struct(self.bin_basename + "_CLI",CLIStruct)
   self.cli.access.w_s("cli_DefaultStack", self.stack.get_size() / 4) # in longs
   if input_fh != None:
     self.cli.access.w_s("cli_StandardInput", input_fh.b_addr << 2)
     self.cli.access.w_s("cli_CurrentInput", input_fh.b_addr << 2)
   if output_fh != None:
     self.cli.access.w_s("cli_StandardOutput", output_fh.b_addr << 2)
     self.cli.access.w_s("cli_CurrentOutput", output_fh.b_addr << 2)
   self.prompt  = self.ctx.alloc.alloc_memory("cli_Prompt",60)
   self.cmdname = self.ctx.alloc.alloc_memory("cli_CommandName",104)
   self.cmdfile = self.ctx.alloc.alloc_memory("cli_CommandFile",40)
   self.setname = self.ctx.alloc.alloc_memory("cli_SetName",80)
   self.cli.access.w_s("cli_Prompt",self.prompt.addr)
   self.cli.access.w_s("cli_CommandName",self.cmdname.addr)
   self.cli.access.w_s("cli_CommandFile",self.cmdfile.addr)
   self.cli.access.w_s("cli_SetName",self.setname.addr)
   if name != None:
     self.ctx.mem.w_bstr(self.cmdname.addr,name)
   log_proc.info(self.cli)
Пример #12
0
 def init_cli_struct(self, input_fh, output_fh, name):
   self.cli = self.ctx.alloc.alloc_struct(self.bin_basename + "_CLI",CLIStruct)
   self.cli.access.w_s("cli_DefaultStack", self.stack_size / 4) # in longs
   if input_fh != None:
     self.cli.access.w_s("cli_StandardInput", input_fh.b_addr)
     self.cli.access.w_s("cli_CurrentInput", input_fh.b_addr)
   if output_fh != None:
     self.cli.access.w_s("cli_StandardOutput", output_fh.b_addr)
     self.cli.access.w_s("cli_CurrentOutput", output_fh.b_addr)
   self.prompt  = self.ctx.alloc.alloc_memory("cli_Prompt",60)
   self.cmdname = self.ctx.alloc.alloc_memory("cli_CommandName",104)
   self.cmdfile = self.ctx.alloc.alloc_memory("cli_CommandFile",40)
   self.setname = self.ctx.alloc.alloc_memory("cli_SetName",80)
   self.cli.access.w_s("cli_Prompt",self.prompt.addr)
   self.cli.access.w_s("cli_CommandName",self.cmdname.addr)
   self.cli.access.w_s("cli_CommandFile",self.cmdfile.addr)
   self.cli.access.w_s("cli_SetName",self.setname.addr)
   if name != None:
     self.ctx.mem.w_bstr(self.cmdname.addr,name)
   log_proc.info(self.cli)
Пример #13
0
 def load_binary(self, lock, ami_bin_file, shell=False):
   self.bin_basename = self.ctx.path_mgr.ami_name_of_path(lock,ami_bin_file)
   self.bin_file     = ami_bin_file
   sys_path = self.ctx.path_mgr.ami_command_to_sys_path(lock, ami_bin_file)
   if not sys_path or not os.path.exists(sys_path):
     log_proc.error("failed loading binary: %s -> %s", ami_bin_file, sys_path)
     return False
   self.bin_seg_list = self.ctx.seg_loader.load_sys_seglist(sys_path)
   info = self.ctx.seg_loader.get_info(self.bin_seg_list)
   self.prog_start = info.seglist.get_segment().get_addr()
   # THOR: If this is a shell, then the seglist requires BCPL linkage and
   # initialization of the GlobVec. Fortunately, for the 3.9 shell all this
   # magic is not really required, and the BCPL call-in (we use) is at
   # offset +8
   if shell:
     self.prog_start += 8
     self.shell_start = self.prog_start
   log_proc.info("loaded binary: %s", info)
   for seg in info.seglist:
     log_proc.info(seg)
   return True
Пример #14
0
 def load_binary(self, lock, ami_bin_file, shell=False):
   self.bin_basename = self.ctx.path_mgr.ami_name_of_path(lock,ami_bin_file)
   self.bin_file     = ami_bin_file
   sys_path, ami_path = self.ctx.path_mgr.ami_command_to_sys_path(lock, ami_bin_file)
   if not sys_path:
     log_proc.error("failed loading binary: %s -> %s", ami_bin_file, sys_path)
     return False
   self.bin_seg_list = self.ctx.seg_loader.load_sys_seglist(sys_path)
   info = self.ctx.seg_loader.get_info(self.bin_seg_list)
   self.prog_start = info.seglist.get_segment().get_addr()
   # set home dir and get lock
   self.home_dir = self.ctx.path_mgr.ami_dir_of_path(lock, ami_path)
   lock_mgr = self.ctx.dos_lib.lock_mgr
   self.home_lock = lock_mgr.create_lock(lock, self.home_dir, False)
   log_proc.info("home dir: %s", self.home_lock)
   # THOR: If this is a shell, then the seglist requires BCPL linkage and
   # initialization of the GlobVec. Fortunately, for the 3.9 shell all this
   # magic is not really required, and the BCPL call-in (we use) is at
   # offset +8
   if shell:
     self.prog_start += 8
     self.shell_start = self.prog_start
   log_proc.info("loaded binary: %s", info)
   for seg in info.seglist:
     log_proc.info(seg)
   return True
Пример #15
0
    def create_main_proc(cls, proc_cfg, path_mgr, dos_ctx):
        # a single Amiga-like raw arg was passed
        cmd_cfg = proc_cfg.command
        if cmd_cfg.raw_arg:
            # check args
            if len(cmd_cfg.args) > 0:
                log_proc.error("raw arg only allows a single argument!")
                return None
            # parse raw arg
            cl = CommandLine()
            res = cl.parse_line(cmd_cfg.binary)
            if res != cl.LINE_OK:
                log_proc.error("raw arg is invalid! (error %d)", res)
                return None
            binary = cl.get_cmd()
            arg_str = cl.get_arg_str()
        else:
            # setup binary
            binary = cmd_cfg.binary
            if not cmd_cfg.pure_ami_path:
                # if path exists on host system then make an ami path
                if os.path.exists(binary):
                    sys_binary = binary
                    binary = path_mgr.from_sys_path(binary)
                    if not binary:
                        log_proc.error("can't map binary: %s", sys_binary)
                        return None
            # combine remaining args to arg_str
            arg_str = sys_args_to_ami_arg_str(cmd_cfg.args)

        # summary
        stack_size = proc_cfg.stack * 1024
        shell = proc_cfg.command.shell
        log_proc.info("binary: '%s'", binary)
        log_proc.info("args:   '%s'", arg_str[:-1])
        log_proc.info("stack:  %d", stack_size)

        cwd = str(path_mgr.get_cwd())
        proc = cls(dos_ctx,
                   binary,
                   arg_str,
                   stack_size=stack_size,
                   shell=shell,
                   cwd=cwd)
        if not proc.ok:
            return None
        log_proc.info("set main process: %s", proc)
        return proc
Пример #16
0
 def __init__(self, ctx, bin_file, arg_str,
              input_fh=None, output_fh=None, stack_size=4096,
              shell=False, cwd=None, cwd_lock=None):
   """bin_file  Amiga path to binary for process
      arg_str   Shell-style parameter string with trailing newline
   """
   self.ctx = ctx
   if input_fh == None:
     input_fh = self.ctx.dos_lib.file_mgr.get_input()
   if output_fh == None:
     output_fh = self.ctx.dos_lib.file_mgr.get_output()
   self.init_cwd(cwd, cwd_lock)
   self.ok = self.load_binary(self.cwd_lock,bin_file,shell)
   if not self.ok:
     return
   # setup stack
   self.stack = Stack.alloc(self.ctx.alloc, stack_size)
   log_proc.info(self.stack)
   # thor: the boot shell creates its own CLI if it is not there.
   # but for now, supply it with the Vamos CLI and let it initialize
   # it through the private CliInit() call of the dos.library
   if not shell:
     self.shell = False
     self.init_args(arg_str, input_fh)
     self.init_cli_struct(input_fh, output_fh,self.bin_basename)
   else:
     self.arg = None
     self.arg_base = 0
     self.shell = True
     self.init_cli_struct(None,None,None)
   self.shell_message = None
   self.shell_packet  = None
   self.shell_port    = None
   self.init_task_struct(input_fh, output_fh)
   self.set_cwd()
   self._init_task()
Пример #17
0
 def init_cli_struct(self, input_fh, output_fh, name):
     self.cli = self.ctx.alloc.alloc_struct(CLIStruct,
                                            label=self.bin_basename +
                                            "_CLI")
     self.cli.access.w_s("cli_DefaultStack",
                         self.stack.get_size() // 4)  # in longs
     if input_fh != None:
         self.cli.access.w_s("cli_StandardInput", input_fh.b_addr << 2)
         self.cli.access.w_s("cli_CurrentInput", input_fh.b_addr << 2)
     if output_fh != None:
         self.cli.access.w_s("cli_StandardOutput", output_fh.b_addr << 2)
         self.cli.access.w_s("cli_CurrentOutput", output_fh.b_addr << 2)
     self.prompt = self.ctx.alloc.alloc_memory(60, label="cli_Prompt")
     self.cmdname = self.ctx.alloc.alloc_memory(104,
                                                label="cli_CommandName")
     self.cmdfile = self.ctx.alloc.alloc_memory(40, label="cli_CommandFile")
     self.setname = self.ctx.alloc.alloc_memory(80, label="cli_SetName")
     self.cli.access.w_s("cli_Prompt", self.prompt.addr)
     self.cli.access.w_s("cli_CommandName", self.cmdname.addr)
     self.cli.access.w_s("cli_CommandFile", self.cmdfile.addr)
     self.cli.access.w_s("cli_SetName", self.setname.addr)
     if name != None:
         self.ctx.mem.w_bstr(self.cmdname.addr, name)
     log_proc.info(self.cli)
Пример #18
0
  def create_main_proc(cls, proc_cfg, path_mgr, dos_ctx):
    # a single Amiga-like raw arg was passed
    cmd_cfg = proc_cfg.command
    if cmd_cfg.raw_arg:
      # check args
      if len(cmd_cfg.args) > 0:
        log_proc.error("raw arg only allows a single argument!")
        return None
      # parse raw arg
      cl = CommandLine()
      res = cl.parse_line(cmd_cfg.binary)
      if res != cl.LINE_OK:
        log_proc.error("raw arg is invalid! (error %d)", res)
        return None
      binary = cl.get_cmd()
      arg_str = cl.get_arg_str()
    else:
      # setup binary
      binary = cmd_cfg.binary
      if not cmd_cfg.pure_ami_path:
        # if path exists on host system then make an ami path
        if os.path.exists(binary):
          sys_binary = binary
          binary = path_mgr.from_sys_path(binary)
          if not binary:
            log_proc.error("can't map binary: %s", sys_binary)
            return None
      # combine remaining args to arg_str
      arg_str = sys_args_to_ami_arg_str(cmd_cfg.args)

    # summary
    stack_size = proc_cfg.stack * 1024
    shell = proc_cfg.command.shell
    log_proc.info("binary: '%s'", binary)
    log_proc.info("args:   '%s'", arg_str[:-1])
    log_proc.info("stack:  %d", stack_size)

    cwd = str(path_mgr.get_cwd())
    proc = cls(dos_ctx, binary, arg_str, stack_size=stack_size,
               shell=shell, cwd=cwd)
    if not proc.ok:
      return None
    log_proc.info("set main process: %s", proc)
    return proc
Пример #19
0
 def free_cwd(self):
     if self.cwd_lock is not None and not self.cwd_shared:
         log_proc.info("current_dir: free lock=%s", self.cwd_lock)
         lock_mgr = self.ctx.dos_lib.lock_mgr
         lock_mgr.release_lock(self.cwd_lock)
Пример #20
0
 def free_cwd(self):
   if self.cwd_lock is not None and not self.cwd_shared:
     log_proc.info("current_dir: free lock=%s", self.cwd_lock)
     lock_mgr = self.ctx.dos_lib.lock_mgr
     lock_mgr.release_lock(self.cwd_lock)