openat: detect Solaris fchownat bug
[pspp] / lib / relocatable.c
index e814a0e4ebd620d09e44f6df05425fdcb507bc48..b4944200381337ee15b91f1a19f346b03a0f51d7 100644 (file)
@@ -1,5 +1,5 @@
 /* Provide relocatable packages.
-   Copyright (C) 2003-2006, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2003-2006, 2008-2009 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software; you can redistribute it and/or modify it
@@ -233,11 +233,11 @@ compute_curr_prefix (const char *orig_installprefix,
                  same = true;
                break;
              }
-           /* Do case-insensitive comparison if the filesystem is always or
+           /* Do case-insensitive comparison if the file system is always or
               often case-insensitive.  It's better to accept the comparison
               if the difference is only in case, rather than to fail.  */
 #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
-           /* Win32, Cygwin, OS/2, DOS - case insignificant filesystem */
+           /* Win32, Cygwin, OS/2, DOS - case insignificant file system */
            if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi)
                != (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
              break;
@@ -409,7 +409,9 @@ get_shared_library_fullname ()
 #endif /* PIC */
 
 /* Returns the pathname, relocated according to the current installation
-   directory.  */
+   directory.
+   The returned string is either PATHNAME unmodified or a freshly allocated
+   string that you can free with free() after casting it to 'char *'.  */
 const char *
 relocate (const char *pathname)
 {
@@ -448,16 +450,26 @@ relocate (const char *pathname)
 #endif
 
   /* Note: It is not necessary to perform case insensitive comparison here,
-     even for DOS-like filesystems, because the pathname argument was
+     even for DOS-like file systems, because the pathname argument was
      typically created from the same Makefile variable as orig_prefix came
      from.  */
   if (orig_prefix != NULL && curr_prefix != NULL
       && strncmp (pathname, orig_prefix, orig_prefix_len) == 0)
     {
       if (pathname[orig_prefix_len] == '\0')
-       /* pathname equals orig_prefix.  */
-       return curr_prefix;
-      if (ISSLASH (pathname[orig_prefix_len]))
+       {
+         /* pathname equals orig_prefix.  */
+         char *result = (char *) xmalloc (strlen (curr_prefix) + 1);
+
+#ifdef NO_XMALLOC
+         if (result != NULL)
+#endif
+           {
+             strcpy (result, curr_prefix);
+             return result;
+           }
+       }
+      else if (ISSLASH (pathname[orig_prefix_len]))
        {
          /* pathname starts with orig_prefix.  */
          const char *pathname_tail = &pathname[orig_prefix_len];