Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/sh Make cd (really) do cd -P, and not just claim that is...
details: https://anonhg.NetBSD.org/src/rev/0d7273e53633
branches: trunk
changeset: 354122:0d7273e53633
user: kre <kre%NetBSD.org@localhost>
date: Sun Jun 04 20:27:14 2017 +0000
description:
Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)
Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)
Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.
Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....
Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).
Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")
Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.
Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
diffstat:
bin/sh/cd.c | 65 ++++++++++++++++++++++++++++++----------------------------
bin/sh/eval.c | 6 ++--
bin/sh/exec.c | 28 +++++++++++++++---------
bin/sh/exec.h | 4 +-
bin/sh/mail.c | 7 +++--
bin/sh/sh.1 | 24 ++++++++++++++-------
6 files changed, 76 insertions(+), 58 deletions(-)
diffs (truncated from 370 to 300 lines):
diff -r 121552776733 -r 0d7273e53633 bin/sh/cd.c
--- a/bin/sh/cd.c Sun Jun 04 19:15:46 2017 +0000
+++ b/bin/sh/cd.c Sun Jun 04 20:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cd.c,v 1.47 2016/12/26 02:27:57 christos Exp $ */
+/* $NetBSD: cd.c,v 1.48 2017/06/04 20:27:14 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95";
#else
-__RCSID("$NetBSD: cd.c,v 1.47 2016/12/26 02:27:57 christos Exp $");
+__RCSID("$NetBSD: cd.c,v 1.48 2017/06/04 20:27:14 kre Exp $");
#endif
#endif /* not lint */
@@ -80,10 +80,11 @@
cdcmd(int argc, char **argv)
{
const char *dest;
- const char *path, *p;
+ const char *path, *cp;
+ char *p;
char *d;
struct stat statb;
- int print = cdprint; /* set -cdprint to enable */
+ int print = cdprint; /* set -o cdprint to enable */
while (nextopt("P") != '\0')
;
@@ -98,46 +99,46 @@
dest = bltinlookup("HOME", 1);
if (dest == NULL)
error("HOME not set");
- } else {
- if (argptr[1]) {
- /* Do 'ksh' style substitution */
- if (!curdir)
- error("PWD not set");
- p = strstr(curdir, dest);
- if (!p)
- error("bad substitution");
- d = stalloc(strlen(curdir) + strlen(argptr[1]) + 1);
- memcpy(d, curdir, p - curdir);
- strcpy(d + (p - curdir), argptr[1]);
- strcat(d, p + strlen(dest));
- dest = d;
- print = 1;
- }
- }
-
- if (dest[0] == '-' && dest[1] == '\0') {
+ } else if (argptr[1]) {
+ /* Do 'ksh' style substitution */
+ if (!curdir)
+ error("PWD not set");
+ p = strstr(curdir, dest);
+ if (!p)
+ error("bad substitution");
+ d = stalloc(strlen(curdir) + strlen(argptr[1]) + 1);
+ memcpy(d, curdir, p - curdir);
+ strcpy(d + (p - curdir), argptr[1]);
+ strcat(d, p + strlen(dest));
+ dest = d;
+ print = 1;
+ } else if (dest[0] == '-' && dest[1] == '\0') {
dest = prevdir ? prevdir : curdir;
print = 1;
}
if (*dest == '\0')
dest = ".";
- p = dest;
- if (*p == '.' && *++p == '.')
- p++;
- if (*p == 0 || *p == '/' || (path = bltinlookup("CDPATH", 1)) == NULL)
+
+ cp = dest;
+ if (*cp == '.' && *++cp == '.')
+ cp++;
+ if (*cp == 0 || *cp == '/' || (path = bltinlookup("CDPATH", 1)) == NULL)
path = nullstr;
- while ((p = padvance(&path, dest)) != NULL) {
+ while ((p = padvance(&path, dest, 0)) != NULL) {
+ stunalloc(p);
if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
+ int dopr = print;
+
if (!print) {
/*
* XXX - rethink
*/
if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
- print = strcmp(p + 2, dest);
+ dopr = strcmp(p + 2, dest);
else
- print = strcmp(p, dest);
+ dopr = strcmp(p, dest);
}
- if (docd(p, print) >= 0)
+ if (docd(p, dopr) >= 0)
return 0;
}
@@ -155,6 +156,7 @@
STATIC int
docd(const char *dest, int print)
{
+#if 0 /* no "cd -L" (ever) so all this is just a waste of time ... */
char *p;
char *q;
char *component;
@@ -195,13 +197,14 @@
break;
}
}
+#endif
INTOFF;
if (chdir(dest) < 0) {
INTON;
return -1;
}
- updatepwd(badstat ? NULL : dest);
+ updatepwd(NULL); /* only do cd -P, no "pretend" -L mode */
INTON;
if (print && iflag == 1 && curdir)
out1fmt("%s\n", curdir);
diff -r 121552776733 -r 0d7273e53633 bin/sh/eval.c
--- a/bin/sh/eval.c Sun Jun 04 19:15:46 2017 +0000
+++ b/bin/sh/eval.c Sun Jun 04 20:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: eval.c,v 1.140 2017/05/13 03:26:03 kre Exp $ */
+/* $NetBSD: eval.c,v 1.141 2017/06/04 20:27:14 kre Exp $ */
/*-
* Copyright (c) 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
#else
-__RCSID("$NetBSD: eval.c,v 1.140 2017/05/13 03:26:03 kre Exp $");
+__RCSID("$NetBSD: eval.c,v 1.141 2017/06/04 20:27:14 kre Exp $");
#endif
#endif /* not lint */
@@ -1300,7 +1300,7 @@
error("%s: is a block device", basename);
return basename;
}
- } else while ((fullname = padvance(&path, basename)) != NULL) {
+ } else while ((fullname = padvance(&path, basename, 1)) != NULL) {
if ((stat(fullname, &statb) == 0)) {
/* weird format is to ease future code... */
if (S_ISDIR(statb.st_mode) || S_ISBLK(statb.st_mode))
diff -r 121552776733 -r 0d7273e53633 bin/sh/exec.c
--- a/bin/sh/exec.c Sun Jun 04 19:15:46 2017 +0000
+++ b/bin/sh/exec.c Sun Jun 04 20:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.47 2017/05/15 19:55:20 kre Exp $ */
+/* $NetBSD: exec.c,v 1.48 2017/06/04 20:27:14 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95";
#else
-__RCSID("$NetBSD: exec.c,v 1.47 2017/05/15 19:55:20 kre Exp $");
+__RCSID("$NetBSD: exec.c,v 1.48 2017/06/04 20:27:14 kre Exp $");
#endif
#endif /* not lint */
@@ -130,7 +130,7 @@
e = errno;
} else {
e = ENOENT;
- while ((cmdname = padvance(&path, argv[0])) != NULL) {
+ while ((cmdname = padvance(&path, argv[0], 1)) != NULL) {
if (--idx < 0 && pathopt == NULL) {
tryexec(cmdname, argv, envp, vforked);
if (errno != ENOENT && errno != ENOTDIR)
@@ -296,7 +296,7 @@
const char *pathopt;
char *
-padvance(const char **path, const char *name)
+padvance(const char **path, const char *name, int magic_percent)
{
const char *p;
char *q;
@@ -305,8 +305,12 @@
if (*path == NULL)
return NULL;
+ if (magic_percent)
+ magic_percent = '%';
+
start = *path;
- for (p = start ; *p && *p != ':' && *p != '%' ; p++);
+ for (p = start ; *p && *p != ':' && *p != magic_percent ; p++)
+ ;
len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
while (stackblocksize() < len)
growstackblock();
@@ -314,13 +318,15 @@
if (p != start) {
memcpy(q, start, p - start);
q += p - start;
- *q++ = '/';
+ if (q[-1] != '/')
+ *q++ = '/';
}
strcpy(q, name);
pathopt = NULL;
- if (*p == '%') {
+ if (*p == magic_percent) {
pathopt = ++p;
- while (*p && *p != ':') p++;
+ while (*p && *p != ':')
+ p++;
}
if (*p == ':')
*path = p + 1;
@@ -441,7 +447,7 @@
idx = cmdp->param.index;
path = pathval();
do {
- name = padvance(&path, cmdp->cmdname);
+ name = padvance(&path, cmdp->cmdname, 1);
stunalloc(name);
} while (--idx >= 0);
if (verbose)
@@ -574,7 +580,7 @@
e = ENOENT;
idx = -1;
loop:
- while ((fullname = padvance(&path, name)) != NULL) {
+ while ((fullname = padvance(&path, name, 1)) != NULL) {
stunalloc(fullname);
idx++;
if (pathopt) {
@@ -1075,7 +1081,7 @@
char *name;
int j = entry.u.index;
do {
- name = padvance(&path, arg);
+ name = padvance(&path, arg, 1);
stunalloc(name);
} while (--j >= 0);
if (!v_flag)
diff -r 121552776733 -r 0d7273e53633 bin/sh/exec.h
--- a/bin/sh/exec.h Sun Jun 04 19:15:46 2017 +0000
+++ b/bin/sh/exec.h Sun Jun 04 20:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.h,v 1.24 2016/05/03 13:47:58 kre Exp $ */
+/* $NetBSD: exec.h,v 1.25 2017/06/04 20:27:14 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -62,7 +62,7 @@
extern const char *pathopt; /* set by padvance */
void shellexec(char **, char **, const char *, int, int) __dead;
-char *padvance(const char **, const char *);
+char *padvance(const char **, const char *, int);
void find_command(char *, struct cmdentry *, int, const char *);
int (*find_builtin(char *))(int, char **);
int (*find_splbltin(char *))(int, char **);
diff -r 121552776733 -r 0d7273e53633 bin/sh/mail.c
--- a/bin/sh/mail.c Sun Jun 04 19:15:46 2017 +0000
+++ b/bin/sh/mail.c Sun Jun 04 20:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mail.c,v 1.16 2003/08/07 09:05:33 agc Exp $ */
+/* $NetBSD: mail.c,v 1.17 2017/06/04 20:27:14 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)mail.c 8.2 (Berkeley) 5/4/95";
#else
-__RCSID("$NetBSD: mail.c,v 1.16 2003/08/07 09:05:33 agc Exp $");
+__RCSID("$NetBSD: mail.c,v 1.17 2017/06/04 20:27:14 kre Exp $");
#endif
#endif /* not lint */
@@ -88,9 +88,10 @@
setstackmark(&smark);
mpath = mpathset() ? mpathval() : mailval();
for (i = 0 ; i < nmboxes ; i++) {
- p = padvance(&mpath, nullstr);
+ p = padvance(&mpath, nullstr, 1);
if (p == NULL)
break;
+ stunalloc(p);
if (*p == '\0')
continue;
for (q = p ; *q ; q++);
Home |
Main Index |
Thread Index |
Old Index