OpenCoverage

cd.def

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/bash/src/builtins/cd.def
Source codeSwitch to Preprocessed file
LineSourceCount
1This file is cd.def, from which is created cd.c. It implements the-
2builtins "cd" and "pwd" in Bash.-
3-
4Copyright (C) 1987-2016 Free Software Foundation, Inc.-
5-
6This file is part of GNU Bash, the Bourne Again SHell.-
7-
8Bash is free software: you can redistribute it and/or modify-
9it under the terms of the GNU General Public License as published by-
10the Free Software Foundation, either version 3 of the License, or-
11(at your option) any later version.-
12-
13Bash is distributed in the hope that it will be useful,-
14but WITHOUT ANY WARRANTY; without even the implied warranty of-
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
16GNU General Public License for more details.-
17-
18You should have received a copy of the GNU General Public License-
19along with Bash. If not, see <http://www.gnu.org/licenses/>.-
20-
21$PRODUCES cd.c-
22#include <config.h>-
23-
24#if defined (HAVE_UNISTD_H)-
25# ifdef _MINIX-
26# include <sys/types.h>-
27# endif-
28# include <unistd.h>-
29#endif-
30-
31#include "../bashtypes.h"-
32#include "posixdir.h"-
33#include "posixstat.h"-
34#if defined (HAVE_SYS_PARAM_H)-
35#include <sys/param.h>-
36#endif-
37#include <fcntl.h>-
38-
39#include <stdio.h>-
40-
41#include "../bashansi.h"-
42#include "../bashintl.h"-
43-
44#include <errno.h>-
45#include <tilde/tilde.h>-
46-
47#include "../shell.h"-
48#include "../flags.h"-
49#include "maxpath.h"-
50#include "common.h"-
51#include "bashgetopt.h"-
52-
53#if !defined (errno)-
54extern int errno;-
55#endif /* !errno */-
56-
57extern const char * const bash_getcwd_errstr;-
58-
59static int bindpwd __P((int));-
60static int setpwd __P((char *));-
61static char *resetpwd __P((char *));-
62static int change_to_directory __P((char *, int, int));-
63-
64static int cdxattr __P((char *, char **));-
65static void resetxattr __P((void));-
66-
67/* Change this to 1 to get cd spelling correction by default. */-
68int cdspelling = 0;-
69-
70int cdable_vars;-
71-
72static int eflag; /* file scope so bindpwd() can see it */-
73static int xattrflag; /* O_XATTR support for openat */-
74static int xattrfd = -1;-
75-
76$BUILTIN cd-
77$FUNCTION cd_builtin-
78$SHORT_DOC cd [-L|[-P [-e]] [-@]] [dir]-
79Change the shell working directory.-
80-
81Change the current directory to DIR. The default DIR is the value of the-
82HOME shell variable.-
83-
84The variable CDPATH defines the search path for the directory containing-
85DIR. Alternative directory names in CDPATH are separated by a colon (:).-
86A null directory name is the same as the current directory. If DIR begins-
87with a slash (/), then CDPATH is not used.-
88-
89If the directory is not found, and the shell option `cdable_vars' is set,-
90the word is assumed to be a variable name. If that variable has a value,-
91its value is used for DIR.-
92-
93Options:-
94 -L force symbolic links to be followed: resolve symbolic-
95 links in DIR after processing instances of `..'-
96 -P use the physical directory structure without following-
97 symbolic links: resolve symbolic links in DIR before-
98 processing instances of `..'-
99 -e if the -P option is supplied, and the current working-
100 directory cannot be determined successfully, exit with-
101 a non-zero status-
102#if defined (O_XATTR)-
103 -@ on systems that support it, present a file with extended-
104 attributes as a directory containing the file attributes-
105#endif-
106-
107The default is to follow symbolic links, as if `-L' were specified.-
108`..' is processed by removing the immediately previous pathname component-
109back to a slash or the beginning of DIR.-
110-
111Exit Status:-
112Returns 0 if the directory is changed, and if $PWD is set successfully when-
113-P is used; non-zero otherwise.-
114$END-
115-
116/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */-
117static int-
118setpwd (dirname)-
119 char *dirname;-
120{-
121 int old_anm;-
122 SHELL_VAR *tvar;-
123-
124 old_anm = array_needs_making;-
125 tvar = bind_variable ("PWD", dirname ? dirname : "", 0);-
126 if (tvar && readonly_p (tvar))
tvarDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
((((tvar)->att... (0x0000002)))Description
TRUEnever evaluated
FALSEevaluated 66 times by 1 test
Evaluated by:
  • Self test
0-66
127 return EXECUTION_FAILURE;
never executed: return 1;
0
128 if (tvar && old_anm == 0 && array_needs_making && exported_p (tvar))
tvarDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
old_anm == 0Description
TRUEevaluated 44 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 22 times by 1 test
Evaluated by:
  • Self test
array_needs_makingDescription
TRUEevaluated 44 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
((((tvar)->att... (0x0000001)))Description
TRUEevaluated 44 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-66
129 {-
130 update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");-
131 array_needs_making = 0;-
132 }
executed 44 times by 1 test: end of block
Executed by:
  • Self test
44
133 return EXECUTION_SUCCESS;
executed 66 times by 1 test: return 0;
Executed by:
  • Self test
66
134}-
135-
136static int-
137bindpwd (no_symlinks)-
138 int no_symlinks;-
139{-
140 char *dirname, *pwdvar;-
141 int old_anm, r;-
142 SHELL_VAR *tvar;-
143-
144 r = sh_chkwrite (EXECUTION_SUCCESS);-
145-
146#define tcwd the_current_working_directory-
147 dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
the_current_working_directoryDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
no_symlinksDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 65 times by 1 test
Evaluated by:
  • Self test
0-66
148 : get_working_directory ("cd");-
149#undef tcwd-
150-
151 old_anm = array_needs_making;-
152 pwdvar = get_string_value ("PWD");-
153-
154 tvar = bind_variable ("OLDPWD", pwdvar, 0);-
155 if (tvar && readonly_p (tvar))
tvarDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
((((tvar)->att... (0x0000002)))Description
TRUEnever evaluated
FALSEevaluated 66 times by 1 test
Evaluated by:
  • Self test
0-66
156 r = EXECUTION_FAILURE;
never executed: r = 1;
0
157-
158 if (old_anm == 0 && array_needs_making && exported_p (tvar))
old_anm == 0Description
TRUEevaluated 44 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 22 times by 1 test
Evaluated by:
  • Self test
array_needs_makingDescription
TRUEevaluated 44 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
((((tvar)->att... (0x0000001)))Description
TRUEevaluated 44 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-44
159 {-
160 update_export_env_inplace ("OLDPWD=", 7, pwdvar);-
161 array_needs_making = 0;-
162 }
executed 44 times by 1 test: end of block
Executed by:
  • Self test
44
163-
164 if (setpwd (dirname) == EXECUTION_FAILURE)
setpwd (dirname) == 1Description
TRUEnever evaluated
FALSEevaluated 66 times by 1 test
Evaluated by:
  • Self test
0-66
165 r = EXECUTION_FAILURE;
never executed: r = 1;
0
166 if (dirname == 0 && eflag)
dirname == 0Description
TRUEnever evaluated
FALSEevaluated 66 times by 1 test
Evaluated by:
  • Self test
eflagDescription
TRUEnever evaluated
FALSEnever evaluated
0-66
167 r = EXECUTION_FAILURE;
never executed: r = 1;
0
168-
169 if (dirname && dirname != the_current_working_directory)
dirnameDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
dirname != the...king_directoryDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 65 times by 1 test
Evaluated by:
  • Self test
0-66
170 free (dirname);
executed 1 time by 1 test: sh_xfree((dirname), "./cd.def", 170);
Executed by:
  • Self test
1
171-
172 return (r);
executed 66 times by 1 test: return (r);
Executed by:
  • Self test
66
173}-
174-
175/* Call get_working_directory to reset the value of-
176 the_current_working_directory () */-
177static char *-
178resetpwd (caller)-
179 char *caller;-
180{-
181 char *tdir;-
182 -
183 FREE (the_current_working_directory);
never executed: sh_xfree((the_current_working_directory), "./cd.def", 183);
the_current_working_directoryDescription
TRUEnever evaluated
FALSEnever evaluated
0
184 the_current_working_directory = (char *)NULL;-
185 tdir = get_working_directory (caller);-
186 return (tdir);
never executed: return (tdir);
0
187}-
188-
189static int-
190cdxattr (dir, ndirp)-
191 char *dir; /* don't assume we can always free DIR */-
192 char **ndirp; /* return new constructed directory name */-
193{-
194#if defined (O_XATTR)-
195 int apfd, fd, r, e;-
196 char buf[11+40+40]; /* construct new `fake' path for pwd */-
197-
198 apfd = openat (AT_FDCWD, dir, O_RDONLY|O_NONBLOCK);-
199 if (apfd < 0)-
200 return -1;-
201 fd = openat (apfd, ".", O_XATTR);-
202 e = errno;-
203 close (apfd); /* ignore close error for now */-
204 errno = e;-
205 if (fd < 0)-
206 return -1;-
207 r = fchdir (fd); /* assume fchdir exists everywhere with O_XATTR */-
208 if (r < 0)-
209 {-
210 close (fd);-
211 return -1;-
212 }-
213 /* NFSv4 and ZFS extended attribute directories do not have names which are-
214 visible in the standard Unix directory tree structure. To ensure we have-
215 a valid name for $PWD, we synthesize one under /proc, but to keep that-
216 path valid, we need to keep the file descriptor open as long as we are in-
217 this directory. This imposes a certain structure on /proc. */-
218 if (ndirp)-
219 {-
220 sprintf (buf, "/proc/%d/fd/%d", getpid(), fd);-
221 *ndirp = savestring (buf);-
222 }-
223-
224 if (xattrfd >= 0)-
225 close (xattrfd);-
226 xattrfd = fd; -
227-
228 return r;-
229#else-
230 return -1;
never executed: return -1;
0
231#endif-
232}-
233-
234/* Clean up the O_XATTR baggage. Currently only closes xattrfd */-
235static void-
236resetxattr ()-
237{-
238#if defined (O_XATTR)-
239 if (xattrfd >= 0)-
240 {-
241 close (xattrfd);-
242 xattrfd = -1;-
243 }-
244#else-
245 xattrfd = -1; /* not strictly necessary */-
246#endif-
247}
executed 66 times by 1 test: end of block
Executed by:
  • Self test
