Use Gnulib's `sys_stat' module; update Gnulib.
[bpt/guile.git] / lib / canonicalize-lgpl.c
index a053825..c361a46 100644 (file)
 
 #if !HAVE_CANONICALIZE_FILE_NAME || !FUNC_REALPATH_WORKS || defined _LIBC
 
+/* Don't use __attribute__ __nonnull__ in this compilation unit.  Otherwise gcc
+   optimizes away the name == NULL test below.  */
+#define _GL_ARG_NONNULL(params)
+
 /* Specification.  */
 #include <stdlib.h>
 
@@ -94,9 +98,9 @@ __realpath (const char *name, char *resolved)
   if (name == NULL)
     {
       /* As per Single Unix Specification V2 we must return an error if
-        either parameter is a null pointer.  We extend this to allow
-        the RESOLVED parameter to be NULL in case the we are expected to
-        allocate the room for the return value.  */
+         either parameter is a null pointer.  We extend this to allow
+         the RESOLVED parameter to be NULL in case the we are expected to
+         allocate the room for the return value.  */
       __set_errno (EINVAL);
       return NULL;
     }
@@ -104,7 +108,7 @@ __realpath (const char *name, char *resolved)
   if (name[0] == '\0')
     {
       /* As per Single Unix Specification V2 we must return an error if
-        the name argument points to an empty string.  */
+         the name argument points to an empty string.  */
       __set_errno (ENOENT);
       return NULL;
     }
@@ -121,12 +125,12 @@ __realpath (const char *name, char *resolved)
     {
       rpath = malloc (path_max);
       if (rpath == NULL)
-       {
-         /* It's easier to set errno to ENOMEM than to rely on the
-            'malloc-posix' gnulib module.  */
-         errno = ENOMEM;
-         return NULL;
-       }
+        {
+          /* It's easier to set errno to ENOMEM than to rely on the
+             'malloc-posix' gnulib module.  */
+          errno = ENOMEM;
+          return NULL;
+        }
     }
   else
     rpath = resolved;
@@ -135,10 +139,10 @@ __realpath (const char *name, char *resolved)
   if (name[0] != '/')
     {
       if (!__getcwd (rpath, path_max))
-       {
-         rpath[0] = '\0';
-         goto error;
-       }
+        {
+          rpath[0] = '\0';
+          goto error;
+        }
       dest = strchr (rpath, '\0');
     }
   else
@@ -146,7 +150,7 @@ __realpath (const char *name, char *resolved)
       rpath[0] = '/';
       dest = rpath + 1;
       if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/')
-       *dest++ = '/';
+        *dest++ = '/';
     }
 
   for (start = end = name; *start; start = end)
@@ -160,153 +164,153 @@ __realpath (const char *name, char *resolved)
 
       /* Skip sequence of multiple path-separators.  */
       while (*start == '/')
-       ++start;
+        ++start;
 
       /* Find end of path component.  */
       for (end = start; *end && *end != '/'; ++end)
-       /* Nothing.  */;
+        /* Nothing.  */;
 
       if (end - start == 0)
-       break;
+        break;
       else if (end - start == 1 && start[0] == '.')
-       /* nothing */;
+        /* nothing */;
       else if (end - start == 2 && start[0] == '.' && start[1] == '.')
-       {
-         /* Back up to previous component, ignore if at root already.  */
-         if (dest > rpath + 1)
-           while ((--dest)[-1] != '/');
-         if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
-             && *dest == '/')
-           dest++;
-       }
+        {
+          /* Back up to previous component, ignore if at root already.  */
+          if (dest > rpath + 1)
+            while ((--dest)[-1] != '/');
+          if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
+              && *dest == '/')
+            dest++;
+        }
       else
