/* * 976_stat_run — execute the lib/os stat fixture under the C-side * `ww run` driver and assert exit 0. * * Workflow (mirrors 975_dirs_run's mkdtemp + setenv + rm-rf shape): * 1. mkdtemp /tmp/wwstat-XXXXXX — fresh per run, no parallel-test * contention. * 2. Populate the scratch tree: * /regfile regular file, 11 bytes "hello world" * /symlink → ./regfile (relative symlink) * /subdir directory, mode 0700 * 3. setenv WW_TEST_STAT_REGFILE / SYMLINK / SUBDIR / NOENT with * the absolute paths; lib/os/stattest.ww reads them via * os.getenv and exercises stat/lstat/fstat/exists. * 4. exec `ww run lib/os/stattest.ww`. * 5. system("rm -rf ") regardless of pass/fail. * * Same wrapper shape as 970-975; cleanup-on-failure is rm-rf'd so a * regression never leaves residue under /tmp. */ #include #include #include #include #include #include #include static int runwait(const char *cmd) { int rc = system(cmd); if (rc == -1) return -1; if (WIFEXITED(rc)) return WEXITSTATUS(rc); return 1; } int main(void) { const char *bin = getenv("BIN"); if (!bin) bin = "out/bin"; char absbin[1024]; if (bin[0] != '/') { char cwd[1024]; if (getcwd(cwd, sizeof cwd) == NULL) return 1; snprintf(absbin, sizeof absbin, "%s/%s", cwd, bin); bin = absbin; } char cwd[1024]; if (getcwd(cwd, sizeof cwd) == NULL) return 1; char tmpl[64]; strcpy(tmpl, "/tmp/wwstat-XXXXXX"); if (mkdtemp(tmpl) == NULL) { perror("mkdtemp"); return 1; } char regfile[256], symlink_path[256], subdir[256], noent[256]; snprintf(regfile, sizeof regfile, "%s/regfile", tmpl); snprintf(symlink_path, sizeof symlink_path, "%s/symlink", tmpl); snprintf(subdir, sizeof subdir, "%s/subdir", tmpl); snprintf(noent, sizeof noent, "%s/does-not-exist", tmpl); /* Populate. */ int fd = open(regfile, O_WRONLY | O_CREAT | O_EXCL, 0644); if (fd < 0) { perror("open regfile"); goto cleanup_fail; } if (write(fd, "hello world", 11) != 11) { perror("write regfile"); close(fd); goto cleanup_fail; } close(fd); if (symlink("./regfile", symlink_path) != 0) { perror("symlink"); goto cleanup_fail; } if (mkdir(subdir, 0700) != 0) { perror("mkdir subdir"); goto cleanup_fail; } setenv("WW_TEST_STAT_REGFILE", regfile, 1); setenv("WW_TEST_STAT_SYMLINK", symlink_path, 1); setenv("WW_TEST_STAT_SUBDIR", subdir, 1); setenv("WW_TEST_STAT_NOENT", noent, 1); const char *src = "lib/os/stattest.ww"; char path[1024], cmd[2048]; snprintf(path, sizeof path, "%s/%s", cwd, src); snprintf(cmd, sizeof cmd, "%s/ww test %s", bin, path); int rc = runwait(cmd); char rmcmd[256]; snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpl); (void)system(rmcmd); if (rc != 0) { fprintf(stderr, "stat_run FAIL: %s exited %d\n", src, rc); return 1; } printf("stat_run: %s ok\n", src); return 0; cleanup_fail: { char rmcmd[256]; snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpl); (void)system(rmcmd); return 1; } }