66
248-
249#define LCD_DOVARS 0x001-
250#define LCD_DOSPELL 0x002-
251#define LCD_PRINTPATH 0x004-
252#define LCD_FREEDIRNAME 0x008-
253-
254/* This builtin is ultimately the way that all user-visible commands should-
255 change the current working directory. It is called by cd_to_string (),-
256 so the programming interface is simple, and it handles errors and-
257 restrictions properly. */-
258int-
259cd_builtin (list)-
260 WORD_LIST *list;-
261{-
262 char *dirname, *cdpath, *path, *temp;-
263 int path_index, no_symlinks, opt, lflag, e;-
264-
265#if defined (RESTRICTED_SHELL)-
266 if (restricted)
restrictedDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 73 times by 1 test
Evaluated by:
  • Self test
1-73
267 {-
268 sh_restricted ((char *)NULL);-
269 return (EXECUTION_FAILURE);
executed 1 time by 1 test: return (1);
Executed by:
  • Self test
1
270 }-
271#endif /* RESTRICTED_SHELL */-
272-
273 eflag = 0;-
274 no_symlinks = no_symbolic_links;-
275 xattrflag = 0;-
276 reset_internal_getopt ();-
277#if defined (O_XATTR)-
278 while ((opt = internal_getopt (list, "eLP@")) != -1)-
279#else-
280 while ((opt = internal_getopt (list, "eLP")) != -1)
(opt = interna... "eLP")) != -1Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 73 times by 1 test
Evaluated by:
  • Self test
