/* * p1_dir.c — наблюдаемая проверка CURDIR/CHDIR/F_FIRST/F_NEXT. * * Тест не меняет файлы. chdir(".") используется только для проверки * сохранения текущего каталога. */ #include #include #include #include #include #include #include "p1_platform.h" #define P1_FIND_ATTRS (FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_DIREC | FA_ARCH) #define P1_FIND_LIMIT 4096u static char cwd_before[256]; static char cwd_after[256]; static ffblk_t find_buf; static int scan_pattern(const char *pattern, uint16_t *out_count, uint8_t *out_dot, uint8_t *out_dotdot) { uint16_t count = 0; uint8_t dot = 0; uint8_t dotdot = 0; int rc; int end_errno; errno = 0; rc = ffirst(pattern, &find_buf, P1_FIND_ATTRS); if (rc != 0) { if (errno == ENOENT) { printf("Pattern %-4s: empty (ffirst errno=%d)\n", pattern, errno); *out_count = 0; *out_dot = 0; *out_dotdot = 0; return 0; } printf("ffirst(%s) failed: errno=%d\n", pattern, errno); return -1; } for (;;) { if (strcmp(find_buf.found_name, ".") == 0) dot = 1; if (strcmp(find_buf.found_name, "..") == 0) dotdot = 1; if (count < 20) { printf(" %02X %10lu %04X/%04X %s\n", (unsigned)find_buf.found_attr, (unsigned long)find_buf.size, (unsigned)find_buf.date, (unsigned)find_buf.time, find_buf.found_name); } count++; if (count >= P1_FIND_LIMIT) { puts("Enumeration limit reached: possible F_NEXT loop."); return -1; } errno = 0; if (fnext(&find_buf) != 0) break; } end_errno = errno; printf("Pattern %-4s: count=%u dot=%u dotdot=%u end_errno=%d\n", pattern, (unsigned)count, (unsigned)dot, (unsigned)dotdot, end_errno); /* MAME 0.287 / BIOS 3.06 подтвердил ENOENT (3) для конца F_NEXT. * Код 0x0F из старого описания DSS здесь не является штатным. */ if (end_errno != ENOENT) { puts("Unexpected F_NEXT termination code."); return -1; } *out_count = count; *out_dot = dot; *out_dotdot = dotdot; return 0; } int p1_test_directory(void) { uint16_t count_star_dot; uint16_t count_star; uint8_t dot1, dotdot1, dot2, dotdot2; int failed = 0; p1_heading("Directory: CURDIR, CHDIR, F_FIRST/F_NEXT"); errno = 0; if (getcwd(cwd_before, sizeof(cwd_before)) == 0) { printf("getcwd failed: errno=%d\n", errno); return -1; } printf("CWD before: %s\n", cwd_before); if (chdir(".") != 0) { printf("chdir(.) failed: errno=%d\n", errno); failed++; } if (getcwd(cwd_after, sizeof(cwd_after)) == 0) { printf("second getcwd failed: errno=%d\n", errno); return -1; } printf("CWD after : %s\n", cwd_after); if (strcmp(cwd_before, cwd_after) != 0) { puts("CWD changed after chdir(.)."); failed++; } puts("\nFirst entries for *.*:"); if (scan_pattern("*.*", &count_star_dot, &dot1, &dotdot1) != 0) { failed++; } puts("\nFirst entries for *:"); if (scan_pattern("*", &count_star, &dot2, &dotdot2) != 0) { failed++; } if (count_star != count_star_dot) { printf("NOTE: * count (%u) differs from *.* count (%u).\n", (unsigned)count_star, (unsigned)count_star_dot); } if (dot1 != dot2 || dotdot1 != dotdot2) { puts("NOTE: dot entries differ between patterns."); } printf("Directory checks failed: %u\n", (unsigned)failed); return failed ? -1 : 0; } int p1_test_disk_info(void) { P1DiskInfo info; uint32_t cluster_bytes; uint32_t total_bytes; uint32_t free_bytes; p1_heading("DSKINFO: current disk"); errno = 0; if (p1_disk_info(0xFF, &info) != 0) { printf("DSKINFO failed: errno=%d\n", errno); return -1; } cluster_bytes = (uint32_t)info.sectors_per_cluster * (uint32_t)info.bytes_per_sector; total_bytes = cluster_bytes * (uint32_t)info.total_clusters; free_bytes = cluster_bytes * (uint32_t)info.free_clusters; printf("Sectors/cluster : %u\n", (unsigned)info.sectors_per_cluster); printf("Bytes/sector : %u\n", (unsigned)info.bytes_per_sector); printf("Total clusters : %u\n", (unsigned)info.total_clusters); printf("Free clusters : %u\n", (unsigned)info.free_clusters); printf("Cluster bytes : %lu\n", (unsigned long)cluster_bytes); printf("Total bytes : %lu\n", (unsigned long)total_bytes); printf("Free bytes : %lu\n", (unsigned long)free_bytes); if (info.sectors_per_cluster == 0 || info.bytes_per_sector == 0 || info.total_clusters == 0 || info.free_clusters > info.total_clusters) { puts("DSKINFO returned inconsistent values."); return -1; } return 0; }