-       {
-         size_t new_size;
-
-         if (dest[-1] != '/')
-           *dest++ = '/';
-
-         if (dest + (end - start) >= rpath_limit)
-           {
-             ptrdiff_t dest_offset = dest - rpath;
-             char *new_rpath;
-
-             if (resolved)
-               {
-                 __set_errno (ENAMETOOLONG);
-                 if (dest > rpath + 1)
-                   dest--;
-                 *dest = '\0';
-                 goto error;
-               }
-             new_size = rpath_limit - rpath;
-             if (end - start + 1 > path_max)
-               new_size += end - start + 1;
-             else
-               new_size += path_max;
-             new_rpath = (char *) realloc (rpath, new_size);
-             if (new_rpath == NULL)
-               {
-                 /* It's easier to set errno to ENOMEM than to rely on the
-                    'realloc-posix' gnulib module.  */
-                 errno = ENOMEM;
-                 goto error;
-               }
-             rpath = new_rpath;
-             rpath_limit = rpath + new_size;
-
-             dest = rpath + dest_offset;
-           }
+        {
+          size_t new_size;
+
+          if (dest[-1] != '/')
+            *dest++ = '/';
+
+          if (dest + (end - start) >= rpath_limit)
+            {
+              ptrdiff_t dest_offset = dest - rpath;
+              char *new_rpath;
+
+              if (resolved)
+                {
+                  __set_errno (ENAMETOOLONG);
+                  if (dest > rpath + 1)
+                    dest--;
+                  *dest = '\0';
+                  goto error;
+                }
+              new_size = rpath_limit - rpath;
+              if (end - start + 1 > path_max)
+                new_size += end - start + 1;
+              else
+                new_size += path_max;
+              new_rpath = (char *) realloc (rpath, new_size);
+              if (new_rpath == NULL)
+                {
+                  /* It's easier to set errno to ENOMEM than to rely on the
+                     'realloc-posix' gnulib module.  */
+                  errno = ENOMEM;
+                  goto error;
+                }
+              rpath = new_rpath;
+              rpath_limit = rpath + new_size;
+
+              dest = rpath + dest_offset;
+            }
 
 #ifdef _LIBC
-         dest = __mempcpy (dest, start, end - start);
+          dest = __mempcpy (dest, start, end - start);
 #else
-         memcpy (dest, start, end - start);
-         dest += end - start;
+          memcpy (dest, start, end - start);
+          dest += end - start;
 #endif
-         *dest = '\0';
+          *dest = '\0';
 
 #ifdef _LIBC
-         if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
+          if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
 #else
-         if (lstat (rpath, &st) < 0)
+          if (lstat (rpath, &st) < 0)
 #endif
-           goto error;
-
-         if (S_ISLNK (st.st_mode))
-           {
-             char *buf;
-             size_t len;
-
-             if (++num_links > MAXSYMLINKS)
-               {
-                 __set_errno (ELOOP);
-                 goto error;
-               }
-
-             buf = malloca (path_max);
-             if (!buf)
-               {
-                 errno = ENOMEM;
-                 goto error;
-               }
-
-             n = __readlink (rpath, buf, path_max - 1);
-             if (n < 0)
-               {
-                 int saved_errno = errno;
-                 freea (buf);
-                 errno = saved_errno;
-                 goto error;
-               }
-             buf[n] = '\0';
-
-             if (!extra_buf)
-               {
-                 extra_buf = malloca (path_max);
-                 if (!extra_buf)
-                   {
-                     freea (buf);
-                     errno = ENOMEM;
-                     goto error;
-                   }
-               }
-
-             len = strlen (end);
-             if ((long int) (n + len) >= path_max)
-               {
-                 freea (buf);
-                 __set_errno (ENAMETOOLONG);
-                 goto error;
-               }
-
-             /* Careful here, end may be a pointer into extra_buf... */
-             memmove (&extra_buf[n], end, len + 1);
-             name = end = memcpy (extra_buf, buf, n);
-
-             if (buf[0] == '/')
-               {
-                 dest = rpath + 1;     /* It's an absolute symlink */
-                 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && buf[1] == '/')
-                   *dest++ = '/';
-               }
-             else
-               {
-                 /* Back up to previous component, ignore if at root
-                    already: */
-                 if (dest > rpath + 1)
-                   while ((--dest)[-1] != '/');
-                 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
-                     && *dest == '/')
-                   dest++;
-               }
-           }
-         else if (!S_ISDIR (st.st_mode) && *end != '\0')
-           {
-             __set_errno (ENOTDIR);
-             goto error;
-           }
-       }
+            goto error;
+
+          if (S_ISLNK (st.st_mode))
+            {
+              char *buf;
+              size_t len;
+
+              if (++num_links > MAXSYMLINKS)
+                {
+                  __set_errno (ELOOP);
+                  goto error;
+                }
+
+              buf = malloca (path_max);
+              if (!buf)
+                {
+                  errno = ENOMEM;
+                  goto error;
+                }
+
+              n = __readlink (rpath, buf, path_max - 1);
+              if (n < 0)
+                {
+                  int saved_errno = errno;
+                  freea (buf);
+                  errno = saved_errno;
+                  goto error;
+                }
+              buf[n] = '\0';
+
+              if (!extra_buf)
+                {
+                  extra_buf = malloca (path_max);
+                  if (!extra_buf)
+                    {
+                      freea (buf);
+                      errno = ENOMEM;
+                      goto error;
+                    }
+                }
+
+              len = strlen (end);
+              if ((long int) (n + len) >= path_max)
+                {
+                  freea (buf);
+                  __set_errno (ENAMETOOLONG);
+                  goto error;
+                }
+
+              /* Careful here, end may be a pointer into extra_buf... */
+              memmove (&extra_buf[n], end, len + 1);
+              name = end = memcpy (extra_buf, buf, n);
+
+              if (buf[0] == '/')
+                {
+                  dest = rpath + 1;     /* It's an absolute symlink */
+                  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && buf[1] == '/')
+                    *dest++ = '/';
+                }
+              else
+                {
+                  /* Back up to previous component, ignore if at root
+                     already: */
+                  if (dest > rpath + 1)
+                    while ((--dest)[-1] != '/');
+                  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
+                      && *dest == '/')
+                    dest++;
+                }
+            }
+          else if (!S_ISDIR (st.st_mode) && *end != '\0')
+            {
+              __set_errno (ENOTDIR);
+              goto error;
+            }
+        }
     }
   if (dest > rpath + 1 && dest[-1] == '/')
     --dest;