Beispiel #1
0
  def _InitDefaults(self):
    # For some reason this is one of few variables EXPORTED.  bash and dash
    # both do it.  (e.g. env -i -- dash -c env)
    ExportGlobalString(self, 'PWD', posix.getcwd())

    # Default value; user may unset it.
    # $ echo -n "$IFS" | python -c 'import sys;print repr(sys.stdin.read())'
    # ' \t\n'
    SetGlobalString(self, 'IFS', split.DEFAULT_IFS)

    # NOTE: Should we put these in a namespace for Oil?
    SetGlobalString(self, 'UID', str(posix.getuid()))
    SetGlobalString(self, 'EUID', str(posix.geteuid()))

    SetGlobalString(self, 'HOSTNAME', str(libc.gethostname()))

    # In bash, this looks like 'linux-gnu', 'linux-musl', etc.  Scripts test
    # for 'darwin' and 'freebsd' too.  They generally don't like at 'gnu' or
    # 'musl'.  We don't have that info, so just make it 'linux'.
    SetGlobalString(self, 'OSTYPE', str(posix.uname()[0].lower()))

    # For getopts builtin
    SetGlobalString(self, 'OPTIND', '1')

    # For xtrace
    SetGlobalString(self, 'PS4', '+ ')

    # bash-completion uses this.  Value copied from bash.  It doesn't integrate
    # with 'readline' yet.
    SetGlobalString(self, 'COMP_WORDBREAKS', _READLINE_DELIMS)
Beispiel #2
0
def abspath(path):
    # type: (str) -> str
    """Return an absolute path."""
    if not isabs(path):
        cwd = posix.getcwd()
        path = join(cwd, path)
    return normpath(path)
Beispiel #3
0
def main(argv):
    # type: (List[str]) -> int
    loader = pyutil.GetResourceLoader()
    login_shell = False

    environ = {}  # type: Dict[str, str]
    environ['PWD'] = posix.getcwd()

    arg_r = args.Reader(argv, spids=[runtime.NO_SPID] * len(argv))

    try:
        status = pure.Main('osh', arg_r, environ, login_shell, loader, None)
        return status
    except error.Usage as e:
        #builtin.Help(['oil-usage'], util.GetResourceLoader())
        log('oil: %s', e.msg)
        return 2
    except RuntimeError as e:
        if 0:
            import traceback
            traceback.print_exc()
        # NOTE: The Python interpreter can cause this, e.g. on stack overflow.
        # f() { f; }; f will cause this
        msg = e.message  # type: str
        stderr_line('osh fatal error: %s', msg)
        return 1

    # Note: This doesn't happen in C++.
    except KeyboardInterrupt:
        print('')
        return 130  # 128 + 2

    except OSError as e:
        if 0:
            import traceback
            traceback.print_exc()

        # test this with prlimit --nproc=1 --pid=$$
        stderr_line('osh I/O error: %s', pyutil.strerror_OS(e))
        return 2  # dash gives status 2

    except IOError as e:  # duplicate of above because CPython is inconsistent
        stderr_line('osh I/O error: %s', pyutil.strerror_IO(e))
        return 2
Beispiel #4
0
  def __call__(self, arg_vec):
    arg, _ = PWD_SPEC.ParseVec(arg_vec)

    try:
      # This comes FIRST, even if you change $PWD.
      pwd = posix.getcwd()
    except OSError as e:
      # Happens when the directory is unlinked.
      self.errfmt.Print("Can't determine working directory: %s",
                        posix.strerror(e.errno))
      return 1

    # '-L' is the default behavior; no need to check it
    # TODO: ensure that if multiple flags are provided, the *last* one overrides
    # the others
    if arg.P:
      pwd = libc.realpath(pwd)
    print(pwd)
    return 0
Beispiel #5
0
 def Reset(self):
   del self.stack[:] 
   self.stack.append(posix.getcwd())
Beispiel #6
0
def _GetWorkingDir():
    """Fallback for pwd and $PWD when there's no 'cd' and no inherited $PWD."""
    try:
        return posix.getcwd()
    except OSError as e:
        e_die("Can't determine working directory: %s", posix.strerror(e.errno))
Beispiel #7
0
 def testFoo(self):
     print(posix_.getcwd())
     # Testing this because I removed a lot of #ifdef
     entries = posix_.listdir('.')
     self.assert_('doc' in entries)
