コード例 #1
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int
        num_args = len(cmd_val.argv) - 1
        if num_args == 0:
            # TODO: It's suppose to try another dir before doing this?
            self.errfmt.Print('pushd: no other directory')
            return 1
        elif num_args > 1:
            raise args.UsageError('got too many arguments')

        # TODO: 'cd' uses normpath?  Is that inconsistent?
        dest_dir = os_path.abspath(cmd_val.argv[1])
        try:
            posix.chdir(dest_dir)
        except OSError as e:
            self.errfmt.Print("pushd: %r: %s",
                              dest_dir,
                              posix.strerror(e.errno),
                              span_id=cmd_val.arg_spids[1])
            return 1

        self.dir_stack.Push(dest_dir)
        _PrintDirStack(self.dir_stack, SINGLE_LINE, self.mem.GetVar('HOME'))
        state.ExportGlobalString(self.mem, 'PWD', dest_dir)
        self.mem.SetPwd(dest_dir)
        return 0
コード例 #2
0
  def __call__(self, arg_vec):
    arg, i = CD_SPEC.ParseVec(arg_vec)
    # TODO: error checking, etc.
    # TODO: ensure that if multiple flags are provided, the *last* one overrides
    # the others.

    try:
      dest_dir = arg_vec.strs[i]
    except IndexError:
      val = self.mem.GetVar('HOME')
      if val.tag == value_e.Undef:
        self.errfmt.Print("$HOME isn't defined")
        return 1
      elif val.tag == value_e.Str:
        dest_dir = val.s
      elif val.tag == value_e.StrArray:
        # User would have to unset $HOME to get rid of exported flag
        self.errfmt.Print("$HOME shouldn't be an array")
        return 1

    if dest_dir == '-':
      old = self.mem.GetVar('OLDPWD', scope_e.GlobalOnly)
      if old.tag == value_e.Undef:
        self.errfmt.Print('OLDPWD not set')
        return 1
      elif old.tag == value_e.Str:
        dest_dir = old.s
        print(dest_dir)  # Shells print the directory
      elif old.tag == value_e.StrArray:
        # TODO: Prevent the user from setting OLDPWD to array (or maybe they
        # can't even set it at all.)
        raise AssertionError('Invalid OLDPWD')

    pwd = self.mem.GetVar('PWD')
    assert pwd.tag == value_e.Str, pwd  # TODO: Need a general scheme to avoid

    # Calculate new directory, chdir() to it, then set PWD to it.  NOTE: We can't
    # call posix.getcwd() because it can raise OSError if the directory was
    # removed (ENOENT.)
    abspath = os_path.join(pwd.s, dest_dir)  # make it absolute, for cd ..
    if arg.P:
      # -P means resolve symbolic links, then process '..'
      real_dest_dir = libc.realpath(abspath)
    else:
      # -L means process '..' first.  This just does string manipulation.  (But
      # realpath afterward isn't correct?)
      real_dest_dir = os_path.normpath(abspath)

    try:
      posix.chdir(real_dest_dir)
    except OSError as e:
      self.errfmt.Print("cd %r: %s", real_dest_dir, posix.strerror(e.errno),
                        span_id=arg_vec.spids[i])
      return 1

    state.ExportGlobalString(self.mem, 'OLDPWD', pwd.s)
    state.ExportGlobalString(self.mem, 'PWD', real_dest_dir)
    self.dir_stack.Reset()  # for pushd/popd/dirs
    return 0
コード例 #3
0
def Chdir(dest_dir):
    # type: (str) -> int
    """Returns 0 for success and nonzero errno for error."""
    try:
        posix.chdir(dest_dir)
    except OSError as e:
        return e.errno
    return 0