1-73
281#endif-
282 {-
283 switch (opt)-
284 {-
285 case 'P':
executed 1 time by 1 test: case 'P':
Executed by:
  • Self test
1
286 no_symlinks = 1;-
287 break;
executed 1 time by 1 test: break;
Executed by:
  • Self test
1
288 case 'L':
never executed: case 'L':
0
289 no_symlinks = 0;-
290 break;
never executed: break;
0
291 case 'e':
never executed: case 'e':
0
292 eflag = 1;-
293 break;
never executed: break;
0
294#if defined (O_XATTR)-
295 case '@':-
296 xattrflag = 1;-
297 break;-
298#endif-
299 CASE_HELPOPT;
never executed: return (258);
never executed: case -99:
0
300 default:
never executed: default:
0
301 builtin_usage ();-
302 return (EX_USAGE);
never executed: return (258);
0
303 }-
304 }-
305 list = loptend;-
306-
307 lflag = (cdable_vars ? LCD_DOVARS : 0) |
cdable_varsDescription
TRUEnever evaluated
FALSEevaluated 73 times by 1 test
Evaluated by:
  • Self test
0-73
308 ((interactive && cdspelling) ? LCD_DOSPELL : 0);-
309 if (eflag && no_symlinks == 0)
eflagDescription
TRUEnever evaluated
FALSEevaluated 73 times by 1 test
Evaluated by:
  • Self test
