zsh-workers
 help / color / mirror / code / Atom feed
* Re: PATCH: pathconf() again
@ 2000-08-04  7:06 Sven Wischnowsky
  0 siblings, 0 replies; 6+ messages in thread
From: Sven Wischnowsky @ 2000-08-04  7:06 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> ...
> 
> I restrained myself (and was badly bruised in the process) from inserting
> spaces before the left-parens in all the if() for() while() statements in
> the files module.  I'm tempted to add something to zsh-development-guide
> about this, too, but at the moment it'd sound much too ascerbic.

It's already there:

* Do not use space between the function name and the opening parenthesis.
  Use space after if/for/while.  Use space after type casts.


Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: pathconf() again
  2000-08-04  7:02 Bart Schaefer
  2000-08-04 13:19 ` Clint Adams
@ 2000-08-05  6:45 ` Wayne Davison
  1 sibling, 0 replies; 6+ messages in thread
From: Wayne Davison @ 2000-08-05  6:45 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

On Fri, 4 Aug 2000, Bart Schaefer wrote:
> There's a macro version of zpathmax() in system.h for not-HAVE_PATHCONF.

...which is missing a closing paren.  I assume that it should have the
paren added at the end of the macro, but I'll let you double-check that
and check in a fix.  I made that change locally, and was able to compile
a working zsh.

..wayne..


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: pathconf() again
  2000-08-04 18:15   ` Bart Schaefer
@ 2000-08-05  0:52     ` Clint Adams
  0 siblings, 0 replies; 6+ messages in thread
From: Clint Adams @ 2000-08-05  0:52 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

> But ... readlink() doesn't have any provision to "read more of the link"
> and doesn't tell you if it truncated what it did read.

I didn't realize that readlink() was so unfriendly.  You could
memset() the buffer with 0 and then test to see if the final octet
of the buffer was still zero.  If it is, you have a complete,
zero-terminated string.  If not, realloc the buffer and try again.

I don't know if that's more or less ugly.

> Only if it's a relative rather than absolute link.

I don't understand the significance.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: pathconf() again
  2000-08-04 13:19 ` Clint Adams
@ 2000-08-04 18:15   ` Bart Schaefer
  2000-08-05  0:52     ` Clint Adams
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2000-08-04 18:15 UTC (permalink / raw)
  To: Clint Adams; +Cc: zsh-workers

On Aug 4,  9:19am, Clint Adams wrote:
> Subject: Re: PATCH: pathconf() again
> > Random questions:  Can someone explain how one is supposed to determine a
> > useful buffer size for e.g. readlink() if pathconf() returns `unlimited'?
> 
> What I was told is that one should malloc an arbitrary amount, say 512
> bytes, then realloc to double the buffer size if it's too small.  Rinse
> and repeat.

But ... readlink() doesn't have any provision to "read more of the link"
and doesn't tell you if it truncated what it did read.

In that specific instance, I suppose you could allocate space based on
the st_size returned by lstat(), but the general solution feels sloppy
at best.

> > For that matter, how does one even know what directory name to pass into
> > pathconf() in that case?
> 
> I assume you want the PATH_MAX of the filesystem where the link lives,
> and not the psychically-determined filesystem to which it's pointing.

Only if it's a relative rather than absolute link.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: pathconf() again
  2000-08-04  7:02 Bart Schaefer
@ 2000-08-04 13:19 ` Clint Adams
  2000-08-04 18:15   ` Bart Schaefer
  2000-08-05  6:45 ` Wayne Davison
  1 sibling, 1 reply; 6+ messages in thread
From: Clint Adams @ 2000-08-04 13:19 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

> Random questions:  Can someone explain how one is supposed to determine a
> useful buffer size for e.g. readlink() if pathconf() returns `unlimited'?

What I was told is that one should malloc an arbitrary amount, say 512
bytes, then realloc to double the buffer size if it's too small.  Rinse
and repeat.

> For that matter, how does one even know what directory name to pass into
> pathconf() in that case?

I assume you want the PATH_MAX of the filesystem where the link lives,
and not the psychically-determined filesystem to which it's pointing.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* PATCH: pathconf() again
@ 2000-08-04  7:02 Bart Schaefer
  2000-08-04 13:19 ` Clint Adams
  2000-08-05  6:45 ` Wayne Davison
  0 siblings, 2 replies; 6+ messages in thread
