sh.dir.c (tcsh-6.22.02) | : | sh.dir.c (tcsh-6.22.03) | ||
---|---|---|---|---|
skipping to change at line 51 | skipping to change at line 51 | |||
static struct directory *dfind (Char *); | static struct directory *dfind (Char *); | |||
static Char *dfollow (Char *, int); | static Char *dfollow (Char *, int); | |||
static void printdirs (int); | static void printdirs (int); | |||
static Char *dgoto (Char *); | static Char *dgoto (Char *); | |||
static void dnewcwd (struct directory *, int); | static void dnewcwd (struct directory *, int); | |||
static void dset (Char *); | static void dset (Char *); | |||
static void dextract (struct directory *); | static void dextract (struct directory *); | |||
static int skipargs (Char ***, const char *, | static int skipargs (Char ***, const char *, | |||
const char *); | const char *); | |||
static void dgetstack (void); | static void dgetstack (void); | |||
static Char *dcanon_internal(Char *, Char *); | ||||
static struct directory dhead INIT_ZERO_STRUCT; /* "head" of loop */ | static struct directory dhead INIT_ZERO_STRUCT; /* "head" of loop */ | |||
static int printd; /* force name to be printed */ | static int printd; /* force name to be printed */ | |||
int bequiet = 0; /* do not print dir stack -strike */ | int bequiet = 0; /* do not print dir stack -strike */ | |||
static Char * | static Char * | |||
agetcwd(void) | agetcwd(void) | |||
{ | { | |||
char *buf; | char *buf; | |||
skipping to change at line 151 | skipping to change at line 152 | |||
* use PWD if we have it (for subshells) | * use PWD if we have it (for subshells) | |||
*/ | */ | |||
if (swd_ok && (cwd = getenv("PWD")) != NULL) { | if (swd_ok && (cwd = getenv("PWD")) != NULL) { | |||
if (stat(cwd, &shp) != -1 && | if (stat(cwd, &shp) != -1 && | |||
DEV_DEV_COMPARE(swd.st_dev, shp.st_dev) && | DEV_DEV_COMPARE(swd.st_dev, shp.st_dev) && | |||
swd.st_ino == shp.st_ino) { | swd.st_ino == shp.st_ino) { | |||
tcp = SAVE(cwd); | tcp = SAVE(cwd); | |||
cleanup_push(tcp, xfree); | cleanup_push(tcp, xfree); | |||
} | } | |||
} | } | |||
cleanup_push(tcp, xfree); | ||||
cp = dcanon(tcp, STRNULL); | cp = dcanon(tcp, STRNULL); | |||
cleanup_ignore(tcp); | ||||
cleanup_until(tcp); | ||||
} | } | |||
#else /* S_IFLNK */ | #else /* S_IFLNK */ | |||
cleanup_push(tcp, xfree); | ||||
cp = dcanon(tcp, STRNULL); | cp = dcanon(tcp, STRNULL); | |||
cleanup_ignore(tcp); | ||||
cleanup_until(tcp); | ||||
#endif /* S_IFLNK */ | #endif /* S_IFLNK */ | |||
} | } | |||
dp = xcalloc(sizeof(struct directory), 1); | dp = xcalloc(sizeof(struct directory), 1); | |||
dp->di_name = cp; | dp->di_name = cp; | |||
dp->di_count = 0; | dp->di_count = 0; | |||
dhead.di_next = dhead.di_prev = dp; | dhead.di_next = dhead.di_prev = dp; | |||
dp->di_next = dp->di_prev = &dhead; | dp->di_next = dp->di_prev = &dhead; | |||
printd = 0; | printd = 0; | |||
dnewcwd(dp, 0); | dnewcwd(dp, 0); | |||
skipping to change at line 316 | skipping to change at line 311 | |||
} | } | |||
void | void | |||
dtilde(void) | dtilde(void) | |||
{ | { | |||
struct directory *d = dcwd; | struct directory *d = dcwd; | |||
do { | do { | |||
if (d == &dhead) | if (d == &dhead) | |||
continue; | continue; | |||
d->di_name = dcanon(d->di_name, STRNULL); | d->di_name = dcanon_internal(d->di_name, STRNULL); | |||
} while ((d = d->di_prev) != dcwd); | } while ((d = d->di_prev) != dcwd); | |||
dset(dcwd->di_name); | dset(dcwd->di_name); | |||
} | } | |||
/* dnormalize(): | /* dnormalize(): | |||
* The path will be normalized if it | * The path will be normalized if it | |||
* 1) is "..", | * 1) is "..", | |||
* 2) or starts with "../", | * 2) or starts with "../", | |||
* 3) or ends with "/..", | * 3) or ends with "/..", | |||
skipping to change at line 572 | skipping to change at line 567 | |||
} | } | |||
else | else | |||
dp = cp; | dp = cp; | |||
#if defined(WINNT_NATIVE) | #if defined(WINNT_NATIVE) | |||
return agetcwd(); | return agetcwd(); | |||
#elif defined(__CYGWIN__) | #elif defined(__CYGWIN__) | |||
if (ABSOLUTEP(cp) && cp[1] == ':') { /* Only DOS paths are treated that way */ | if (ABSOLUTEP(cp) && cp[1] == ':') { /* Only DOS paths are treated that way */ | |||
return agetcwd(); | return agetcwd(); | |||
} else { | } else { | |||
cleanup_push(cp, xfree); | ||||
ret = dcanon(cp, dp); | ret = dcanon(cp, dp); | |||
cleanup_ignore(cp); | ||||
cleanup_until(cp); | ||||
} | } | |||
#else /* !WINNT_NATIVE */ | #else /* !WINNT_NATIVE */ | |||
cleanup_push(cp, xfree); | ||||
ret = dcanon(cp, dp); | ret = dcanon(cp, dp); | |||
cleanup_ignore(cp); | ||||
cleanup_until(cp); | ||||
#endif /* WINNT_NATIVE */ | #endif /* WINNT_NATIVE */ | |||
return ret; | return ret; | |||
} | } | |||
/* | /* | |||
* dfollow - change to arg directory; fall back on cdpath if not valid | * dfollow - change to arg directory; fall back on cdpath if not valid | |||
*/ | */ | |||
static Char * | static Char * | |||
dfollow(Char *cp, int old) | dfollow(Char *cp, int old) | |||
{ | { | |||
skipping to change at line 868 | skipping to change at line 857 | |||
if (dp->di_count != 0) { | if (dp->di_count != 0) { | |||
dp->di_next = dp->di_prev = 0; | dp->di_next = dp->di_prev = 0; | |||
} | } | |||
else { | else { | |||
xfree(dp->di_name); | xfree(dp->di_name); | |||
xfree(dp); | xfree(dp); | |||
} | } | |||
} | } | |||
/* | /* | |||
* dcanon - canonicalize the pathname, removing excess ./ and ../ etc. | * dcanon - a safe version of dcanon_internal that arranges for cleanup | |||
*/ | ||||
Char * | ||||
dcanon(Char *cp, Char *p) | ||||
{ | ||||
cleanup_push(cp, xfree); | ||||
p = dcanon_internal(cp, p); | ||||
// coverity[use_after_free] we use the pointer as a marker | ||||
cleanup_ignore(cp); | ||||
cleanup_until(cp); | ||||
return p; | ||||
} | ||||
/* | ||||
* dcanon_internal - canonicalize the pathname, removing excess ./ and ../ etc. | ||||
* we are of course assuming that the file system is standardly | * we are of course assuming that the file system is standardly | |||
* constructed (always have ..'s, directories have links) | * constructed (always have ..'s, directories have links) | |||
*/ | */ | |||
Char * | static Char * | |||
dcanon(Char *cp, Char *p) | dcanon_internal(Char *cp, Char *p) | |||
{ | { | |||
Char *sp; | Char *sp; | |||
Char *p1, *p2; /* general purpose */ | Char *p1, *p2; /* general purpose */ | |||
int slash; | int slash; | |||
#ifdef HAVE_SLASHSLASH | #ifdef HAVE_SLASHSLASH | |||
int slashslash; | int slashslash; | |||
#endif /* HAVE_SLASHSLASH */ | #endif /* HAVE_SLASHSLASH */ | |||
size_t clen; | size_t clen; | |||
#ifdef S_IFLNK /* if we have symlinks */ | #ifdef S_IFLNK /* if we have symlinks */ | |||
skipping to change at line 1355 | skipping to change at line 1358 | |||
/* | /* | |||
* create a file called ~/.cshdirs which has a sequence | * create a file called ~/.cshdirs which has a sequence | |||
* of pushd commands which will restore the dir stack to | * of pushd commands which will restore the dir stack to | |||
* its state before exit/logout. remember that the order | * its state before exit/logout. remember that the order | |||
* is reversed in the file because we are pushing. | * is reversed in the file because we are pushing. | |||
* -strike | * -strike | |||
*/ | */ | |||
void | void | |||
recdirs(Char *fname, int def) | recdirs(Char *fname, int def) | |||
{ | { | |||
int fp, ftmp, oldidfds; | int fp, ftmp, oldidfds, ophup_disabled; | |||
int cdflag = 0; | int cdflag = 0; | |||
struct directory *dp; | struct directory *dp; | |||
unsigned int num; | unsigned int num; | |||
Char *snum; | Char *snum; | |||
struct Strbuf qname = Strbuf_INIT; | struct Strbuf qname = Strbuf_INIT; | |||
if (fname == NULL && !def) | if (fname == NULL && !def) | |||
return; | return; | |||
ophup_disabled = phup_disabled; | ||||
phup_disabled = 1; | ||||
if (fname == NULL) { | if (fname == NULL) { | |||
if ((fname = varval(STRdirsfile)) == STRNULL) | if ((fname = varval(STRdirsfile)) == STRNULL) | |||
fname = Strspl(varval(STRhome), &STRtildotdirs[1]); | fname = Strspl(varval(STRhome), &STRtildotdirs[1]); | |||
else | else | |||
fname = Strsave(fname); | fname = Strsave(fname); | |||
} | } | |||
else | else | |||
fname = globone(fname, G_ERROR); | fname = globone(fname, G_ERROR); | |||
cleanup_push(fname, xfree); | cleanup_push(fname, xfree); | |||
if ((fp = xcreat(short2str(fname), 0600)) == -1) { | if ((fp = xcreat(short2str(fname), 0600)) == -1) { | |||
cleanup_until(fname); | cleanup_until(fname); | |||
phup_disabled = ophup_disabled; | ||||
return; | return; | |||
} | } | |||
if ((snum = varval(STRsavedirs)) == STRNULL || snum[0] == '\0') | if ((snum = varval(STRsavedirs)) == STRNULL || snum[0] == '\0') | |||
num = (unsigned int) ~0; | num = (unsigned int) ~0; | |||
else | else | |||
num = (unsigned int) atoi(short2str(snum)); | num = (unsigned int) atoi(short2str(snum)); | |||
oldidfds = didfds; | oldidfds = didfds; | |||
didfds = 0; | didfds = 0; | |||
skipping to change at line 1412 | skipping to change at line 1418 | |||
if (num-- == 0) | if (num-- == 0) | |||
break; | break; | |||
} while ((dp = dp->di_next) != dcwd->di_next); | } while ((dp = dp->di_next) != dcwd->di_next); | |||
xclose(fp); | xclose(fp); | |||
SHOUT = ftmp; | SHOUT = ftmp; | |||
didfds = oldidfds; | didfds = oldidfds; | |||
cleanup_until(fname); | cleanup_until(fname); | |||
phup_disabled = ophup_disabled; | ||||
} | } | |||
End of changes. 16 change blocks. | ||||
17 lines changed or deleted | 24 lines changed or added |