The following patch has been submitted to Bugzilla as bug # 44841. It creates 
an APR wrapper for
the link(2) function in Unix, which corresponds to the CreateHardLink() function in Win32.
Regards,

 - Mark

diff -x '*.lo' -x '*.mk' -x 'config.*' -ur 
../apr.20080417222010/file_io/unix/copy.c ./file_io/unix/copy.c
--- ../apr.20080417222010/file_io/unix/copy.c   2008-04-17 21:01:23.000000000 
-0400
+++ ./file_io/unix/copy.c       2008-04-18 18:22:22.000000000 -0400
@@ -110,3 +110,13 @@
                                      perms,
                                      pool);
}
+
+APR_DECLARE(apr_status_t) apr_file_link(const char *from_path, + const char *to_path)
+{
+    if (link(from_path, to_path) == -1) {
+        return errno;
+    }
+
+    return APR_SUCCESS;
+}
diff -x '*.lo' -x '*.mk' -x 'config.*' -ur 
../apr.20080417222010/file_io/win32/open.c ./file_io/win32/open.c
--- ../apr.20080417222010/file_io/win32/open.c  2008-04-17 21:01:23.000000000 
-0400
+++ ./file_io/win32/open.c      2008-04-18 18:21:36.000000000 -0400
@@ -578,6 +578,36 @@
    return apr_get_os_error();
}

+APR_DECLARE(apr_status_t) apr_file_link(const char *from_path, + const char *to_path)
+{
+    apr_status_t rv;
+
+#if APR_HAS_UNICODE_FS
+    IF_WIN_OS_IS_UNICODE
+    {
+        apr_wchar_t wfrom_path[APR_PATH_MAX];
+        apr_wchar_t wto_path[APR_PATH_MAX];
+
+ if (rv = utf8_to_unicode_path(wfrom_path, sizeof(wfrom_path) + / sizeof(apr_wchar_t), from_path))
+            return rv;
+ if (rv = utf8_to_unicode_path(wto_path, sizeof(wto_path) + / sizeof(apr_wchar_t), to_path))
+            return rv;
+
+        if (!CreateHardLinkW(wto_path, wfrom_path))
+                return apr_get_os_error()
+    }
+#endif
+#if APR_HAS_ANSI_FS
+    ELSE_WIN_OS_IS_ANSI {
+        if (!CreateHardLinkA(wto_path, wfrom_path))
+                return apr_get_os_error()
+    }
+#endif
+}
+
APR_DECLARE(apr_status_t) apr_os_file_get(apr_os_file_t *thefile,
                                          apr_file_t *file)
{
diff -x '*.lo' -x '*.mk' -x 'config.*' -ur 
../apr.20080417222010/include/apr_file_io.h ./include/apr_file_io.h
--- ../apr.20080417222010/include/apr_file_io.h 2008-04-17 21:01:23.000000000 
-0400
+++ ./include/apr_file_io.h     2008-04-18 18:23:13.000000000 -0400
@@ -265,6 +265,15 @@
                                          apr_pool_t *pool);

/**
+ * Create a hard link to the specified file.
+ * @param from_path The full path to the original file (using / on all systems)
+ * @param to_path The full path to the new file (using / on all systems)
+ * @remark Both files must reside on the same device.
+ */
+APR_DECLARE(apr_status_t) apr_file_link(const char *from_path, + const char *to_path);
+
+/**
 * Copy the specified file to another file.
 * @param from_path The full path to the original file (using / on all systems)
 * @param to_path The full path to the new file (using / on all systems)
diff -x '*.lo' -x '*.mk' -x 'config.*' -ur 
../apr.20080417222010/test/testfilecopy.c ./test/testfilecopy.c
--- ../apr.20080417222010/test/testfilecopy.c   2008-04-17 21:01:23.000000000 
-0400
+++ ./test/testfilecopy.c       2008-04-18 19:53:33.000000000 -0400
@@ -123,6 +123,23 @@
    APR_ASSERT_SUCCESS(tc, "Couldn't remove copy file", rv);
}

+static void link_existing(abts_case *tc, void *data)
+{
+    apr_status_t rv;
+ + rv = apr_file_link("data/file_datafile.txt", "data/file_datafile2.txt");
+    apr_file_remove("data/file_datafile2.txt", p);
+    ABTS_ASSERT(tc, "Couldn't create hardlink to file", rv == APR_SUCCESS);
+}
+
+static void link_nonexisting(abts_case *tc, void *data)
+{
+    apr_status_t rv;
+ + rv = apr_file_link("data/does_not_exist.txt", "data/fake.txt");
+    ABTS_ASSERT(tc, "", rv != APR_SUCCESS);
+}
+
abts_suite *testfilecopy(abts_suite *suite)
{
    suite = ADD_SUITE(suite)
@@ -133,6 +150,9 @@
    abts_run_test(suite, append_nonexist, NULL);
    abts_run_test(suite, append_exist, NULL);

+    abts_run_test(suite, link_existing, NULL);
+    abts_run_test(suite, link_nonexisting, NULL);
+
    return suite;
}


Reply via email to