+# endif /* !Windows */
+#else /* HAVE_LINK */
+
+# undef link
+
+/* Create a hard link from FILE1 to FILE2, working around platform bugs. */
+int
+rpl_link (char const *file1, char const *file2)
+{
+ size_t len1;
+ size_t len2;
+ struct stat st;
+
+ /* Don't allow IRIX to dereference dangling file2 symlink. */
+ if (!lstat (file2, &st))
+ {
+ errno = EEXIST;
+ return -1;
+ }
+
+ /* Reject trailing slashes on non-directories. */
+ len1 = strlen (file1);
+ len2 = strlen (file2);
+ if ((len1 && file1[len1 - 1] == '/')
+ || (len2 && file2[len2 - 1] == '/'))
+ {
+ /* Let link() decide whether hard-linking directories is legal.
+ If stat() fails, then link() should fail for the same reason
+ (although on Solaris 9, link("file/","oops") mistakenly
+ succeeds); if stat() succeeds, require a directory. */
+ if (stat (file1, &st))
+ return -1;
+ if (!S_ISDIR (st.st_mode))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+ }
+ else
+ {
+ /* Fix Cygwin 1.5.x bug where link("a","b/.") creates file "b". */
+ char *dir = strdup (file2);
+ char *p;
+ if (!dir)
+ return -1;
+ /* We already know file2 does not end in slash. Strip off the
+ basename, then check that the dirname exists. */
+ p = strrchr (dir, '/');
+ if (p)
+ {
+ *p = '\0';
+ if (stat (dir, &st) == -1)
+ {
+ int saved_errno = errno;
+ free (dir);
+ errno = saved_errno;
+ return -1;
+ }
+ }
+ free (dir);
+ }
+ return link (file1, file2);
+}
+#endif /* HAVE_LINK */