From 3dc6f517f2ee16aeb5fd3ca1c8d41b534851ffb1 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 2 Jul 2001 11:24:39 +0000 Subject: fix IRIX 5.3 specific compilation problems and some error messages (15204) --- Src/compat.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'Src/compat.c') 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) -- cgit 1.4.1