/* * p10_rename_probe.c — target-регрессия локального F6/RENAME. * * Проверяет файл, каталог, запрет overwrite и восстановление CWD через тот * же низкоуровневый helper, который вызывает Commander. */ #include #include #include #include #include #include "sc_file_ops.h" static int result_fd = -1; static uint8_t failures; static char cwd_before[256]; static char cwd_after[256]; static char cwd_scratch[256]; static void log_text(const char *text) { const char *end = text; while (*end != '\0') end++; if (result_fd >= 0) { (void)write(result_fd, text, (uint16_t)(end - text)); } } static void check(uint8_t condition, const char *name) { log_text(condition ? "PASS " : "FAIL "); if (!condition) failures++; log_text(name); log_text("\r\n"); } static uint8_t file_has(const char *path, const char *expected) { char data[24]; int fd = open(path, O_RDONLY); int got; uint16_t length = 0u; if (fd < 0) return 0u; while (expected[length] != '\0') length++; got = read(fd, data, sizeof(data)); (void)close(fd); return got == (int)length && memcmp(data, expected, length) == 0; } static uint8_t file_absent(const char *path) { int fd; errno = 0; fd = open(path, O_RDONLY); if (fd >= 0) { (void)close(fd); return 0u; } return errno == ENOENT || errno == ENOPATH; } int main(void) { int rc; int collision_errno; int entered; result_fd = open("D:\\RENRES.TXT", O_WRONLY | O_CREAT | O_TRUNC); check(getcwd(cwd_before, sizeof(cwd_before)) != 0, "CWD captured before rename matrix"); rc = sc_rename_local("D:\\RENTEST", "OLD.TXT", "NEW.TXT", cwd_scratch, sizeof(cwd_scratch)); check(rc == 0 && file_absent("D:\\RENTEST\\OLD.TXT") && file_has("D:\\RENTEST\\NEW.TXT", "old payload\r\n"), "file renamed without data change"); errno = 0; rc = sc_rename_local("D:\\RENTEST", "NEW.TXT", "EXIST.TXT", cwd_scratch, sizeof(cwd_scratch)); collision_errno = errno; check(rc != 0 && collision_errno == EEXIST && file_has("D:\\RENTEST\\NEW.TXT", "old payload\r\n") && file_has("D:\\RENTEST\\EXIST.TXT", "existing payload\r\n"), "existing target blocks rename and stays intact"); rc = sc_rename_local("D:\\RENTEST", "OLDDIR", "NEWDIR", cwd_scratch, sizeof(cwd_scratch)); entered = chdir("D:\\RENTEST\\NEWDIR"); if (entered == 0) entered = chdir(cwd_before); check(rc == 0 && entered == 0 && file_has("D:\\RENTEST\\NEWDIR\\KEEP.BIN", "dir payload\r\n"), "directory renamed with contents intact"); errno = 0; rc = sc_rename_local("D:\\MISSING", "A.TXT", "B.TXT", cwd_scratch, sizeof(cwd_scratch)); check(rc != 0 && getcwd(cwd_after, sizeof(cwd_after)) != 0 && strcmp(cwd_before, cwd_after) == 0, "failed directory change preserves CWD"); check(getcwd(cwd_after, sizeof(cwd_after)) != 0 && strcmp(cwd_before, cwd_after) == 0, "successful and rejected renames restore CWD"); if (failures == 0u) log_text("ALL PASS\r\n"); if (result_fd >= 0) (void)close(result_fd); return failures; }