changeset 3345:fdd65e9ab37b

(<errno.h>): Include. (errno): Declare if not defined. (addext): Work correctly when pathconf returns -1 and leaves errno alone because there is no limit. Also, work even if pathconf returns a value greater than SIZE_MAX.
author Jim Meyering <jim@meyering.net>
date Mon, 13 Aug 2001 06:30:10 +0000
parents 6cf36abcf4e5
children b3660313d1e9
files lib/addext.c
diffstat 1 files changed, 24 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/lib/addext.c
+++ b/lib/addext.c
@@ -47,6 +47,11 @@
 # include <unistd.h>
 #endif
 
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
 #include "backupfile.h"
 #include "dirname.h"
 
@@ -57,26 +62,30 @@
 addext (char *filename, char const *ext, int e)
 {
   char *s = base_name (filename);
-  size_t slen = base_len (s), extlen = strlen (ext);
-  long slen_max = -1;
+  size_t slen = base_len (s);
+  size_t extlen = strlen (ext);
+  size_t slen_max = HAVE_LONG_FILE_NAMES ? 255 : _POSIX_NAME_MAX;
 
 #if HAVE_PATHCONF && defined _PC_NAME_MAX
-  if (slen + extlen <= _POSIX_NAME_MAX && ! HAVE_DOS_FILE_NAMES)
-    /* The file name is so short there's no need to call pathconf.  */
-    slen_max = _POSIX_NAME_MAX;
-  else if (s == filename)
-    slen_max = pathconf (".", _PC_NAME_MAX);
-  else
+  if (_POSIX_NAME_MAX < slen + extlen || HAVE_DOS_FILE_NAMES)
     {
-      char c = *s;
-      if (! ISSLASH (c))
-	*s = 0;
-      slen_max = pathconf (filename, _PC_NAME_MAX);
-      *s = c;
+      /* The new base name is long enough to require a pathconf check.  */
+      long name_max;
+      errno = 0;
+      if (s == filename)
+	name_max = pathconf (".", _PC_NAME_MAX);
+      else
+	{
+	  char c = *s;
+	  if (! ISSLASH (c))
+	    *s = 0;
+	  name_max = pathconf (filename, _PC_NAME_MAX);
+	  *s = c;
+	}
+      if (0 <= name_max || errno == 0)
+	slen_max = name_max == (size_t) name_max ? name_max : -1;
     }
 #endif
-  if (slen_max < 0)
-    slen_max = HAVE_LONG_FILE_NAMES ? 255 : 14;
 
   if (HAVE_DOS_FILE_NAMES && slen_max <= 12)
     {