summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Schaefer <barts@users.sourceforge.net>2000-08-04 07:09:12 +0000
committerBart Schaefer <barts@users.sourceforge.net>2000-08-04 07:09:12 +0000
commit22cbf1b2719c99c2f17a34859520dbead03e5799 (patch)
treeab0c326c9a8a69c3acab21f9b880b6d3b59dfce4
parent55b07cb525388bca7c0dbaf057483c493ff0b053 (diff)
downloadzsh-22cbf1b2719c99c2f17a34859520dbead03e5799.tar.gz
zsh-22cbf1b2719c99c2f17a34859520dbead03e5799.zip
15216: Rewrite pathconf() support.
-rw-r--r--ChangeLog6
-rw-r--r--Src/Modules/files.c19
-rw-r--r--Src/Modules/parameter.c32
-rw-r--r--Src/compat.c90
-rw-r--r--Src/system.h9
5 files changed, 103 insertions, 53 deletions
diff --git a/ChangeLog b/ChangeLog
index 8d2f8c573..7e35b2ead 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2000-08-04 Bart Schaefer <schaefer@zsh.org>
+
+ * 12516: Src/compat.c, Src/system.h, Src/Modules/files.c,
+ Src/Modules/parameter.c: Rewrite the pathconf() support using a
+ wrapper function in compat.c to isolate the #ifdefs.
+
2000-08-03 Peter Stephenson <pws@csr.com>
* Andrej: 12501: Src/params.c: getenv etc. become zgetenv etc.
diff --git a/Src/Modules/files.c b/Src/Modules/files.c
index b5e0b5f62..d01a59b03 100644
--- a/Src/Modules/files.c
+++ b/Src/Modules/files.c
@@ -71,9 +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;
-#ifdef HAVE_PATHCONF
- int pathmax = 0;
-#endif
umask(oumask);
if(ops['m']) {
@@ -94,21 +91,11 @@ bin_mkdir(char *nam, char **args, char *ops, int func)
while(ptr > *args + (**args == '/') && *--ptr == '/')
*ptr = 0;
-#ifdef HAVE_PATHCONF
- errno = 0;
- if(((pathmax = pathconf(*args,_PC_PATH_MAX)) == -1) && errno) {
- zwarnnam(nam, "%s: %e", *args, errno);
- err = 1;
- continue;
- }
- else if((ztrlen(*args) > pathmax - 1) && errno != -1) {
-#else
- if(ztrlen(*args) > PATH_MAX - 1) {
-#endif
- zwarnnam(nam, "%s: %e", *args, ENAMETOOLONG);
+ 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 2328eae51..b2b3657c0 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -1397,20 +1397,9 @@ scanpmjobdirs(HashTable ht, ScanFunc func, int flags)
static void
setpmnameddir(Param pm, char *value)
{
-#ifdef HAVE_PATHCONF
- int pathmax = 0;
-
errno = 0;
- pathmax = pathconf(value, _PC_PATH_MAX);
- if ((pathmax == -1) && errno) {
- zwarn("%s: %e", value, errno);
- }
- else if (!value || *value != '/' || ((strlen(value) >= pathmax) &&
- pathmax != -1))
-#else
- if (!value || *value != '/' || strlen(value) >= PATH_MAX)
-#endif
- zwarn("invalid value: %s", value, 0);
+ if (!value || *value != '/' || zpathmax(value) < 0)
+ zwarn((errno ? "%s: %e" : "invalid value: %s"), value, errno);
else
adduserdir(pm->nam, value, 0, 1);
zsfree(value);
@@ -1432,9 +1421,6 @@ setpmnameddirs(Param pm, HashTable ht)
{
int i;
HashNode hn, next, hd;
-#ifdef HAVE_PATHCONF
- int pathmax = 0;
-#endif
if (!ht)
return;
@@ -1457,19 +1443,9 @@ setpmnameddirs(Param pm, HashTable ht)
v.arr = NULL;
v.pm = (Param) hn;
-#ifdef HAVE_PATHCONF
errno = 0;
- if((((pathmax = pathconf(val, _PC_PATH_MAX)) == -1)) && errno)
- zwarn("%s: %e", val, errno);
- else
-#endif
- if (!(val = getstrvalue(&v)) || *val != '/' ||
-#ifdef HAVE_PATHCONF
- ((strlen(val) >= pathmax)) && pathmax != -1)
-#else
- strlen(val) >= PATH_MAX)
-#endif
- zwarn("invalid value: %s", val, 0);
+ if (!(val = getstrvalue(&v)) || *val != '/' || zpathmax(val) < 0)
+ zwarn((errno ? "%s: %e" : "invalid value: %s"), val, errno);
else
adduserdir(hn->nam, val, 0, 1);
}
diff --git a/Src/compat.c b/Src/compat.c
index ca9c57aac..2f6628f33 100644
--- a/Src/compat.c
+++ b/Src/compat.c
@@ -105,20 +105,62 @@ strerror(int errnum)
#endif
+#ifdef HAVE_PATHCONF
+
+/* 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. *
+ * *
+ * This is less useful than may be, as one must reset errno to 0 (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." *
+ * *
+ * This is replaced by a macro from system.h if not HAVE_PATHCONF. */
+
/**/
-char *
+mod_export long
+zpathmax(char *dir)
+{
+ long pathmax;
+ errno = 0;
+ if ((pathmax = pathconf(dir, _PC_PATH_MAX)) >= 0) {
+ if (strlen(dir) < pathmax)
+ return pathmax;
+ else
+ errno = ENAMETOOLONG;
+ }
+ if (errno)
+ return -1;
+ else
+ return 0; /* pathmax should be considered unlimited */
+}
+#endif
+
+
+/**/
+mod_export char *
zgetdir(struct dirsav *d)
{
char nbuf[PATH_MAX+3];
char *buf;
- int bufsiz, pos, len;
+ int bufsiz, pos;
struct stat sbuf;
+ ino_t pino;
+ dev_t pdev;
+#if !defined(__CYGWIN__) && !defined(USE_GETCWD)
struct dirent *de;
DIR *dir;
- ino_t ino, pino;
- dev_t dev, pdev;
+ dev_t dev;
+ ino_t ino;
+ int len;
+#endif
- buf = halloc(bufsiz = PATH_MAX);
+ buf = zhalloc(bufsiz = PATH_MAX);
pos = bufsiz - 1;
buf[pos] = '\0';
strcpy(nbuf, "../");
@@ -137,6 +179,7 @@ zgetdir(struct dirsav *d)
#ifdef HAVE_FCHDIR
else
#endif
+#if !defined(__CYGWIN__) && !defined(USE_GETCWD)
holdintr();
for (;;) {
@@ -196,7 +239,7 @@ zgetdir(struct dirsav *d)
len = strlen(nbuf + 2);
pos -= len;
while (pos <= 1) {
- char *newbuf = halloc(2*bufsiz);
+ char *newbuf = zhalloc(2*bufsiz);
memcpy(newbuf + bufsiz, buf, bufsiz);
buf = newbuf;
pos += bufsiz;
@@ -221,6 +264,21 @@ zgetdir(struct dirsav *d)
if (*buf)
zchdir(buf + pos + 1);
noholdintr();
+
+#else /* __CYGWIN__, USE_GETCWD cases */
+
+ if (!getcwd(buf, bufsiz)) {
+ if (d) {
+ return NULL;
+ }
+ } else {
+ if (d) {
+ return d->dirname = ztrdup(buf);
+ }
+ return buf;
+ }
+#endif
+
buf[0] = '.';
buf[1] = '\0';
return buf;
@@ -237,7 +295,7 @@ zgetcwd(void)
* faliliure and -2 when chdir failed and the current directory is lost. */
/**/
-int
+mod_export int
zchdir(char *dir)
{
char *s;
@@ -283,3 +341,21 @@ zchdir(char *dir)
return currdir == -2 ? -1 : -2;
#endif
}
+
+/*
+ * How to print out a 64 bit integer. This isn't needed (1) if longs
+ * are 64 bit, since ordinary %ld will work (2) if we couldn't find a
+ * 64 bit type anyway.
+ */
+/**/
+#ifdef ZSH_64_BIT_TYPE
+/**/
+mod_export char *
+output64(zlong val)
+{
+ static char llbuf[DIGBUFSIZE];
+ convbase(llbuf, val, 0);
+ return llbuf;
+}
+/**/
+#endif /* ZSH_64_BIT_TYPE */
diff --git a/Src/system.h b/Src/system.h
index cba80a5f6..ba83e005e 100644
--- a/Src/system.h
+++ b/Src/system.h
@@ -194,8 +194,8 @@ struct timezone {
# define VARARR(X,Y,Z) X *(Y) = (X *) alloca(sizeof(X) * (Z))
#endif
-/* we should be getting this value from pathconf(_PC_PATH_MAX) */
-/* but this is too much trouble */
+/* we should handle unlimited sizes from pathconf(_PC_PATH_MAX) */
+/* but this is too much trouble */
#ifndef PATH_MAX
# ifdef MAXPATHLEN
# define PATH_MAX MAXPATHLEN
@@ -204,6 +204,11 @@ struct timezone {
# define PATH_MAX 1024
# 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 */