no_symlinks == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-73
310 eflag = 0;
never executed: eflag = 0;
0
311-
312 if (list == 0)
list == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 71 times by 1 test
Evaluated by:
  • Self test
2-71
313 {-
314 /* `cd' without arguments is equivalent to `cd $HOME' */-
315 dirname = get_string_value ("HOME");-
316-
317 if (dirname == 0)
dirname == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
1
318 {-
319 builtin_error (_("HOME not set"));-
320 return (EXECUTION_FAILURE);
executed 1 time by 1 test: return (1);
Executed by:
  • Self test
1
321 }-
322 lflag = 0;-
323 }
executed 1 time by 1 test: end of block
Executed by:
  • Self test
1
324#if defined (CD_COMPLAINS)-
325 else if (list->next)
list->nextDescription
TRUEnever evaluated
FALSEevaluated 71 times by 1 test
Evaluated by:
  • Self test
0-71
326 {-
327 builtin_error (_("too many arguments"));-
328 return (EXECUTION_FAILURE);
never executed: return (1);
0
329 }-
330#endif-
331#if 0-
332 else if (list->word->word[0] == '\0')-
333 {-
334 builtin_error (_("null directory"));-
335 return (EXECUTION_FAILURE);-
336 }-
337#endif-
338 else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
list->word->word[0] == '-'Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 69 times by 1 test
Evaluated by:
  • Self test
list->word->word[1] == '\0'Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-69
339 {-
340 /* This is `cd -', equivalent to `cd $OLDPWD' */-
341 dirname = get_string_value ("OLDPWD");-
342-
343 if (dirname == 0)
dirname == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
1
344 {-
345 builtin_error (_("OLDPWD not set"));-
346 return (EXECUTION_FAILURE);
executed 1 time by 1 test: return (1);
Executed by:
  • Self test
1
347 }-
348#if 0-
349 lflag = interactive ? LCD_PRINTPATH : 0;-
350#else-
351 lflag = LCD_PRINTPATH; /* According to SUSv3 */-
352#endif-
353 }
executed 1 time by 1 test: end of block
Executed by:
  • Self test
1
354 else if (absolute_pathname (list->word->word))
absolute_pathn...t->word->word)Description
TRUEevaluated 67 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test
2-67
355 dirname = list->word->word;
executed 67 times by 1 test: dirname = list->word->word;
Executed by:
  • Self test