From: Bart Schaefer @ 2000-08-04  7:02 UTC (permalink / raw)
  To: zsh-workers

There was a problem with the string passed to pathconf() from the files
module:  It might contain metacharacters, and thus be an invalid path.

Consequently, I rewrote the entire HAVE_PATHCONF patch from scratch, with
the exception of the innocuous configure.in bit.

This patch introduces a new function in compat.c, zpathmax(dir), which
returns -1 if the dir is too long (or otherwise invalid), or returns the
max path length otherwise.  It returns 0 (and sets errno = 0) if path
lengths are unlimited (see the comment), but this isn't used yet.  I'm
not sure the (strlen(dir) < pathmax) test can ever fail, but in case
the limit is for some bizarre reason set to zero ...

There's a macro version of zpathmax() in system.h for not-HAVE_PATHCONF.

I'm not sure how pathconf() treats a path that's exactly PATH_MAX long,
but I decided that since the argument is a directory name it's pretty
silly to create one to which no '/' can be appended; hence zpathmax()
gives ENAMETOOLONG in that case.

I then tore out all the #ifdef HAVE_PATHCONF and put in zpathmax() calls.
I'm tempted to add something to Etc/zsh-development-guide about isolating
#ifdefs in this way whenever possible.

I restrained myself (and was badly bruised in the process) from inserting
spaces before the left-parens in all the if() for() while() statements in
the files module.  I'm tempted to add something to zsh-development-guide
about this, too, but at the moment it'd sound much too ascerbic.

Random questions:  Can someone explain how one is supposed to determine a
useful buffer size for e.g. readlink() if pathconf() returns `unlimited'?
For that matter, how does one even know what directory name to pass into
pathconf() in that case?

Index: Src/compat.c
===================================================================
RCS file: /extra/cvsroot/zsh/zsh-3.1/Src/compat.c,v
retrieving revision 1.2
diff -u -r1.2 compat.c
--- compat.c	1999/12/02 17:16:06	1.2
+++ compat.c	2000/08/04 06:53:48
@@ -105,6 +105,43 @@
 #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.   */
+
+/**/
+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)
Index: Src/system.h
===================================================================
RCS file: /extra/cvsroot/zsh/zsh-3.1/Src/system.h,v
retrieving revision 1.7
diff -u -r1.7 system.h
--- system.h	2000/05/18 17:19:38	1.7
+++ system.h	2000/08/04 06:49:07
@@ -194,8 +194,8 @@
 # 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
@@ -203,6 +203,11 @@
    /* so we will just pick something */
 #  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) */
Index: Src/Modules/files.c
===================================================================
RCS file: /extra/cvsroot/zsh/zsh-3.1/Src/Modules/files.c,v
retrieving revision 1.9
diff -u -r1.9 files.c
--- files.c	2000/08/03 04:51:42	1.9
+++ files.c	2000/08/04 06:12:00
@@ -71,9 +71,6 @@
     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 @@
 
 	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;
 
Index: Src/Modules/parameter.c
===================================================================
RCS file: /extra/cvsroot/zsh/zsh-3.1/Src/Modules/parameter.c,v
retrieving revision 1.46
diff -u -r1.46 parameter.c
--- parameter.c	2000/08/03 14:49:44	1.46
+++ parameter.c	2000/08/04 06:03:22
@@ -1397,20 +1397,9 @@
 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 @@
 {
     int i;
     HashNode hn, next, hd;
-#ifdef HAVE_PATHCONF
-    int pathmax = 0;
-#endif
 
     if (!ht)
 	return;
@@ -1457,19 +1443,9 @@
 	    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);
 	}

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2000-08-05  6:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-08-04  7:06 PATCH: pathconf() again Sven Wischnowsky
  -- strict thread matches above, loose matches on Subject: below --
2000-08-04  7:02 Bart Schaefer
2000-08-04 13:19 ` Clint Adams
2000-08-04 18:15   ` Bart Schaefer
2000-08-05  0:52     ` Clint Adams
2000-08-05  6:45 ` Wayne Davison

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).