summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Src/Modules/files.c5
-rw-r--r--Src/Modules/parameter.c10
-rw-r--r--Src/compat.c66
-rw-r--r--Src/system.h17
5 files changed, 56 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index 435aaa21c..7dc510610 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2000-08-13 Bart Schaefer <schaefer@zsh.org>
+ * 12604: Src/compat.c, Src/system.h, Src/Modules/files.c,
+ Src/Modules/parameter.c: Remove calls to zpathmax(); fix some
+ serious errors in zpathmax() but wrap it in #if 0 anyway; minor
+ fixes to comments and coding style for zopenmax().
+
* 12601: aczsh.m4, configure.in: configure --enable-cflags and the
like, i.e., with no =... part, should preserve the environment
values for CFLAGS etc. rather than erase them.
diff --git a/Src/Modules/files.c b/Src/Modules/files.c
index d01a59b03..54b399866 100644
--- a/Src/Modules/files.c
+++ b/Src/Modules/files.c
@@ -91,11 +91,6 @@ bin_mkdir(char *nam, char **args, char *ops, int func)
while(ptr > *args + (**args == '/') && *--ptr == '/')
*ptr = 0;
- if(zpathmax(unmeta(*args)) < 0) {
- zwarnnam(nam, "%s: %e", *args, errno);
- err = 1;
- continue;
- }
if(ops['p']) {
char *ptr = *args;
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index b2b3657c0..e8a0c09a0 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -1397,9 +1397,8 @@ scanpmjobdirs(HashTable ht, ScanFunc func, int flags)
static void
setpmnameddir(Param pm, char *value)
{
- errno = 0;
- if (!value || *value != '/' || zpathmax(value) < 0)
- zwarn((errno ? "%s: %e" : "invalid value: %s"), value, errno);
+ if (!value || *value != '/')
+ zwarn("invalid value: %s", value, 0);
else
adduserdir(pm->nam, value, 0, 1);
zsfree(value);
@@ -1443,9 +1442,8 @@ setpmnameddirs(Param pm, HashTable ht)
v.arr = NULL;
v.pm = (Param) hn;
- errno = 0;
- if (!(val = getstrvalue(&v)) || *val != '/' || zpathmax(val) < 0)
- zwarn((errno ? "%s: %e" : "invalid value: %s"), val, errno);
+ if (!(val = getstrvalue(&v)) || *val != '/')
+ zwarn("invalid value: %s", val, 0);
else
adduserdir(hn->nam, val, 0, 1);
}
diff --git a/Src/compat.c b/Src/compat.c
index 88ceac2c8..8cfb8a3a5 100644
--- a/Src/compat.c
+++ b/Src/compat.c
@@ -105,7 +105,23 @@ strerror(int errnum)
#endif
-#ifdef HAVE_PATHCONF
+#if 0
+/* pathconf(_PC_PATH_MAX) is not currently useful to zsh. The value *
+ * returned varies depending on a number of factors, e.g. the amount *
+ * of memory available to the operating system at a given time; thus *
+ * it can't be used for buffer allocation, or even as an indication *
+ * of whether an attempt to use or create a given pathname may fail *
+ * at any future time. *
+ * *
+ * The call is also permitted to fail if the argument path is not an *
+ * existing directory, so even to make sense of that one must search *
+ * for a valid directory somewhere in the path and adjust. Even if *
+ * it succeeds, the return value is relative to the input directory, *
+ * and therefore potentially relative to the length of the shortest *
+ * path either to that directory or to our working directory. *
+ * *
+ * Finally, see the note below for glibc; detection of pathconf() is *
+ * not by itself an indication that it works reliably. */
/* The documentation for pathconf() says something like: *
* The limit is returned, if one exists. If the system does *
@@ -114,34 +130,24 @@ strerror(int errnum)
* -1 is returned, and errno is set to reflect the nature of *
* the error. *
* *
- * This is less useful than may be, as one must reset errno to 0 (or *
+ * System calls are not permitted to set errno to 0; but we must (or *
* 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," so that -1 always means a real error. *
- * *
- * 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. */
+ * does not have a limit," so that -1 always means a real error. */
/**/
mod_export long
zpathmax(char *dir)
{
+#ifdef HAVE_PATHCONF
long pathmax;
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) {
+ /* Some versions of glibc pathconf return a hardwired value! */
+ return pathmax;
+ } else if (errno == EINVAL || 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] == '/')
@@ -158,8 +164,9 @@ zpathmax(char *dir)
pathmax = pathconf(".", _PC_PATH_MAX);
}
if (pathmax > 0) {
- if (strlen(dir) < pathmax)
- return pathmax;
+ long taillen = (tail ? strlen(tail) : (strlen(dir) + 1));
+ if (taillen < pathmax)
+ return pathmax - taillen;
else
errno = ENAMETOOLONG;
}
@@ -168,12 +175,20 @@ zpathmax(char *dir)
return -1;
else
return 0; /* pathmax should be considered unlimited */
-}
+#else
+ long dirlen = strlen(dir);
+
+ /* The following is wrong if dir is not an absolute path. */
+ return ((long) ((dirlen >= PATH_MAX) ?
+ ((errno = ENAMETOOLONG), -1) :
+ ((errno = 0), PATH_MAX - dirlen)));
#endif
+}
+#endif // 0
#ifdef HAVE_SYSCONF
-/* This is replaced by a macro from system.h if not HAVE_PATHCONF. *
- * 0 is returned if _SC_OPEN_MAX is unavailable *
+/* This is replaced by a macro from system.h if not HAVE_SYSCONF. *
+ * 0 is returned by sysconf if _SC_OPEN_MAX is unavailable; *
* -1 is returned on error *
* *
* Neither of these should happen, but resort to OPEN_MAX rather *
@@ -183,10 +198,9 @@ zpathmax(char *dir)
mod_export long
zopenmax(void)
{
- long openmax;
-
- openmax = sysconf(_SC_OPEN_MAX);
- if(openmax < 1)
+ long openmax = sysconf(_SC_OPEN_MAX);
+
+ if (openmax < 1)
return OPEN_MAX;
else
return openmax;
diff --git a/Src/system.h b/Src/system.h
index 2ed75b621..3d23f5761 100644
--- a/Src/system.h
+++ b/Src/system.h
@@ -200,18 +200,15 @@ struct timezone {
# ifdef MAXPATHLEN
# define PATH_MAX MAXPATHLEN
# else
- /* so we will just pick something */
-# define PATH_MAX 1024
+# ifdef _POSIX_PATH_MAX
+# define PATH_MAX _POSIX_PATH_MAX
+# else
+ /* so we will just pick something */
+# define PATH_MAX 1024
+# endif
# endif
#endif
-#ifndef HAVE_PATHCONF
-# define zpathmax(X) ((long)((strlen(X) >= PATH_MAX) ? \
- ((errno = ENAMETOOLONG), -1) : \
- ((errno = 0), PATH_MAX)))
-#endif
-/* we should be getting this value from sysconf(_SC_OPEN_MAX) */
-/* but this is too much trouble */
#ifndef OPEN_MAX
# ifdef NOFILE
# define OPEN_MAX NOFILE
@@ -221,7 +218,7 @@ struct timezone {
# endif
#endif
#ifndef HAVE_SYSCONF
-# define zopenmax() (long) OPEN_MAX
+# define zopenmax() ((long) OPEN_MAX)
#endif
#ifdef HAVE_FCNTL_H