コード例 #4
0
ファイル: builtin.py プロジェクト: waldyrious/oil
def _PopDirStack(mem, dir_stack, errfmt):
    """Helper for popd and cd { ... }."""
    dest_dir = dir_stack.Pop()
    if dest_dir is None:
        errfmt.Print('popd: directory stack is empty')
        return 1

    try:
        posix.chdir(dest_dir)
    except OSError as e:
        # Happens if a directory is deleted in pushing and popping
        errfmt.Print("popd: %r: %s", dest_dir, posix.strerror(e.errno))
        return 1

    state.SetGlobalString(mem, 'PWD', dest_dir)
    mem.SetPwd(dest_dir)
コード例 #5
0
  def __call__(self, arg_vec):
    dest_dir = self.dir_stack.Pop()
    if dest_dir is None:
      self.errfmt.Print('popd: directory stack is empty')
      return 1

    try:
      posix.chdir(dest_dir)
    except OSError as e:
      # Happens if a directory is deleted in pushing and popping
      self.errfmt.Print("popd: %r: %s", dest_dir, posix.strerror(e.errno))
      return 1

    _PrintDirStack(self.dir_stack, SINGLE_LINE, self.mem.GetVar('HOME'))
    state.SetGlobalString(self.mem, 'PWD', dest_dir)
    return 0
コード例 #6
0
def _PopDirStack(mem, dir_stack, errfmt):
    # type: (Mem, DirStack, ErrorFormatter) -> bool
    """Helper for popd and cd { ... }."""
    dest_dir = dir_stack.Pop()
    if dest_dir is None:
        errfmt.Print_('popd: directory stack is empty')
        return False

    try:
        posix.chdir(dest_dir)
    except OSError as e:
        # Happens if a directory is deleted in pushing and popping
        errfmt.Print_("popd: %r: %s" % (dest_dir, pyutil.strerror_OS(e)))
        return False

    state.SetGlobalString(mem, 'PWD', dest_dir)
    mem.SetPwd(dest_dir)
    return True
コード例 #7
0
  def __call__(self, arg_vec):
    num_args = len(arg_vec.strs) - 1
    if num_args == 0:
      # TODO: It's suppose to try another dir before doing this?
      self.errfmt.Print('pushd: no other directory')
      return 1
    elif num_args > 1:
      raise args.UsageError('got too many arguments')

    dest_dir = os_path.abspath(arg_vec.strs[1])
    try:
      posix.chdir(dest_dir)
    except OSError as e:
      self.errfmt.Print("pushd: %r: %s", dest_dir, posix.strerror(e.errno),
                        span_id=arg_vec.spids[1])
      return 1

    self.dir_stack.Push(dest_dir)
    _PrintDirStack(self.dir_stack, SINGLE_LINE, self.mem.GetVar('HOME'))
    state.SetGlobalString(self.mem, 'PWD', dest_dir)
    return 0
