}
return f == NULL ? 0 : (*f)(linkname, target, NULL);
}
+
+int
+my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+ HANDLE h;
+ int r;
+
+ h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return (0);
+ r = GetFileInformationByHandle(h, bhfi);
+ CloseHandle(h);
+ return (r);
+}
#endif
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__GNUC__)
return (0);
}
-/* Verify that two paths point to the same file. */
+/* Test that two paths point to the same file. */
+/* As a side-effect, asserts that both files exist. */
int
-assertion_file_hardlinks(const char *file, int line,
+is_file_hardlinks(const char *file, int line,
const char *path1, const char *path2)
{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ BY_HANDLE_FILE_INFORMATION bhfi1, bhfi2;
+ int r;
+
+ assertion_count(file, line);
+ r = my_GetFileInformationByName(path1, &bhfi1);
+ if (r == 0) {
+ failure_start(file, line, "File %s can't be inspected?", path1);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = my_GetFileInformationByName(path2, &bhfi2);
+ if (r == 0) {
+ failure_start(file, line, "File %s can't be inspected?", path2);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh
+ && bhfi1.nFileIndexLow == bhfi2.nFileIndexLow);
+#else
struct stat st1, st2;
int r;
failure_finish(NULL);
return (0);
}
- if (st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) {
- failure_start(file, line,
- "Files %s and %s are not hardlinked", path1, path2);
- failure_finish(NULL);
- return (0);
- }
- return (1);
+ return (st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev);
+#endif
+}
+
+int
+assertion_file_hardlinks(const char *file, int line,
+ const char *path1, const char *path2)
+{
+ if (is_file_hardlinks(file, line, path1, path2))
+ return (1);
+ failure_start(file, line,
+ "Files %s and %s are not hardlinked", path1, path2);
+ failure_finish(NULL);
+ return (0);
}
/* Verify a/b/mtime of 'pathname'. */
const char *pathname, int nlinks)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE h;
BY_HANDLE_FILE_INFORMATION bhfi;
int r;
assertion_count(file, line);
- h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE) {
- failure_start(file, line, "Can't access %s", pathname);
- failure_finish(NULL);
- return (0);
- }
- r = GetFileInformationByHandle(h, &bhfi);
+ r = my_GetFileInformationByName(pathname, &bhfi);
if (r != 0 && bhfi.nNumberOfLinks == nlinks)
return (1);
failure_start(file, line, "File %s has %d links, expected %d",
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
+/*
+ */
+#define isFileHardlinks(path1, path2) \
+ is_file_hardlinks(__FILE__, __LINE__, path1, path2)
+
/*
* This would be simple with C99 variadic macros, but I don't want to
* require that. Instead, I insert a function call before each
int assertion_text_file_contents(const char *buff, const char *f);
int assertion_umask(const char *, int, int);
void assertion_setup(const char *, int);
+
+int is_file_hardlinks(const char *, int, const char *, const char *);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
DEFINE_TEST(test_option_l)
{
- struct stat st, st2;
int r;
/* Create a file. */
assertMakeFile("f", 0644, "a");
- /* Stat it. */
- assertEqualInt(0, stat("f", &st));
-
/* Copy the file to the "copy" dir. */
r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
testprog);
assertEqualInt(r, 0);
/* Check that the copy is a true copy and not a link. */
- assertEqualInt(0, stat("copy/f", &st2));
- assert(st2.st_ino != st.st_ino);
+ assert(!isFileHardlinks("f", "copy/f"));
/* Copy the file to the "link" dir with the -l option. */
r = systemf("echo f | %s -pld link >link.out 2>link.err",
assertEqualInt(r, 0);
/* Check that this is a link and not a copy. */
- assertEqualInt(0, stat("link/f", &st2));
- assert(st2.st_ino == st.st_ino);
+ assertFileHardlinks("f", "link/f");
}