Import upstream version 1.29
[debian/tar] / gnu / linkat.c
index 2874205414300cb9f55e7228f0d48913a88b41b6..4bdbae677a6ef8703c7930d66e20b3657c9df354 100644 (file)
@@ -1,7 +1,5 @@
-/* -*- buffer-read-only: t -*- vi: set ro: */
-/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
 /* Create a hard link relative to open directories.
-   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+   Copyright (C) 2009-2015 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -45,7 +43,7 @@
 # endif
 #endif
 
-#if !HAVE_LINKAT
+#if !HAVE_LINKAT || LINKAT_SYMLINK_NOTSUP
 
 /* Create a link.  If FILE1 is a symlink, either create a hardlink to
    that symlink, or fake it by creating an identical symlink.  */
@@ -197,6 +195,10 @@ solaris_optimized_link_follow (char const *file1, char const *file2)
 
 # endif
 
+#endif /* !HAVE_LINKAT || LINKAT_SYMLINK_NOTSUP  */
+
+#if !HAVE_LINKAT
+
 /* Create a link to FILE1, in the directory open on descriptor FD1, to FILE2,
    in the directory open on descriptor FD2.  If FILE1 is a symlink, FLAG
    controls whether to dereference FILE1 first.  If possible, do it without
@@ -323,7 +325,17 @@ rpl_linkat (int fd1, char const *file1, int fd2, char const *file2, int flag)
 # endif
 
   if (!flag)
-    return linkat (fd1, file1, fd2, file2, flag);
+    {
+      int result = linkat (fd1, file1, fd2, file2, flag);
+# if LINKAT_SYMLINK_NOTSUP
+      /* OS X 10.10 has linkat() but it doesn't support
+         hardlinks to symlinks.  Fallback to our emulation
+         in that case.  */
+      if (result == -1 && (errno == ENOTSUP || errno == EOPNOTSUPP))
+        return at_func2 (fd1, file1, fd2, file2, link_immediate);
+# endif
+      return result;
+    }
 
   /* Cache the information on whether the system call really works.  */
   {