Beispiel #1
0
  def Run(self, cmd_val):
    # type: (cmd_value__Argv) -> int

    arg_r = args.Reader(cmd_val.argv, spids=cmd_val.arg_spids)
    arg_r.Next()  # skip 'exec'
    _ = EXEC_SPEC.Parse(arg_r)  # no flags now, but accepts --

    # Apply redirects in this shell.  # NOTE: Redirects were processed earlier.
    if arg_r.AtEnd():
      self.fd_state.MakePermanent()
      return 0

    environ = self.mem.GetExported()
    i = arg_r.i
    cmd = cmd_val.argv[i]
    argv0_path = self.search_path.CachedLookup(cmd)
    if argv0_path is None:
      self.errfmt.Print('exec: %r not found', cmd,
                        span_id=cmd_val.arg_spids[1])
      raise SystemExit(127)  # exec builtin never returns

    # shift off 'exec'
    c2 = cmd_value.Argv(cmd_val.argv[i:], cmd_val.arg_spids[i:], cmd_val.block)
    self.ext_prog.Exec(argv0_path, c2, environ)  # NEVER RETURNS
    assert False, "This line should never be reached" # makes mypy happy
  def Run(self, cmd_val):
    # type: (cmd_value__Argv) -> int

    if len(cmd_val.argv) == 1:
      return 0  # this could be an error in strict mode?

    name = cmd_val.argv[1]

    # Run regular builtin or special builtin
    to_run = consts.LookupNormalBuiltin(name)
    if to_run == consts.NO_INDEX:
      to_run = consts.LookupSpecialBuiltin(name)
    if to_run == consts.NO_INDEX:
      span_id = cmd_val.arg_spids[1]
      if consts.LookupAssignBuiltin(name) != consts.NO_INDEX:
        # NOTE: There's a similar restriction for 'command'
        self.errfmt.Print("Can't run assignment builtin recursively",
                          span_id=span_id)
      else:
        self.errfmt.Print("%r isn't a shell builtin", name, span_id=span_id)
      return 1

    cmd_val2 = cmd_value.Argv(cmd_val.argv[1:], cmd_val.arg_spids[1:],
                              cmd_val.block)
    return self.shell_ex.RunBuiltin(to_run, cmd_val2)
Beispiel #3
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int
        attrs, arg_r = flag_spec.ParseCmdVal('command', cmd_val)
        arg = arg_types.command(attrs.attrs)
        if arg.v:
            status = 0
            names = arg_r.Rest()
            for kind, argument in _ResolveNames(names, self.funcs,
                                                self.aliases,
                                                self.search_path):
                if kind is None:
                    status = 1  # nothing printed, but we fail
                else:
                    # This is for -v, -V is more detailed.
                    print(argument)
            return status

        # shift by one
        cmd_val = cmd_value.Argv(cmd_val.argv[1:], cmd_val.arg_spids[1:], None)

        # If we respected do_fork here instead of passing True, the case
        # 'command date | wc -l' would take 2 processes instead of 3.  But no other
        # shell does that, and this rare case isn't worth the bookkeeping.
        # See test/syscall
        return self.shell_ex.RunSimpleCommand(cmd_val, True, call_procs=False)