Beispiel #8
0
def main(argv):
  # type: (List[str]) -> int
  arena = alloc.Arena()

  dollar0 = argv[0]
  debug_stack = []  # type: List[state.DebugFrame]

  argv = argv[1:]  # remove binary name
  i, flag_a, flag_c, flag_n = Parse(argv)
  argv = argv[i:]  # truncate

  mem = state.Mem(dollar0, argv, arena, debug_stack)

  # TODO: look at extern char** environ;

  environ = {}  # type: Dict[str, str]
  environ['PWD'] = posix.getcwd()
  state.InitMem(mem, environ, 'VERSION')

  opt_hook = state.OptHook()
  parse_opts, exec_opts, mutable_opts = state.MakeOpts(mem, opt_hook)
  # Dummy value; not respecting aliases!
  aliases = {}  # type: Dict[str, str]
  # parse `` and a[x+1]=bar differently

  oil_grammar = None  # type: Grammar
  if mylib.PYTHON:
    loader = pyutil.GetResourceLoader()
    oil_grammar = meta.LoadOilGrammar(loader)

  parse_ctx = parse_lib.ParseContext(arena, parse_opts, aliases, oil_grammar)

  if flag_c:
    # This path is easier to run through GDB
    line_reader = reader.StringLineReader(flag_c, arena)
    src = source.CFlag()  # type: source_t

  elif len(argv) == 0:
    line_reader = reader.FileLineReader(mylib.Stdin(), arena)
    src = source.Stdin('')

  elif len(argv) == 1:
    path = argv[0]
    f = mylib.open(path)
    line_reader = reader.FileLineReader(f, arena)
    src = source.MainFile(path)

  else:
    raise AssertionError(argv)

  arena.PushSource(src)
  c_parser = parse_ctx.MakeOshParser(line_reader)

  # C++ doesn't have the abbreviations yet (though there are some differences
  # like omitting spids)
  #tree = node.AbbreviatedTree()
  if flag_n:
    try:
      node = main_loop.ParseWholeFile(c_parser)
    except error.Parse as e:
      ui.PrettyPrintError(e, arena)
      return 2
    assert node is not None

    if flag_a:
      tree = node.PrettyTree()

      ast_f = fmt.DetectConsoleOutput(mylib.Stdout())
      fmt.PrintTree(tree, ast_f)
      ast_f.write('\n')
    return 0

  # New osh_eval.py instantiations

  errfmt = ui.ErrorFormatter(arena)

  splitter = split.SplitContext(mem)
  arith_ev = sh_expr_eval.ArithEvaluator(mem, exec_opts, parse_ctx, errfmt)
  bool_ev = sh_expr_eval.BoolEvaluator(mem, exec_opts, parse_ctx, errfmt)
  word_ev = word_eval.NormalWordEvaluator(mem, exec_opts, splitter, errfmt)
  prompt_ev = prompt.Evaluator('osh', parse_ctx, mem)

  arith_ev.word_ev = word_ev
  word_ev.arith_ev = arith_ev
  word_ev.prompt_ev = prompt_ev

  prompt_ev.word_ev = word_ev

  procs = {}  # type: Dict[str, command__ShFunction]

  assign_builtins = {}  # type: Dict[int, _AssignBuiltin]

  new_var = builtin_assign.NewVar(mem, procs, errfmt)
  assign_builtins[builtin_i.declare] = new_var
  assign_builtins[builtin_i.typeset] = new_var
  assign_builtins[builtin_i.local] = new_var
  assign_builtins[builtin_i.export_] = builtin_assign.Export(mem, errfmt)
  assign_builtins[builtin_i.readonly] = builtin_assign.Readonly(mem, errfmt)

  #assign_builtins = {
  #    # ShAssignment (which are pure)
  #    builtin_i.declare: new_var,
  #    builtin_i.typeset: new_var,
  #    builtin_i.local: new_var,

  #    builtin_i.export_: builtin_assign.Export(mem, errfmt),
  #    builtin_i.readonly: builtin_assign.Readonly(mem, errfmt),
  #}

  cmd_deps = cmd_eval.Deps()
  cmd_deps.mutable_opts = mutable_opts
  cmd_deps.traps = {}
  cmd_deps.trap_nodes = []  # TODO: Clear on fork() to avoid duplicates

  cmd_deps.dumper = dev.CrashDumper('')

  search_path = state.SearchPath(mem)

  builtins = {}  # type: Dict[int, vm._Builtin]
  builtins[builtin_i.echo] = builtin_pure.Echo(exec_opts)

  builtins[builtin_i.set] = Set(mutable_opts)  # DUMMY until ParseMore()
  if mylib.PYTHON:
    # Use the real one
    builtins[builtin_i.set] = builtin_pure.Set(mutable_opts, mem)

  builtins[builtin_i.shopt] = builtin_pure.Shopt(mutable_opts)
  builtins[builtin_i.alias] = builtin_pure.Alias(aliases, errfmt)
  builtins[builtin_i.unalias] = builtin_pure.UnAlias(aliases, errfmt)

  builtins[builtin_i.hash] = builtin_pure.Hash(search_path)
  builtins[builtin_i.getopts] = builtin_pure.GetOpts(mem, errfmt)

  builtins[builtin_i.shift] = builtin_assign.Shift(mem)
  builtins[builtin_i.unset] = builtin_assign.Unset(
      mem, exec_opts, procs, parse_ctx, arith_ev, errfmt)

  true_ = builtin_pure.Boolean(0)
  builtins[builtin_i.colon] = true_  # a "special" builtin 
  builtins[builtin_i.true_] = true_
  builtins[builtin_i.false_] = builtin_pure.Boolean(1)

  # builtin_meta
  builtins[builtin_i.type] = builtin_meta.Type(procs, aliases, search_path, errfmt)

  shell_ex = NullExecutor(exec_opts, mutable_opts, procs, builtins)

  trace_f = util.DebugFile(mylib.Stderr())
  tracer = dev.Tracer(parse_ctx, exec_opts, mutable_opts, mem, word_ev, trace_f)

  cmd_ev = cmd_eval.CommandEvaluator(mem, exec_opts, errfmt, procs,
                                     assign_builtins, arena, cmd_deps)

  # TODO: can't instantiate this yet
  #fd_state = None

  # needs cmd_ev
  builtins[builtin_i.eval] = builtin_meta.Eval(parse_ctx, exec_opts, cmd_ev)
  #source_builtin = builtin_meta.Source(
  #    parse_ctx, search_path, cmd_ev, fd_state, errfmt)
  #builtins[builtin_i.source] = source_builtin
  #builtins[builtin_i.dot] = source_builtin

  builtins[builtin_i.builtin] = builtin_meta.Builtin(shell_ex, errfmt)
  builtins[builtin_i.command] = builtin_meta.Command(shell_ex, procs, aliases,
                                                     search_path)

  builtins[builtin_i.printf] = builtin_printf.Printf(mem, parse_ctx, errfmt)

  builtins[builtin_i.test] = builtin_bracket.Test(False, exec_opts, mem, errfmt)
  builtins[builtin_i.bracket] = builtin_bracket.Test(True, exec_opts, mem, errfmt)

  dir_stack = state.DirStack()
  builtins[builtin_i.pushd] = builtin_misc.Pushd(mem, dir_stack, errfmt)
  builtins[builtin_i.popd] = builtin_misc.Popd(mem, dir_stack, errfmt)
  builtins[builtin_i.dirs] = builtin_misc.Dirs(mem, dir_stack, errfmt)
  builtins[builtin_i.pwd] = builtin_misc.Pwd(mem, errfmt)

  builtins[builtin_i.times] = builtin_misc.Times()
  builtins[builtin_i.read] = builtin_misc.Read(splitter, mem)

  builtins[builtin_i.cat] = builtin_misc.Cat()  # for $(<file)
  builtins[builtin_i.cd] = builtin_misc.Cd(mem, dir_stack, cmd_ev, errfmt)

  # vm.InitCircularDeps
  cmd_ev.arith_ev = arith_ev
  cmd_ev.bool_ev = bool_ev
  cmd_ev.word_ev = word_ev
  cmd_ev.tracer = tracer
  cmd_ev.shell_ex = shell_ex

  shell_ex.cmd_ev = cmd_ev

  bool_ev.word_ev = word_ev

  try:
    status = main_loop.Batch(cmd_ev, c_parser, arena,
                             cmd_flags=cmd_eval.IsMainProgram)
  except util.UserExit as e:
    # TODO: fix this
    #status = e.status
    status = 1
  return status