67
356 else if (privileged_mode == 0 && (cdpath = get_string_value ("CDPATH")))
privileged_mode == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
(cdpath = get_...ue ("CDPATH"))Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
0-2
357 {-
358 dirname = list->word->word;-
359-
360 /* Find directory in $CDPATH. */-
361 path_index = 0;-
362 while (path = extract_colon_unit (cdpath, &path_index))
path = extract..., &path_index)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-2
363 {-
364 /* OPT is 1 if the path element is non-empty */-
365 opt = path[0] != '\0';-
366 temp = sh_makepath (path, dirname, MP_DOTILDE);-
367 free (path);-
368-
369 if (change_to_directory (temp, no_symlinks, xattrflag))
change_to_dire...ks, xattrflag)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
1
370 {-
371 /* POSIX.2 says that if a nonempty directory from CDPATH-
372 is used to find the directory to change to, the new-
373 directory name is echoed to stdout, whether or not-
374 the shell is interactive. */-
375 if (opt && (path = no_symlinks ? temp : the_current_working_directory))
no_symlinksDescription
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test
optDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
(path = no_sym...ing_directory)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-1
376 printf ("%s\n", path);
executed 1 time by 1 test: printf ("%s\n", path);
Executed by:
  • Self test
1
377-
378 free (temp);-
379#if 0-
380 /* Posix.2 says that after using CDPATH, the resultant-
381 value of $PWD will not contain `.' or `..'. */-
382 return (bindpwd (posixly_correct || no_symlinks));-
383#else-
384 return (bindpwd (no_symlinks));
executed 1 time by 1 test: return (bindpwd (no_symlinks));
Executed by:
  • Self test
1
385#endif-
386 }-
387 else-
388 free (temp);
executed 1 time by 1 test: sh_xfree((temp), "./cd.def", 388);
Executed by:
  • Self test
1
389 }-
390-
391#if 0-
392 /* changed for bash-4.2 Posix cd description steps 5-6 */-
393 /* POSIX.2 says that if `.' does not appear in $CDPATH, we don't-
394 try the current directory, so we just punt now with an error-
395 message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]-
396 is so we don't mistakenly treat a CDPATH value of "" as not-
397 specifying the current directory. */-
398 if (posixly_correct && cdpath[0])-
399 {-
400 builtin_error ("%s: %s", dirname, strerror (ENOENT));-
401 return (EXECUTION_FAILURE);-
402 }-
403#endif-
404 }
never executed: end of block
0
405 else-
406 dirname = list->word->word;
executed 1 time by 1 test: dirname = list->word->word;
Executed by:
  • Self test
1
407-
408 /* When we get here, DIRNAME is the directory to change to. If we-
409 chdir successfully, just return. */-
410 if (change_to_directory (dirname, no_symlinks, xattrflag))
change_to_dire...ks, xattrflag)Description
TRUEevaluated 65 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
5-65
411 {-
412 if (lflag & LCD_PRINTPATH)
lflag & 0x004Description
TRUEnever evaluated
FALSEevaluated 65 times by 1 test
Evaluated by:
  • Self test
0-65
413 printf ("%s\n", dirname);
never executed: printf ("%s\n", dirname);
0
414 return (bindpwd (no_symlinks));
executed 65 times by 1 test: return (bindpwd (no_symlinks));
Executed by:
  • Self test
65
415 }-
416-
417 /* If the user requests it, then perhaps this is the name of-
418 a shell variable, whose value contains the directory to-
419 change to. */-
420 if (lflag & LCD_DOVARS)
lflag & 0x001Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
0-5
421 {-
422 temp = get_string_value (dirname);-
423 if (temp && change_to_directory (temp, no_symlinks, xattrflag))
tempDescription
TRUEnever evaluated
FALSEnever evaluated
change_to_dire...ks, xattrflag)Description
TRUEnever evaluated
FALSEnever evaluated
0
424 {-
425 printf ("%s\n", temp);-
426 return (bindpwd (no_symlinks));
never executed: return (bindpwd (no_symlinks));
0
427 }-
428 }
never executed: end of block
0
429-
430 /* If the user requests it, try to find a directory name similar in-
431 spelling to the one requested, in case the user made a simple-
432 typo. This is similar to the UNIX 8th and 9th Edition shells. */-
433 if (lflag & LCD_DOSPELL)
lflag & 0x002Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
0-5
434 {-
435 temp = dirspell (dirname);-
436 if (temp && change_to_directory (temp, no_symlinks, xattrflag))
tempDescription
TRUEnever evaluated
FALSEnever evaluated
change_to_dire...ks, xattrflag)Description
TRUEnever evaluated
FALSEnever evaluated
0
437 {-
438 printf ("%s\n", temp);-
439 free (temp);-
440 return (bindpwd (no_symlinks));
never executed: return (bindpwd (no_symlinks));
0
441 }-
442 else-
443 FREE (temp);
never executed: sh_xfree((temp), "./cd.def", 443);
never executed: end of block
tempDescription
TRUEnever evaluated
FALSEnever evaluated
0
444 }-
445-
446 e = errno;-
447 temp = printable_filename (dirname, 0);-
448 builtin_error ("%s: %s", temp, strerror (e));-
449 if (temp != dirname)
temp != dirnameDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 4 times by 1 test
Evaluated by:
  • Self test
