mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-01 21:51:40 +02:00
12547: Handle ENOENT and ENOTDIR in zpathmax().
This commit is contained in:
parent
45ffc3b6c8
commit
1ff8518b16
4 changed files with 42 additions and 32 deletions
|
@ -1,3 +1,9 @@
|
|||
2000-08-04 Bart Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 12547: configure.in, Src/compat.c, Src/Modules/files.c:
|
||||
Handle ENOENT and ENOTDIR within zpathmax(), and therefore back
|
||||
out the changes from 12541 and 12533.
|
||||
|
||||
2000-08-04 Clint Adams <schizo@debian.org>
|
||||
|
||||
* 12541: configure.in, Src/compat.c: zrealpath wrapper around
|
||||
|
|
|
@ -71,7 +71,6 @@ bin_mkdir(char *nam, char **args, char *ops, int func)
|
|||
mode_t oumask = umask(0);
|
||||
mode_t mode = 0777 & ~oumask;
|
||||
int err = 0;
|
||||
char *head;
|
||||
|
||||
umask(oumask);
|
||||
if(ops['m']) {
|
||||
|
@ -92,19 +91,8 @@ bin_mkdir(char *nam, char **args, char *ops, int func)
|
|||
|
||||
while(ptr > *args + (**args == '/') && *--ptr == '/')
|
||||
*ptr = 0;
|
||||
|
||||
/* Drop the tail so that pathconf receives a potentially valid pathname */
|
||||
head = (char *) ztrdup(*args);
|
||||
if ((ptr = strrchr(head, '/')))
|
||||
*ptr = 0;
|
||||
else {
|
||||
/* Relative to current directory */
|
||||
*head = '.';
|
||||
*(head + 1) = '\0';
|
||||
}
|
||||
|
||||
if(zpathmax(unmeta(head)) < 0) {
|
||||
zwarnnam(nam, "%s: %e", head, errno);
|
||||
if(zpathmax(unmeta(*args)) < 0) {
|
||||
zwarnnam(nam, "%s: %e", *args, errno);
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -133,8 +121,6 @@ bin_mkdir(char *nam, char **args, char *ops, int func)
|
|||
}
|
||||
} else
|
||||
err |= domkdir(nam, *args, mode, 0);
|
||||
|
||||
free(head);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
|
48
Src/compat.c
48
Src/compat.c
|
@ -118,21 +118,52 @@ strerror(int errnum)
|
|||
* some other flag value) in order to determine that the resource is *
|
||||
* unlimited. What use is leaving errno unchanged? Instead, define *
|
||||
* a wrapper that resets errno to 0 and returns 0 for "the system *
|
||||
* does not have a limit." *
|
||||
* does not have a limit," so that -1 always means a real error. *
|
||||
* *
|
||||
* This is replaced by a macro from system.h if not HAVE_PATHCONF. */
|
||||
* This is replaced by a macro from system.h if not HAVE_PATHCONF. *
|
||||
*
|
||||
* Note that the length of a relative path is compared without first *
|
||||
* prepending the current directory, if pathconf() does not return *
|
||||
* an error. This is for consistency with the macro and with older *
|
||||
* zsh behavior; it may be problematic in the ENOENT/ENOTDIR cases. */
|
||||
|
||||
/**/
|
||||
mod_export long
|
||||
zpathmax(char *dir)
|
||||
{
|
||||
long pathmax;
|
||||
|
||||
if (!dir || !*dir)
|
||||
dir = ".";
|
||||
errno = 0;
|
||||
if ((pathmax = pathconf(dir, _PC_PATH_MAX)) >= 0) {
|
||||
/* This code is redundant if pathconf works correctly, but *
|
||||
* some versions of glibc pathconf return a hardwired value. */
|
||||
if (strlen(dir) < pathmax)
|
||||
return pathmax;
|
||||
else
|
||||
errno = ENAMETOOLONG;
|
||||
} else if (errno == ENOENT || errno == ENOTDIR) {
|
||||
/* Work backward to find a directory, until we run out of path. */
|
||||
char *tail = strrchr(dir, '/');
|
||||
while (tail > dir && tail[-1] == '/')
|
||||
--tail;
|
||||
if (tail > dir) {
|
||||
*tail = 0;
|
||||
pathmax = zpathmax(dir);
|
||||
*tail = '/';
|
||||
if (pathmax > 0) {
|
||||
if (strlen(dir) < pathmax)
|
||||
return pathmax;
|
||||
else
|
||||
errno = ENAMETOOLONG;
|
||||
}
|
||||
}
|
||||
/* else *
|
||||
* Either we're at the root (tail == dir) or we're on the first *
|
||||
* component of a relative path (tail == NULL). Either way we *
|
||||
* have nothing to do here, the error from pathconf() is real. *
|
||||
* Perhaps our current working directory has been removed? */
|
||||
}
|
||||
if (errno)
|
||||
return -1;
|
||||
|
@ -141,19 +172,6 @@ zpathmax(char *dir)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**/
|
||||
mod_export char *
|
||||
zrealpath(const char *path, char *resolved_path)
|
||||
{
|
||||
#ifdef HAVE_REALPATH
|
||||
return realpath(path, resolved_path);
|
||||
#else /* the following block should be replaced with a realpath() equiv. */
|
||||
long pathmax;
|
||||
|
||||
if ((pathmax = zpathmax(path)) > 0)
|
||||
return strncpy(resolved_path, path, pathmax);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**/
|
||||
mod_export char *
|
||||
|
|
|
@ -864,7 +864,7 @@ AC_CHECK_FUNCS(strftime difftime gettimeofday \
|
|||
signgam \
|
||||
putenv getenv \
|
||||
brk sbrk \
|
||||
pathconf realpath)
|
||||
pathconf)
|
||||
AC_FUNC_STRCOLL
|
||||
|
||||
if test $ac_cv_func_setpgrp = yes; then
|
||||
|
|
Loading…
Reference in a new issue