コード例 #8
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int
        arg, i = CD_SPEC.ParseCmdVal(cmd_val)
        try:
            dest_dir = cmd_val.argv[i]
        except IndexError:
            val = self.mem.GetVar('HOME')
            if val.tag == value_e.Undef:
                self.errfmt.Print("$HOME isn't defined")
                return 1
            elif val.tag == value_e.Str:
                dest_dir = val.s
            elif val.tag == value_e.MaybeStrArray:
                # User would have to unset $HOME to get rid of exported flag
                self.errfmt.Print("$HOME shouldn't be an array")
                return 1

        if dest_dir == '-':
            old = self.mem.GetVar('OLDPWD', scope_e.GlobalOnly)
            if old.tag == value_e.Undef:
                self.errfmt.Print('$OLDPWD not set')
                return 1
            elif old.tag == value_e.Str:
                dest_dir = old.s
                print(dest_dir)  # Shells print the directory
            elif old.tag == value_e.MaybeStrArray:
                # TODO: Prevent the user from setting OLDPWD to array (or maybe they
                # can't even set it at all.)
                raise AssertionError('Invalid $OLDPWD')

        pwd = self.mem.GetVar('PWD')
        assert pwd.tag == value_e.Str, pwd  # TODO: Need a general scheme to avoid

        # Calculate new directory, chdir() to it, then set PWD to it.  NOTE: We can't
        # call posix.getcwd() because it can raise OSError if the directory was
        # removed (ENOENT.)
        abspath = os_path.join(pwd.s, dest_dir)  # make it absolute, for cd ..
        if arg.P:
            # -P means resolve symbolic links, then process '..'
            real_dest_dir = libc.realpath(abspath)
        else:
            # -L means process '..' first.  This just does string manipulation.  (But
            # realpath afterward isn't correct?)
            real_dest_dir = os_path.normpath(abspath)

        try:
            posix.chdir(real_dest_dir)
        except OSError as e:
            self.errfmt.Print("cd %r: %s",
                              real_dest_dir,
                              posix.strerror(e.errno),
                              span_id=cmd_val.arg_spids[i])
            return 1

        state.ExportGlobalString(self.mem, 'PWD', real_dest_dir)

        # WEIRD: We need a copy that is NOT PWD, because the user could mutate PWD.
        # Other shells use global variables.
        self.mem.SetPwd(real_dest_dir)

        if cmd_val.block:
            self.dir_stack.Push(real_dest_dir)
            try:
                unused = self.ex.EvalBlock(cmd_val.block)
            finally:  # TODO: Change this to a context manager.
                # note: it might be more consistent to use an exception here.
                if not _PopDirStack(self.mem, self.dir_stack, self.errfmt):
                    return 1

        else:  # No block
            state.ExportGlobalString(self.mem, 'OLDPWD', pwd.s)
            self.dir_stack.Reset()  # for pushd/popd/dirs

        return 0
コード例 #9
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int
        attrs, arg_r = flag_spec.ParseCmdVal('cd', cmd_val)
        arg = arg_types.cd(attrs.attrs)

        dest_dir, arg_spid = arg_r.Peek2()
        if dest_dir is None:
            val = self.mem.GetVar('HOME')
            try:
                dest_dir = state.GetString(self.mem, 'HOME')
            except error.Runtime as e:
                self.errfmt.Print_(e.UserErrorString())
                return 1

        if dest_dir == '-':
            try:
                dest_dir = state.GetString(self.mem, 'OLDPWD')
                print(dest_dir)  # Shells print the directory
            except error.Runtime as e:
                self.errfmt.Print_(e.UserErrorString())
                return 1

        try:
            pwd = state.GetString(self.mem, 'PWD')
        except error.Runtime as e:
            self.errfmt.Print_(e.UserErrorString())
            return 1

        # Calculate new directory, chdir() to it, then set PWD to it.  NOTE: We can't
        # call posix.getcwd() because it can raise OSError if the directory was
        # removed (ENOENT.)
        abspath = os_path.join(pwd, dest_dir)  # make it absolute, for cd ..
        if arg.P:
            # -P means resolve symbolic links, then process '..'
            real_dest_dir = libc.realpath(abspath)
        else:
            # -L means process '..' first.  This just does string manipulation.  (But
            # realpath afterward isn't correct?)
            real_dest_dir = os_path.normpath(abspath)

        try:
            posix.chdir(real_dest_dir)
        except OSError as e:
            self.errfmt.Print_("cd %r: %s" %
                               (real_dest_dir, pyutil.strerror_OS(e)),
                               span_id=arg_spid)
            return 1

        state.ExportGlobalString(self.mem, 'PWD', real_dest_dir)

        # WEIRD: We need a copy that is NOT PWD, because the user could mutate PWD.
        # Other shells use global variables.
        self.mem.SetPwd(real_dest_dir)

        if cmd_val.block:
            self.dir_stack.Push(real_dest_dir)
            try:
                unused = self.cmd_ev.EvalBlock(cmd_val.block)
            finally:  # TODO: Change this to a context manager.
                # note: it might be more consistent to use an exception here.
                if not _PopDirStack(self.mem, self.dir_stack, self.errfmt):
                    return 1

        else:  # No block
            state.ExportGlobalString(self.mem, 'OLDPWD', pwd)
            self.dir_stack.Reset()  # for pushd/popd/dirs

        return 0