1-4
450 free (temp);
executed 1 time by 1 test: sh_xfree((temp), "./cd.def", 450);
Executed by:
  • Self test
1
451 return (EXECUTION_FAILURE);
executed 5 times by 1 test: return (1);
Executed by:
  • Self test
5
452}-
453-
454$BUILTIN pwd-
455$FUNCTION pwd_builtin-
456$SHORT_DOC pwd [-LP]-
457Print the name of the current working directory.-
458-
459Options:-
460 -L print the value of $PWD if it names the current working-
461 directory-
462 -P print the physical directory, without any symbolic links-
463-
464By default, `pwd' behaves as if `-L' were specified.-
465-
466Exit Status:-
467Returns 0 unless an invalid option is given or the current directory-
468cannot be read.-
469$END-
470-
471/* Non-zero means that pwd always prints the physical directory, without-
472 symbolic links. */-
473static int verbatim_pwd;-
474-
475/* Print the name of the current working directory. */-
476int-
477pwd_builtin (list)-
478 WORD_LIST *list;-
479{-
480 char *directory;-
481 int opt, pflag;-
482-
483 verbatim_pwd = no_symbolic_links;-
484 pflag = 0;-
485 reset_internal_getopt ();-
486 while ((opt = internal_getopt (list, "LP")) != -1)
(opt = interna..., "LP")) != -1Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 9 times by 1 test
Evaluated by:
  • Self test
3-9
487 {-
488 switch (opt)-
489 {-
490 case 'P':
executed 2 times by 1 test: case 'P':
Executed by:
  • Self test
2
491 verbatim_pwd = pflag = 1;-
492 break;
executed 2 times by 1 test: break;
Executed by:
  • Self test
2
493 case 'L':
executed 1 time by 1 test: case 'L':
Executed by:
  • Self test
1
494 verbatim_pwd = 0;-
495 break;
executed 1 time by 1 test: break;
Executed by:
  • Self test
1
496 CASE_HELPOPT;
never executed: return (258);
never executed: case -99:
0
497 default:
never executed: default:
0
498 builtin_usage ();-
499 return (EX_USAGE);
never executed: return (258);
0
500 }-
501 }-
502 list = loptend;-
503-
504#define tcwd the_current_working_directory-
505-
506 directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd)
the_current_working_directoryDescription
TRUEevaluated 9 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
verbatim_pwdDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 7 times by 1 test
Evaluated by:
  • Self test
