Mercurial > hg > toybox
comparison toys/posix/pwd.c @ 776:cf101d432225
Getting the pwd -L behavior right is fiddly.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 30 Dec 2012 04:43:11 -0600 |
parents | adab8adf5f6d |
children |
comparison
equal
deleted
inserted
replaced
775:cf7bbafa06d1 | 776:cf101d432225 |
---|---|
1 /* pwd.c - Print working directory. | 1 /* pwd.c - Print working directory. |
2 * | 2 * |
3 * Copyright 2006 Rob Landley <rob@landley.net> | 3 * Copyright 2006 Rob Landley <rob@landley.net> |
4 * | 4 * |
5 * See http://opengroup.org/onlinepubs/9699919799/utilities/echo.html | 5 * See http://opengroup.org/onlinepubs/9699919799/utilities/pwd.html |
6 | 6 |
7 USE_PWD(NEWTOY(pwd, ">0LP[!LP]", TOYFLAG_BIN)) | 7 USE_PWD(NEWTOY(pwd, ">0LP[-LP]", TOYFLAG_BIN)) |
8 | 8 |
9 config PWD | 9 config PWD |
10 bool "pwd" | 10 bool "pwd" |
11 default y | 11 default y |
12 help | 12 help |
13 usage: pwd [-L|-P] | 13 usage: pwd [-L|-P] |
14 | 14 |
15 The print working directory command prints the current directory. | 15 Print working (current) directory. |
16 | 16 |
17 -P Avoid all symlinks | 17 -L Use shell's path from $PWD (when applicable) |
18 -L Use the value of the environment variable "PWD" if valid | 18 -P Print cannonical absolute path |
19 | |
20 The option "-L" is implied by default. | |
21 */ | 19 */ |
22 | 20 |
23 #define FOR_pwd | 21 #define FOR_pwd |
24 #include "toys.h" | 22 #include "toys.h" |
25 | 23 |
26 void pwd_main(void) | 24 void pwd_main(void) |
27 { | 25 { |
28 char *pwd = xgetcwd(), *env_pwd; | 26 char *s, *pwd = getcwd(0, 0), *PWD; |
29 struct stat st[2]; | |
30 | 27 |
31 if (!(toys.optflags & FLAG_P) && (env_pwd = getenv("PWD")) && | 28 // Only use $PWD if it's an absolute path alias for cwd with no "." or ".." |
32 !stat(pwd, &st[0]) && !stat(env_pwd, &st[1]) && | 29 if (!(toys.optflags & FLAG_P) && (s = PWD = getenv("PWD"))) { |
33 (st[0].st_ino == st[1].st_ino)) xprintf("%s\n", env_pwd); | 30 struct stat st1, st2; |
34 else xprintf("%s\n", pwd); | 31 |
32 while (*s == '/') { | |
33 if (*(++s) == '.') { | |
34 if (s[1] == '/' || !s[1]) break; | |
35 if (s[1] == '.' && (s[2] == '/' || !s[2])) break; | |
36 } | |
37 while (*s && *s != '/') s++; | |
38 } | |
39 if (!*s && s != PWD) s = PWD; | |
40 else s = NULL; | |
41 | |
42 // If current directory exists, make sure it matches. | |
43 if (s && pwd) | |
44 if (stat(pwd, &st1) || stat(PWD, &st2) || st1.st_ino != st2.st_ino || | |
45 st1.st_dev != st2.st_dev) s = NULL; | |
46 } else s = NULL; | |
47 | |
48 // If -L didn't give us a valid path, use cwd. | |
49 if (!s && !(s = pwd)) perror_exit("xgetcwd"); | |
50 | |
51 xprintf("%s\n", s); | |
52 | |
35 if (CFG_TOYBOX_FREE) free(pwd); | 53 if (CFG_TOYBOX_FREE) free(pwd); |
36 } | 54 } |