diff options
| author | Jari Aalto <jari.aalto@cante.net> | 2005-12-07 14:08:12 +0000 |
|---|---|---|
| committer | Jari Aalto <jari.aalto@cante.net> | 2009-09-12 16:46:57 +0000 |
| commit | 95732b497d12c98613bb3c5db16b61f377501a59 (patch) | |
| tree | 5e1cdf79eb0407e09dca4c0ec29e11442c7d1d15 /builtins/cd.def | |
| parent | eb87367179effbe5f430236db8259006d71438b7 (diff) | |
| download | android_external_bash-95732b497d12c98613bb3c5db16b61f377501a59.tar.gz android_external_bash-95732b497d12c98613bb3c5db16b61f377501a59.tar.bz2 android_external_bash-95732b497d12c98613bb3c5db16b61f377501a59.zip | |
Imported from ../bash-3.1.tar.gz.
Diffstat (limited to 'builtins/cd.def')
| -rw-r--r-- | builtins/cd.def | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/builtins/cd.def b/builtins/cd.def index 2be86d1..025e4f5 100644 --- a/builtins/cd.def +++ b/builtins/cd.def @@ -1,7 +1,7 @@ This file is cd.def, from which is created cd.c. It implements the builtins "cd" and "pwd" in Bash. -Copyright (C) 1987-2003 Free Software Foundation, Inc. +Copyright (C) 1987-2005 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -59,6 +59,7 @@ extern int array_needs_making; extern char *bash_getcwd_errstr; static int bindpwd __P((int)); +static void setpwd __P((char *)); static int change_to_directory __P((char *, int)); static char *cdspell __P((char *)); @@ -84,6 +85,23 @@ instead of following symbolic links; the -L option forces symbolic links to be followed. $END +/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */ +static void +setpwd (dirname) + char *dirname; +{ + int old_anm; + SHELL_VAR *tvar; + + old_anm = array_needs_making; + tvar = bind_variable ("PWD", dirname ? dirname : "", 0); + if (old_anm == 0 && array_needs_making && exported_p (tvar)) + { + update_export_env_inplace ("PWD=", 4, dirname ? dirname : ""); + array_needs_making = 0; + } +} + static int bindpwd (no_symlinks) int no_symlinks; @@ -100,19 +118,14 @@ bindpwd (no_symlinks) old_anm = array_needs_making; pwdvar = get_string_value ("PWD"); - tvar = bind_variable ("OLDPWD", pwdvar); + tvar = bind_variable ("OLDPWD", pwdvar, 0); if (old_anm == 0 && array_needs_making && exported_p (tvar)) { update_export_env_inplace ("OLDPWD=", 7, pwdvar); array_needs_making = 0; } - tvar = bind_variable ("PWD", dirname ? dirname : ""); - if (old_anm == 0 && array_needs_making && exported_p (tvar)) - { - update_export_env_inplace ("PWD=", 4, dirname ? dirname : ""); - array_needs_making = 0; - } + setpwd (dirname); if (dirname && dirname != the_current_working_directory) free (dirname); @@ -233,9 +246,13 @@ cd_builtin (list) printf ("%s\n", path); free (temp); +#if 0 /* Posix.2 says that after using CDPATH, the resultant value of $PWD will not contain `.' or `..'. */ return (bindpwd (posixly_correct || no_symlinks)); +#else + return (bindpwd (no_symlinks)); +#endif } else free (temp); @@ -298,7 +315,7 @@ cd_builtin (list) $BUILTIN pwd $FUNCTION pwd_builtin -$SHORT_DOC pwd [-PL] +$SHORT_DOC pwd [-LP] Print the current working directory. With the -P option, pwd prints the physical directory, without any symbolic links; the -L option makes pwd follow symbolic links. @@ -314,16 +331,17 @@ pwd_builtin (list) WORD_LIST *list; { char *directory; - int opt; + int opt, pflag; verbatim_pwd = no_symbolic_links; + pflag = 0; reset_internal_getopt (); while ((opt = internal_getopt (list, "LP")) != -1) { switch (opt) { case 'P': - verbatim_pwd = 1; + verbatim_pwd = pflag = 1; break; case 'L': verbatim_pwd = 0; @@ -342,7 +360,8 @@ pwd_builtin (list) /* Try again using getcwd() if canonicalization fails (for instance, if the file system has changed state underneath bash). */ - if (tcwd && directory == 0) + if ((tcwd && directory == 0) || + (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0)) directory = resetpwd ("pwd"); #undef tcwd @@ -350,12 +369,15 @@ pwd_builtin (list) if (directory) { printf ("%s\n", directory); + /* This is dumb but posix-mandated. */ + if (posixly_correct && pflag) + setpwd (directory); if (directory != the_current_working_directory) free (directory); fflush (stdout); if (ferror (stdout)) { - builtin_error (_("write error: %s"), strerror (errno)); + sh_wrerror (); clearerr (stdout); return (EXECUTION_FAILURE); } @@ -378,7 +400,7 @@ change_to_directory (newdir, nolinks) int nolinks; { char *t, *tdir; - int err, canon_failed, r; + int err, canon_failed, r, ndlen, dlen; tdir = (char *)NULL; @@ -396,6 +418,9 @@ change_to_directory (newdir, nolinks) tdir = nolinks ? sh_physpath (t, 0) : sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); + ndlen = strlen (newdir); + dlen = strlen (t); + /* Use the canonicalized version of NEWDIR, or, if canonicalization failed, use the non-canonical form. */ canon_failed = 0; @@ -411,7 +436,7 @@ change_to_directory (newdir, nolinks) /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath returns NULL (because it checks the path, it will return NULL if the resolved path doesn't exist), fail immediately. */ - if (posixly_correct && nolinks == 0 && canon_failed) + if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX)) { #if defined ENAMETOOLONG if (errno != ENOENT && errno != ENAMETOOLONG) @@ -419,6 +444,7 @@ change_to_directory (newdir, nolinks) if (errno != ENOENT) #endif errno = ENOTDIR; + free (tdir); return (0); } @@ -436,13 +462,17 @@ change_to_directory (newdir, nolinks) else set_working_directory (tdir); + free (tdir); return (1); } /* We failed to change to the appropriate directory name. If we tried what the user passed (nolinks != 0), punt now. */ if (nolinks) - return (0); + { + free (tdir); + return (0); + } err = errno; |