Beispiel #4
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int

        # TODO: Also hard usage error here too?
        attrs, arg_r = flag_spec.ParseOilCmdVal('run', cmd_val)
        arg = arg_types.run(attrs.attrs)

        if arg_r.Peek() is None:
            # HARD ERROR, not e_usage(), because errexit is often disabled!
            e_die("'run' expected a command to run", status=2)

        argv, spids = arg_r.Rest2()
        cmd_val2 = cmd_value.Argv(argv, spids, cmd_val.block)

        # Set in the 'except' block, e.g. if 'myfunc' failed
        failure_spid = runtime.NO_SPID
        try:
            # Temporarily turn ON errexit, and blame the 'run' spid.  Note that
            # 'if run myproc' disables it and then enables it!
            with state.ctx_ErrExit(self.mutable_opts, True,
                                   cmd_val.arg_spids[0]):
                # Pass do_fork=True.  Slight annoyance: the real value is a field of
                # command.Simple().  See _NoForkLast() in CommandEvaluator We have an
                # extra fork (miss out on an optimization) of code like ( status ls )
                # or forkwait { status ls }, but that is NOT idiomatic code.  status is
                # for functions.
                status = self.shell_ex.RunSimpleCommand(cmd_val2, True)
                #log('st %d', status)
        except error.ErrExit as e:  # from functino call
            #log('e %d', e.exit_status)
            status = e.exit_status
            failure_spid = e.span_id

        # Do this before -allow-status-01
        if arg.status_ok is not None:
            status = _AdjustStatus(arg.status_ok, status)

        if arg.allow_status_01 and status not in (0, 1):
            if failure_spid != runtime.NO_SPID:
                self.errfmt.Print_('(original failure)', span_id=failure_spid)
                self.errfmt.StderrLine('')

            raise error.ErrExit('fatal: status %d when --allow-status-01' %
                                status,
                                span_id=spids[0],
                                status=status)

        if arg.assign_status is not None:
            var_name = arg.assign_status
            if var_name.startswith(':'):
                var_name = var_name[1:]

            state.SetRefString(self.mem, var_name, str(status))
            return 0  # don't fail

        return status
Beispiel #5
0
def _ExtProc(argv):
  arg_vec = cmd_value.Argv(argv, [0] * len(argv))
  argv0_path = None
  for path_entry in ['/bin', '/usr/bin']:
    full_path = os.path.join(path_entry, argv[0])
    if os.path.exists(full_path):
      argv0_path = full_path
      break
  if not argv0_path:
    argv0_path = argv[0]  # fallback that tests failure case
  return Process(ExternalThunk(_EXT_PROG, argv0_path, arg_vec, {}), _JOB_STATE)
Beispiel #6
0
 def _ExtProc(self, argv):
     arg_vec = cmd_value.Argv(argv, [0] * len(argv))
     argv0_path = None
     for path_entry in ['/bin', '/usr/bin']:
         full_path = os.path.join(path_entry, argv[0])
         if os.path.exists(full_path):
             argv0_path = full_path
             break
     if not argv0_path:
         argv0_path = argv[0]  # fallback that tests failure case
     return Process(ExternalThunk(self.ext_prog, argv0_path, arg_vec, {}),
                    self.job_state, self.tracer)
Beispiel #7
0
  def __call__(self, cmd_val, fork_external):
    arg, arg_index = COMMAND_SPEC.ParseVec(cmd_val)
    if arg.v:
      status = 0
      names = cmd_val.argv[arg_index:]
      for kind, arg in _ResolveNames(names, self.funcs, self.aliases,
                                     self.search_path):
        if kind is None:
          status = 1  # nothing printed, but we fail
        else:
          # This is for -v, -V is more detailed.
          print(arg)
      return status

    # shift by one
    cmd_val = cmd_value.Argv(cmd_val.argv[1:], cmd_val.arg_spids[1:])
    # 'command ls' suppresses function lookup.
    return self.ex.RunSimpleCommand(cmd_val, fork_external, funcs=False)
Beispiel #8
0
def MakeBuiltinArgv(argv):
  return cmd_value.Argv(argv, [0] * len(argv))
def _MakeBuiltinArgv(argv):
    argv = [''] + argv  # add dummy since arg_vec includes argv[0]
    # no location info
    return cmd_value.Argv(argv, [runtime.NO_SPID] * len(argv))
Beispiel #10
0
def MakeBuiltinArgv(argv1):
    # type: (List[str]) -> cmd_value__Argv
    argv = ['']  # dummy for argv[0]
    argv.extend(argv1)
    # no location info
    return cmd_value.Argv(argv, [runtime.NO_SPID] * len(argv), None)
Beispiel #11
0
def MakeBuiltinArgv(argv):
  # type: (List[str]) -> cmd_value__Argv
  argv = [''] + argv  # add dummy for argv[0]
  # no location info
  return cmd_value.Argv(argv, [runtime.NO_SPID] * len(argv))