Imported from ../bash-2.05b.tar.gz.
[platform/upstream/bash.git] / builtins / cd.def
index 77e8f82..1c58c7c 100644 (file)
@@ -69,7 +69,7 @@ int cdable_vars;
 
 $BUILTIN cd
 $FUNCTION cd_builtin
-$SHORT_DOC cd [-PL] [dir]
+$SHORT_DOC cd [-L|-P] [dir]
 Change the current directory to DIR.  The variable $HOME is the
 default DIR.  The variable CDPATH defines the search path for
 the directory containing DIR.  Alternative directory names in CDPATH
@@ -118,6 +118,19 @@ bindpwd (no_symlinks)
   return (EXECUTION_SUCCESS);
 }
 
+/* Call get_working_directory to reset the value of
+   the_current_working_directory () */
+static char *
+resetpwd ()
+{
+  char *tdir;
+      
+  FREE (the_current_working_directory);
+  the_current_working_directory = (char *)NULL;
+  tdir = get_working_directory ("cd");
+  return (tdir);
+}
+
 #define LCD_DOVARS     0x001
 #define LCD_DOSPELL    0x002
 #define LCD_PRINTPATH  0x004
@@ -137,7 +150,7 @@ cd_builtin (list)
 #if defined (RESTRICTED_SHELL)
   if (restricted)
     {
-      builtin_error ("restricted");
+      sh_restricted ((char *)NULL);
       return (EXECUTION_FAILURE);
     }
 #endif /* RESTRICTED_SHELL */
@@ -350,7 +363,7 @@ change_to_directory (newdir, nolinks)
      int nolinks;
 {
   char *t, *tdir;
-  int err;
+  int err, canon_failed;
 
   tdir = (char *)NULL;
 
@@ -370,20 +383,38 @@ change_to_directory (newdir, nolinks)
 
   /* Use the canonicalized version of NEWDIR, or, if canonicalization
      failed, use the non-canonical form. */
+  canon_failed = 0;
   if (tdir && *tdir)
     free (t);
   else
     {
       FREE (tdir);
       tdir = t;
+      canon_failed = 1;
+    }
+
+  /* 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)
+    {
+      errno = ENOENT;
+      return (0);
     }
 
   /* If the chdir succeeds, update the_current_working_directory. */
   if (chdir (nolinks ? newdir : tdir) == 0)
     {
-      FREE (the_current_working_directory);
-      the_current_working_directory = tdir;
-      
+      /* If canonicalization failed, but the chdir succeeded, reset the
+        shell's idea of the_current_working_directory. */
+      if (canon_failed)
+       resetpwd ();
+      else
+       {
+         FREE (the_current_working_directory);
+         the_current_working_directory = tdir;
+       }
+
       return (1);
     }
 
@@ -400,9 +431,7 @@ change_to_directory (newdir, nolinks)
      verbatim. If we succeed, reinitialize the_current_working_directory. */
   if (chdir (newdir) == 0)
     {
-      FREE (the_current_working_directory);
-      the_current_working_directory = (char *)NULL;
-      tdir = get_working_directory ("cd");
+      tdir = resetpwd ();
       FREE (tdir);
 
       return (1);