Commit 1ff8518b authored by Bart Schaefer's avatar Bart Schaefer

12547: Handle ENOENT and ENOTDIR in zpathmax().

parent 45ffc3b6
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;
}
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment