about summary refs log tree commit diff
path: root/Src/compat.c
diff options
context:
space:
mode:
authorOliver Kiddle <opk@users.sourceforge.net>2001-07-02 11:24:39 +0000
committerOliver Kiddle <opk@users.sourceforge.net>2001-07-02 11:24:39 +0000
commit3dc6f517f2ee16aeb5fd3ca1c8d41b534851ffb1 (patch)
tree7f04f1c9d85cea9cbca29288e3b7271c946d857e /Src/compat.c
parenta591ac043b2a5d8c76fe04a5e4c8ca08e3e59a2c (diff)
downloadzsh-3dc6f517f2ee16aeb5fd3ca1c8d41b534851ffb1.tar.gz
zsh-3dc6f517f2ee16aeb5fd3ca1c8d41b534851ffb1.tar.xz
zsh-3dc6f517f2ee16aeb5fd3ca1c8d41b534851ffb1.zip
fix IRIX 5.3 specific compilation problems and some error messages (15204)
Diffstat (limited to 'Src/compat.c')
-rw-r--r--Src/compat.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/Src/compat.c b/Src/compat.c
index a7e4069d8..86611a727 100644
--- a/Src/compat.c
+++ b/Src/compat.c
@@ -105,6 +105,108 @@ strerror(int errnum)
 #endif
 
 
+#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    *
+ *     not  have  a  limit  for  the  requested  resource,  -1 is    *
+ *     returned, and errno is unchanged.  If there is  an  error,    *
+ *     -1  is returned, and errno is set to reflect the nature of    *
+ *     the error.                                                    *
+ *                                                                   *
+ * 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.     */
+
+/**/
+mod_export long
+zpathmax(char *dir)
+{
+#ifdef HAVE_PATHCONF
+    long pathmax;
+
+    errno = 0;
+    if ((pathmax = pathconf(dir, _PC_PATH_MAX)) >= 0) {
+	/* 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] == '/')
+	    --tail;
+	if (tail > dir) {
+	    *tail = 0;
+	    pathmax = zpathmax(dir);
+	    *tail = '/';
+	} else {
+	    errno = 0;
+	    if (tail)
+		pathmax = pathconf("/", _PC_PATH_MAX);
+	    else
+		pathmax = pathconf(".", _PC_PATH_MAX);
+	}
+	if (pathmax > 0) {
+	    long taillen = (tail ? strlen(tail) : (strlen(dir) + 1));
+	    if (taillen < pathmax)
+		return pathmax - taillen;
+	    else
+		errno = ENAMETOOLONG;
+	}
+    }
+    if (errno)
+	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_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     *
+ * than return 0 or -1 just in case.                                 */
+
+/**/
+mod_export long
+zopenmax(void)
+{
+    long openmax = sysconf(_SC_OPEN_MAX);
+
+    if (openmax < 1)
+	return OPEN_MAX;
+    else
+	return openmax;
+}
+#endif
+
 /**/
 mod_export char *
 zgetdir(struct dirsav *d)