0-9
507 : get_working_directory ("pwd");-
508-
509 /* Try again using getcwd() if canonicalization fails (for instance, if-
510 the file system has changed state underneath bash). */-
511 if ((tcwd && directory == 0) ||
the_current_working_directoryDescription
TRUEevaluated 9 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
directory == 0Description
TRUEnever evaluated
FALSEevaluated 9 times by 1 test
Evaluated by:
  • Self test
0-9
512 (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
posixly_correctDescription
TRUEnever evaluated
FALSEevaluated 9 times by 1 test
Evaluated by:
  • Self test
same_file ("."...stat *)0) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-9
513 {-
514 if (directory && directory != tcwd)
directoryDescription
TRUEnever evaluated
FALSEnever evaluated
directory != t...king_directoryDescription
TRUEnever evaluated
FALSEnever evaluated
0
515 free (directory);
never executed: sh_xfree((directory), "./cd.def", 515);
0
516 directory = resetpwd ("pwd");-
517 }
never executed: end of block
0
518-
519#undef tcwd-
520-
521 if (directory)
directoryDescription
TRUEevaluated 9 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-9
522 {-
523 opt = EXECUTION_SUCCESS;-
524 printf ("%s\n", directory);-
525 /* This is dumb but posix-mandated. */-
526 if (posixly_correct && pflag)
posixly_correctDescription
TRUEnever evaluated
FALSEevaluated 9 times by 1 test
Evaluated by:
  • Self test
pflagDescription
TRUEnever evaluated
FALSEnever evaluated
0-9
527 opt = setpwd (directory);
never executed: opt = setpwd (directory);
0
528 if (directory != the_current_working_directory)
directory != t...king_directoryDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 7 times by 1 test
Evaluated by:
  • Self test
2-7
529 free (directory);
executed 2 times by 1 test: sh_xfree((directory), "./cd.def", 529);
Executed by:
  • Self test
2
530 return (sh_chkwrite (opt));
executed 9 times by 1 test: return (sh_chkwrite (opt));
Executed by:
  • Self test
9
531 }-
532 else-
533 return (EXECUTION_FAILURE);
never executed: return (1);
0
534}-
535-
536/* Do the work of changing to the directory NEWDIR. Handle symbolic-
537 link following, etc. This function *must* return with-
538 the_current_working_directory either set to NULL (in which case-
539 getcwd() will eventually be called), or set to a string corresponding-
540 to the working directory. Return 1 on success, 0 on failure. */-
541-
542static int-
543change_to_directory (newdir, nolinks, xattr)-
544 char *newdir;-
545 int nolinks, xattr;-
546{-
547 char *t, *tdir, *ndir;-
548 int err, canon_failed, r, ndlen;-
549-
550 tdir = (char *)NULL;-
551-
552 if (the_current_working_directory == 0)
the_current_wo...directory == 0Description
TRUEnever evaluated
FALSEevaluated 72 times by 1 test
Evaluated by:
  • Self test
0-72
553 {-
554 t = get_working_directory ("chdir");-
555 FREE (t);
never executed: sh_xfree((t), "./cd.def", 555);
tDescription
TRUEnever evaluated
FALSEnever evaluated
0
556 }
never executed: end of block
0
557-
558 t = make_absolute (newdir, the_current_working_directory);-
559-
560 /* TDIR is either the canonicalized absolute pathname of NEWDIR-
561 (nolinks == 0) or the absolute physical pathname of NEWDIR-
562 (nolinks != 0). */-
563 tdir = nolinks ? sh_physpath (t, 0)
nolinksDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 71 times by 1 test
Evaluated by:
  • Self test
1-71
564 : sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);-
565-
566 ndlen = strlen (newdir);-
567-
568 /* Use the canonicalized version of NEWDIR, or, if canonicalization-
569 failed, use the non-canonical form. */-
570 canon_failed = 0;-
571 if (tdir && *tdir)
tdirDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 6 times by 1 test
Evaluated by:
  • Self test
*tdirDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-66
572 free (t);
executed 66 times by 1 test: sh_xfree((t), "./cd.def", 572);
Executed by:
  • Self test
66
573 else-
574 {-
575 FREE (tdir);
never executed: sh_xfree((tdir), "./cd.def", 575);
tdirDescription
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • Self test
0-6
576 tdir = t;-
577 canon_failed = 1;-
578 }
executed 6 times by 1 test: end of block
Executed by:
  • Self test
