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
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
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
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)
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
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
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
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
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