#define _GNU_SOURCE
#include "test-common.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int test_unlink(const char *base_path) {
char path[512], link_path[512];
struct stat st;
int result, fd;
snprintf(path, sizeof(path), "%s/unlink_test.txt", base_path);
snprintf(link_path, sizeof(link_path), "%s/unlink_test_link", base_path);
unlink(link_path);
unlink(path);
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
TEST_ASSERT_ERRNO(fd >= 0, "create file should succeed");
result = write(fd, "test data", 9);
TEST_ASSERT_ERRNO(result == 9, "write should succeed");
close(fd);
result = link(path, link_path);
if (result < 0 && (errno == ENOSYS || errno == EOPNOTSUPP)) {
printf(" (Skipping unlink path cache test - hard links not supported)\n");
unlink(path);
return 0;
}
TEST_ASSERT_ERRNO(result == 0, "link creation should succeed");
result = unlink(path);
TEST_ASSERT_ERRNO(result == 0, "unlink original should succeed");
* Before the fix, the path cache was invalidated when unlinking,
* even though the hard link still references the same inode.
*/
result = stat(link_path, &st);
TEST_ASSERT_ERRNO(result == 0, "stat on remaining hard link should succeed after unlink");
TEST_ASSERT(S_ISREG(st.st_mode), "hard link should still be a regular file");
TEST_ASSERT(st.st_nlink == 1, "nlink should be 1 after removing original");
char buf[16] = {0};
fd = open(link_path, O_RDONLY);
TEST_ASSERT_ERRNO(fd >= 0, "open hard link for reading should succeed");
result = read(fd, buf, sizeof(buf) - 1);
TEST_ASSERT_ERRNO(result == 9, "read from hard link should succeed");
TEST_ASSERT(memcmp(buf, "test data", 9) == 0, "data should be intact via hard link");
close(fd);
fd = open(link_path, O_WRONLY | O_TRUNC);
TEST_ASSERT_ERRNO(fd >= 0, "open hard link for writing should succeed");
result = write(fd, "new data", 8);
TEST_ASSERT_ERRNO(result == 8, "write to hard link should succeed");
close(fd);
unlink(link_path);
return 0;
}