6
579-
580 /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath-
581 returns NULL (because it checks the path, it will return NULL if the-
582 resolved path doesn't exist), fail immediately. */-
583 if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
posixly_correctDescription
TRUEnever evaluated
FALSEevaluated 72 times by 1 test
Evaluated by:
  • Self test
nolinks == 0Description
TRUEnever evaluated
FALSEnever evaluated
canon_failedDescription
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) != 36Description
TRUEnever evaluated
FALSEnever evaluated
ndlen > 4096Description
TRUEnever evaluated
FALSEnever evaluated
0-72
584 {-
585#if defined ENAMETOOLONG-
586 if (errno != ENOENT && errno != ENAMETOOLONG)
(*__errno_location ()) != 2Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) != 36Description
TRUEnever evaluated
FALSEnever evaluated
0
587#else-
588 if (errno != ENOENT)-
589#endif-
590 errno = ENOTDIR;
never executed: (*__errno_location ()) = 20 ;
0
591 free (tdir);-
592 return (0);
never executed: return (0);
0
593 }-
594-
595#if defined (O_XATTR)-
596 if (xattrflag)-
597 {-
598 r = cdxattr (nolinks ? newdir : tdir, &ndir);-
599 if (r >= 0)-
600 {-
601 canon_failed = 0;-
602 free (tdir);-
603 tdir = ndir;-
604 }-
605 else-
606 {-
607 err = errno;-
608 free (tdir);-
609 errno = err;-
610 return (0); /* no xattr */-
611 }-
612 }-
613 else-
614#endif-
615 {-
616 r = chdir (nolinks ? newdir : tdir);-
617 if (r >= 0)
r >= 0Description
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 6 times by 1 test
Evaluated by:
  • Self test
6-66
618 resetxattr ();
executed 66 times by 1 test: resetxattr ();
Executed by:
  • Self test
66
619 }-
620-
621 /* If the chdir succeeds, update the_current_working_directory. */-
622 if (r == 0)
r == 0Description
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 6 times by 1 test
Evaluated by:
  • Self test
6-66
623 {-
624 /* If canonicalization failed, but the chdir succeeded, reset the-
625 shell's idea of the_current_working_directory. */-
626 if (canon_failed)
canon_failedDescription
TRUEnever evaluated
FALSEevaluated 66 times by 1 test
Evaluated by:
  • Self test
0-66
627 {-
628 t = resetpwd ("cd");-
629 if (t == 0)
t == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
630 set_working_directory (tdir);
never executed: set_working_directory (tdir);
0
631 else-
632 free (t);
never executed: sh_xfree((t), "./cd.def", 632);
0
633 }-
634 else-
635 set_working_directory (tdir);
executed 66 times by 1 test: set_working_directory (tdir);
Executed by:
  • Self test
66
636-
637 free (tdir);-
638 return (1);
executed 66 times by 1 test: return (1);
Executed by:
  • Self test
66
639 }-
640-
641 /* We failed to change to the appropriate directory name. If we tried-
642 what the user passed (nolinks != 0), punt now. */-
643 if (nolinks)
nolinksDescription
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • Self test
0-6
644 {-
645 free (tdir);-
646 return (0);
never executed: return (0);
0
647 }-
648-
649 err = errno;-
650-
651 /* We're not in physical mode (nolinks == 0), but we failed to change to-
652 the canonicalized directory name (TDIR). Try what the user passed-
653 verbatim. If we succeed, reinitialize the_current_working_directory. */-
654 if (chdir (newdir) == 0)
chdir (newdir) == 0Description
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • Self test
0-6
655 {-
656 t = resetpwd ("cd");-
657 if (t == 0)
t == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
658 set_working_directory (tdir);
never executed: set_working_directory (tdir);
0
659 else-
660 free (t);
never executed: sh_xfree((t), "./cd.def", 660);
0
661-
662 r = 1;-
663 }
never executed: end of block
0
664 else-
665 {-
666 errno = err;-
667 r = 0;-
668 }
executed 6 times by 1 test: end of block
Executed by:
  • Self test
6
669-
670 free (tdir);-
671 return r;
executed 6 times by 1 test: return r;
Executed by:
  • Self test
6
672}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2