1 This file is cd.def, from which is created cd.c. It implements the
2 builtins "cd" and "pwd" in Bash.
4 Copyright (C) 1987-2013 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
24 #if defined (HAVE_UNISTD_H)
26 # include <sys/types.h>
31 #include "../bashtypes.h"
33 #include "posixstat.h"
34 #if defined (HAVE_SYS_PARAM_H)
35 #include <sys/param.h>
41 #include "../bashansi.h"
42 #include "../bashintl.h"
45 #include <tilde/tilde.h>
51 #include "bashgetopt.h"
57 extern int posixly_correct;
58 extern int array_needs_making;
59 extern const char * const bash_getcwd_errstr;
61 static int bindpwd __P((int));
62 static int setpwd __P((char *));
63 static char *resetpwd __P((char *));
64 static int change_to_directory __P((char *, int, int));
66 static int cdxattr __P((char *, char **));
67 static void resetxattr __P((void));
69 /* Change this to 1 to get cd spelling correction by default. */
74 static int eflag; /* file scope so bindpwd() can see it */
75 static int xattrflag; /* O_XATTR support for openat */
76 static int xattrfd = -1;
80 $SHORT_DOC cd [-L|[-P [-e]] [-@]] [dir]
81 Change the shell working directory.
83 Change the current directory to DIR. The default DIR is the value of the
86 The variable CDPATH defines the search path for the directory containing
87 DIR. Alternative directory names in CDPATH are separated by a colon (:).
88 A null directory name is the same as the current directory. If DIR begins
89 with a slash (/), then CDPATH is not used.
91 If the directory is not found, and the shell option `cdable_vars' is set,
92 the word is assumed to be a variable name. If that variable has a value,
93 its value is used for DIR.
96 -L force symbolic links to be followed: resolve symbolic links in
97 DIR after processing instances of `..'
98 -P use the physical directory structure without following symbolic
99 links: resolve symbolic links in DIR before processing instances
101 -e if the -P option is supplied, and the current working directory
102 cannot be determined successfully, exit with a non-zero status
103 #if defined (O_XATTR)
104 -@ on systems that support it, present a file with extended attributes
105 as a directory containing the file attributes
108 The default is to follow symbolic links, as if `-L' were specified.
109 `..' is processed by removing the immediately previous pathname component
110 back to a slash or the beginning of DIR.
113 Returns 0 if the directory is changed, and if $PWD is set successfully when
114 -P is used; non-zero otherwise.
117 /* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */
125 old_anm = array_needs_making;
126 tvar = bind_variable ("PWD", dirname ? dirname : "", 0);
127 if (tvar && readonly_p (tvar))
128 return EXECUTION_FAILURE;
129 if (tvar && old_anm == 0 && array_needs_making && exported_p (tvar))
131 update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
132 array_needs_making = 0;
134 return EXECUTION_SUCCESS;
138 bindpwd (no_symlinks)
141 char *dirname, *pwdvar;
145 r = sh_chkwrite (EXECUTION_SUCCESS);
147 #define tcwd the_current_working_directory
148 dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
149 : get_working_directory ("cd");
152 old_anm = array_needs_making;
153 pwdvar = get_string_value ("PWD");
155 tvar = bind_variable ("OLDPWD", pwdvar, 0);
156 if (tvar && readonly_p (tvar))
157 r = EXECUTION_FAILURE;
159 if (old_anm == 0 && array_needs_making && exported_p (tvar))
161 update_export_env_inplace ("OLDPWD=", 7, pwdvar);
162 array_needs_making = 0;
165 if (setpwd (dirname) == EXECUTION_FAILURE)
166 r = EXECUTION_FAILURE;
167 if (dirname == 0 && eflag)
168 r = EXECUTION_FAILURE;
170 if (dirname && dirname != the_current_working_directory)
176 /* Call get_working_directory to reset the value of
177 the_current_working_directory () */
184 FREE (the_current_working_directory);
185 the_current_working_directory = (char *)NULL;
186 tdir = get_working_directory (caller);
192 char *dir; /* don't assume we can always free DIR */
193 char **ndirp; /* return new constructed directory name */
195 #if defined (O_XATTR)
197 char buf[11+40+40]; /* construct new `fake' path for pwd */
199 apfd = openat (AT_FDCWD, dir, O_RDONLY|O_NONBLOCK);
202 fd = openat (apfd, ".", O_XATTR);
204 close (apfd); /* ignore close error for now */
208 r = fchdir (fd); /* assume fchdir exists everywhere with O_XATTR */
214 /* NFSv4 and ZFS extended attribute directories do not have names which are
215 visible in the standard Unix directory tree structure. To ensure we have
216 a valid name for $PWD, we synthesize one under /proc, but to keep that
217 path valid, we need to keep the file descriptor open as long as we are in
218 this directory. This imposes a certain structure on /proc. */
221 sprintf (buf, "/proc/%d/fd/%d", getpid(), fd);
222 *ndirp = savestring (buf);
235 /* Clean up the O_XATTR baggage. Currently only closes xattrfd */
239 #if defined (O_XATTR)
246 xattrfd = -1; /* not strictly necessary */
250 #define LCD_DOVARS 0x001
251 #define LCD_DOSPELL 0x002
252 #define LCD_PRINTPATH 0x004
253 #define LCD_FREEDIRNAME 0x008
255 /* This builtin is ultimately the way that all user-visible commands should
256 change the current working directory. It is called by cd_to_string (),
257 so the programming interface is simple, and it handles errors and
258 restrictions properly. */
263 char *dirname, *cdpath, *path, *temp;
264 int path_index, no_symlinks, opt, lflag;
266 #if defined (RESTRICTED_SHELL)
269 sh_restricted ((char *)NULL);
270 return (EXECUTION_FAILURE);
272 #endif /* RESTRICTED_SHELL */
275 no_symlinks = no_symbolic_links;
277 reset_internal_getopt ();
278 #if defined (O_XATTR)
279 while ((opt = internal_getopt (list, "eLP@")) != -1)
281 while ((opt = internal_getopt (list, "eLP")) != -1)
295 #if defined (O_XATTR)
307 lflag = (cdable_vars ? LCD_DOVARS : 0) |
308 ((interactive && cdspelling) ? LCD_DOSPELL : 0);
309 if (eflag && no_symlinks == 0)
314 /* `cd' without arguments is equivalent to `cd $HOME' */
315 dirname = get_string_value ("HOME");
319 builtin_error (_("HOME not set"));
320 return (EXECUTION_FAILURE);
324 #if defined (CD_COMPLAINS)
327 builtin_error (_("too many arguments"));
328 return (EXECUTION_FAILURE);
331 else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
333 /* This is `cd -', equivalent to `cd $OLDPWD' */
334 dirname = get_string_value ("OLDPWD");
338 builtin_error (_("OLDPWD not set"));
339 return (EXECUTION_FAILURE);
342 lflag = interactive ? LCD_PRINTPATH : 0;
344 lflag = LCD_PRINTPATH; /* According to SUSv3 */
347 else if (absolute_pathname (list->word->word))
348 dirname = list->word->word;
349 else if (privileged_mode == 0 && (cdpath = get_string_value ("CDPATH")))
351 dirname = list->word->word;
353 /* Find directory in $CDPATH. */
355 while (path = extract_colon_unit (cdpath, &path_index))
357 /* OPT is 1 if the path element is non-empty */
358 opt = path[0] != '\0';
359 temp = sh_makepath (path, dirname, MP_DOTILDE);
362 if (change_to_directory (temp, no_symlinks, xattrflag))
364 /* POSIX.2 says that if a nonempty directory from CDPATH
365 is used to find the directory to change to, the new
366 directory name is echoed to stdout, whether or not
367 the shell is interactive. */
368 if (opt && (path = no_symlinks ? temp : the_current_working_directory))
369 printf ("%s\n", path);
373 /* Posix.2 says that after using CDPATH, the resultant
374 value of $PWD will not contain `.' or `..'. */
375 return (bindpwd (posixly_correct || no_symlinks));
377 return (bindpwd (no_symlinks));
385 /* changed for bash-4.2 Posix cd description steps 5-6 */
386 /* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
387 try the current directory, so we just punt now with an error
388 message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
389 is so we don't mistakenly treat a CDPATH value of "" as not
390 specifying the current directory. */
391 if (posixly_correct && cdpath[0])
393 builtin_error ("%s: %s", dirname, strerror (ENOENT));
394 return (EXECUTION_FAILURE);
399 dirname = list->word->word;
401 /* When we get here, DIRNAME is the directory to change to. If we
402 chdir successfully, just return. */
403 if (change_to_directory (dirname, no_symlinks, xattrflag))
405 if (lflag & LCD_PRINTPATH)
406 printf ("%s\n", dirname);
407 return (bindpwd (no_symlinks));
410 /* If the user requests it, then perhaps this is the name of
411 a shell variable, whose value contains the directory to
413 if (lflag & LCD_DOVARS)
415 temp = get_string_value (dirname);
416 if (temp && change_to_directory (temp, no_symlinks, xattrflag))
418 printf ("%s\n", temp);
419 return (bindpwd (no_symlinks));
423 /* If the user requests it, try to find a directory name similar in
424 spelling to the one requested, in case the user made a simple
425 typo. This is similar to the UNIX 8th and 9th Edition shells. */
426 if (lflag & LCD_DOSPELL)
428 temp = dirspell (dirname);
429 if (temp && change_to_directory (temp, no_symlinks, xattrflag))
431 printf ("%s\n", temp);
433 return (bindpwd (no_symlinks));
439 builtin_error ("%s: %s", dirname, strerror (errno));
440 return (EXECUTION_FAILURE);
444 $FUNCTION pwd_builtin
446 Print the name of the current working directory.
449 -L print the value of $PWD if it names the current working
451 -P print the physical directory, without any symbolic links
453 By default, `pwd' behaves as if `-L' were specified.
456 Returns 0 unless an invalid option is given or the current directory
460 /* Non-zero means that pwd always prints the physical directory, without
462 static int verbatim_pwd;
464 /* Print the name of the current working directory. */
472 verbatim_pwd = no_symbolic_links;
474 reset_internal_getopt ();
475 while ((opt = internal_getopt (list, "LP")) != -1)
480 verbatim_pwd = pflag = 1;
492 #define tcwd the_current_working_directory
494 directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd)
495 : get_working_directory ("pwd");
497 /* Try again using getcwd() if canonicalization fails (for instance, if
498 the file system has changed state underneath bash). */
499 if ((tcwd && directory == 0) ||
500 (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
502 if (directory && directory != tcwd)
504 directory = resetpwd ("pwd");
511 opt = EXECUTION_SUCCESS;
512 printf ("%s\n", directory);
513 /* This is dumb but posix-mandated. */
514 if (posixly_correct && pflag)
515 opt = setpwd (directory);
516 if (directory != the_current_working_directory)
518 return (sh_chkwrite (opt));
521 return (EXECUTION_FAILURE);
524 /* Do the work of changing to the directory NEWDIR. Handle symbolic
525 link following, etc. This function *must* return with
526 the_current_working_directory either set to NULL (in which case
527 getcwd() will eventually be called), or set to a string corresponding
528 to the working directory. Return 1 on success, 0 on failure. */
531 change_to_directory (newdir, nolinks, xattr)
535 char *t, *tdir, *ndir;
536 int err, canon_failed, r, ndlen, dlen;
540 if (the_current_working_directory == 0)
542 t = get_working_directory ("chdir");
546 t = make_absolute (newdir, the_current_working_directory);
548 /* TDIR is either the canonicalized absolute pathname of NEWDIR
549 (nolinks == 0) or the absolute physical pathname of NEWDIR
551 tdir = nolinks ? sh_physpath (t, 0)
552 : sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
554 ndlen = strlen (newdir);
557 /* Use the canonicalized version of NEWDIR, or, if canonicalization
558 failed, use the non-canonical form. */
569 /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath
570 returns NULL (because it checks the path, it will return NULL if the
571 resolved path doesn't exist), fail immediately. */
572 if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
574 #if defined ENAMETOOLONG
575 if (errno != ENOENT && errno != ENAMETOOLONG)
584 #if defined (O_XATTR)
587 r = cdxattr (nolinks ? newdir : tdir, &ndir);
599 return (0); /* no xattr */
605 r = chdir (nolinks ? newdir : tdir);
610 /* If the chdir succeeds, update the_current_working_directory. */
613 /* If canonicalization failed, but the chdir succeeded, reset the
614 shell's idea of the_current_working_directory. */
619 set_working_directory (tdir);
624 set_working_directory (tdir);
630 /* We failed to change to the appropriate directory name. If we tried
631 what the user passed (nolinks != 0), punt now. */
640 /* We're not in physical mode (nolinks == 0), but we failed to change to
641 the canonicalized directory name (TDIR). Try what the user passed
642 verbatim. If we succeed, reinitialize the_current_working_directory. */
643 if (chdir (newdir) == 0)
647 set_working_directory (tdir);