diff options
author | Denys Vlasenko | 2011-10-16 05:16:50 +0200 |
---|---|---|
committer | Denys Vlasenko | 2011-10-16 05:16:50 +0200 |
commit | 4c77ad75b11caa824a82eb8a88e91d71c51cdd43 (patch) | |
tree | ced5adb21a97c0e5647090f3e12282b0e64322be /coreutils | |
parent | ecccbac37b733a57099c73bc806ac5de64643a35 (diff) | |
download | busybox-4c77ad75b11caa824a82eb8a88e91d71c51cdd43.zip busybox-4c77ad75b11caa824a82eb8a88e91d71c51cdd43.tar.gz |
pwd: implement -LP if DESKTOP
function old new delta
pwd_main 41 244 +203
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/pwd.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/coreutils/pwd.c b/coreutils/pwd.c index 739b835..9455975 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c @@ -20,13 +20,63 @@ /* This is a NOFORK applet. Be very careful! */ +static int logical_getcwd(void) +{ + struct stat st1; + struct stat st2; + char *wd; + char *p; + + wd = getenv("PWD"); + if (!wd || wd[0] != '/') + return 0; + + p = wd; + while (*p) { + /* doing strstr(p, "/.") by hand is smaller and faster... */ + if (*p++ != '/') + continue; + if (*p != '.') + continue; + /* we found "/.", skip to next char */ + p++; + if (*p == '.') + p++; /* we found "/.." */ + if (*p == '\0' || *p == '/') + return 0; /* "/./" or "/../" component: bad */ + } + + if (stat(wd, &st1) != 0) + return 0; + if (stat(".", &st2) != 0) + return 0; + if (st1.st_ino != st2.st_ino) + return 0; + if (st1.st_dev != st2.st_dev) + return 0; + + puts(wd); + return 1; +} + int pwd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int pwd_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { char *buf; + if (ENABLE_DESKTOP) { + /* TODO: assume -L if $POSIXLY_CORRECT? (coreutils does that) + * Rationale: + * POSIX requires a default of -L, but most scripts expect -P + */ + unsigned opt = getopt32(argv, "LP"); + if ((opt & 1) && logical_getcwd()) + return fflush_all(); + } + buf = xrealloc_getcwd_or_warn(NULL); - if (buf != NULL) { + + if (buf) { puts(buf); free(buf); return fflush_all(); |