diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-10-16 05:16:50 +0200 | 
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-10-16 05:16:50 +0200 | 
| commit | 4c77ad75b11caa824a82eb8a88e91d71c51cdd43 (patch) | |
| tree | ced5adb21a97c0e5647090f3e12282b0e64322be | |
| parent | ecccbac37b733a57099c73bc806ac5de64643a35 (diff) | |
| download | 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>
| -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 739b835b5..9455975e7 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();  | 
