ww: clean per-pid sep-build scratch dir on run/test (#59)
ww run / ww test created /tmp/ww_{run,test}_<pid>.sepwork/ but removed only
the built binary, leaking the scratch DIR every invocation — the tmpfs filler
(98,811 entries blocked the gate twice). Add a keepscratch param to
build_one_sep: a thin wrapper rm -rfs the impl scratch at the single
choke-point when keepscratch==0 AND the path ends ".sepwork" (covers every
return, success+error; fires post-link, pre-run). do_build keeps it (the
byte-id gates read <stem>.sepwork from ww build -o); do_run/do_test clean;
do_test no-o redirects scratch into /tmp. Both stages symmetric; reuses the
existing shell rm -rf idiom (lib/os.removeall = #109). Test 989_sepscratch_run
is self-scoped by child pid (non-flaky) with a KEEP control + revert-verified
non-vacuity. Full gate: 448 pass, zero new run/test leaks. (ww_d_* relic +
historical bulk = one-time sweep + agent-probe discipline, not code.)
This commit is contained in:
@@ -867,9 +867,9 @@ cleanup:
|
||||
* reverse-topo `w6l` of the root `.o` + dep `.a` set + libwwrt.a. Side
|
||||
* files land in a cold `<stem>.sepwork` dir (content-keyed cache = 5b). */
|
||||
static int
|
||||
build_one_sep(const char *src, int entry_is_dir, const char *out,
|
||||
build_one_sep_impl(const char *src, int entry_is_dir, const char *out,
|
||||
const char *objstem, const char *extra_includes, const char *extra_libs,
|
||||
const char *extra_libdirs, int is_test)
|
||||
const char *extra_libdirs, int is_test, char *scratchout, size_t scratchoutsz)
|
||||
{
|
||||
const char *c6 = toolpath("WW_W6C", "w6c");
|
||||
const char *a6 = toolpath("WW_W6A", "w6a");
|
||||
@@ -929,6 +929,10 @@ build_one_sep(const char *src, int entry_is_dir, const char *out,
|
||||
fprintf(stderr, "ww --sep: cannot create scratch %s\n", scratch);
|
||||
return 1;
|
||||
}
|
||||
/* #59: hand the scratch path back so the build_one_sep wrapper can
|
||||
* rm it on run/test (keepscratch 0). Set AFTER mkdir succeeds so the
|
||||
* wrapper only removes a dir we actually created. */
|
||||
if (scratchout) snprintf(scratchout, scratchoutsz, "%s", scratch);
|
||||
|
||||
struct sepgraph *g = calloc(1, sizeof *g);
|
||||
if (g == NULL) return 1;
|
||||
@@ -1062,6 +1066,34 @@ build_one_sep(const char *src, int entry_is_dir, const char *out,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* build_one_sep — thin wrapper over build_one_sep_impl that removes the
|
||||
* per-build `<stem>.sepwork` scratch dir when keepscratch is 0 (ww run /
|
||||
* ww test — the binary is the only artifact wanted). do_build passes
|
||||
* keepscratch 1: the byte-id gates read `<stem>.sepwork/*.s` from the
|
||||
* `ww build -o` path, so build scratch must persist. One cleanup site
|
||||
* covers every impl return (success AND error). Guard: only rm a path the
|
||||
* impl actually wrote that ends ".sepwork" — never an empty/foreign stem
|
||||
* (#59). Reuses the existing shell rm -rf idiom (build_one_sep_impl:927). */
|
||||
static int
|
||||
build_one_sep(const char *src, int entry_is_dir, const char *out,
|
||||
const char *objstem, const char *extra_includes, const char *extra_libs,
|
||||
const char *extra_libdirs, int is_test, int keepscratch)
|
||||
{
|
||||
char scratch[1100] = {0};
|
||||
int r = build_one_sep_impl(src, entry_is_dir, out, objstem,
|
||||
extra_includes, extra_libs, extra_libdirs, is_test,
|
||||
scratch, sizeof scratch);
|
||||
if (!keepscratch && scratch[0]) {
|
||||
size_t sl = strlen(scratch);
|
||||
if (sl > 8 && strcmp(scratch + sl - 8, ".sepwork") == 0) {
|
||||
char m[1200];
|
||||
snprintf(m, sizeof m, "rm -rf %s", scratch);
|
||||
run(m);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
do_version(void)
|
||||
{
|
||||
@@ -1291,7 +1323,7 @@ do_build(int argc, char **argv)
|
||||
basename_no_ext(resolved, out, sizeof out);
|
||||
}
|
||||
return build_one_sep(resolved, is_dir, out, objstem, incs, libs,
|
||||
libdirs, 0);
|
||||
libdirs, 0, 1 /* keepscratch: gates read build -o .sepwork */);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1317,7 +1349,8 @@ do_run(int argc, char **argv)
|
||||
snprintf(tmp, sizeof tmp, "/tmp/ww_run_%d", getpid());
|
||||
/* objstem = tmp → intermediates land under /tmp/ww_run_<pid>.sepwork/,
|
||||
* never next to the source (T3). */
|
||||
if (build_one_sep(resolved, is_dir, tmp, tmp, incs, libs, libdirs, 0) != 0)
|
||||
if (build_one_sep(resolved, is_dir, tmp, tmp, incs, libs, libdirs, 0,
|
||||
0 /* keepscratch: throwaway run scratch */) != 0)
|
||||
return 1;
|
||||
/* exec the built binary with any trailing argv as its argv. */
|
||||
pid_t pid = fork();
|
||||
@@ -1418,8 +1451,12 @@ do_test(int argc, char **argv)
|
||||
const char *outp;
|
||||
if (outstem[0]) outp = outstem;
|
||||
else { snprintf(tmp, sizeof tmp, "/tmp/ww_test_%d", getpid()); outp = tmp; }
|
||||
/* #59: no-o → objstem=tmp so scratch lands in /tmp (cleaned),
|
||||
* not next to the source; keepscratch 0 throws it away. With -o
|
||||
* the user named an artifact home, so keep it (mirror do_build). */
|
||||
int br = build_one_sep(resolved, is_dir, outp,
|
||||
outstem[0] ? outstem : NULL, incs, "", "", 1);
|
||||
outstem[0] ? outstem : tmp, incs, "", "", 1,
|
||||
outstem[0] ? 1 : 0);
|
||||
if (br != 0) return 1;
|
||||
if (compileonly) return 0;
|
||||
int rc = run_test_bin(outp, pattern);
|
||||
@@ -1432,8 +1469,9 @@ do_test(int argc, char **argv)
|
||||
const char *outp;
|
||||
if (outstem[0]) outp = outstem;
|
||||
else { snprintf(tmp, sizeof tmp, "/tmp/ww_test_%d", getpid()); outp = tmp; }
|
||||
int br = build_one_sep(target, 0, outp, outstem[0] ? outstem : NULL,
|
||||
incs, "", "", 1);
|
||||
/* #59: see module-mode note — no-o scratch → /tmp, cleaned. */
|
||||
int br = build_one_sep(target, 0, outp, outstem[0] ? outstem : tmp,
|
||||
incs, "", "", 1, outstem[0] ? 1 : 0);
|
||||
if (br != 0) return 1;
|
||||
if (compileonly) return 0;
|
||||
int rc = run_test_bin(outp, pattern);
|
||||
@@ -1471,7 +1509,8 @@ do_test(int argc, char **argv)
|
||||
snprintf(tmp, sizeof tmp, "/tmp/ww_test_%d_%d", getpid(), i);
|
||||
const char *label = strrchr(files[i], '/');
|
||||
label = label ? label + 1 : files[i];
|
||||
int rc = build_one_sep(files[i], 0, tmp, NULL, target, "", "", 1);
|
||||
/* #59: objstem=tmp → scratch in /tmp (cleaned), keepscratch 0. */
|
||||
int rc = build_one_sep(files[i], 0, tmp, tmp, target, "", "", 1, 0);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "FAIL %s (build)\n", label);
|
||||
fail++;
|
||||
|
||||
Reference in New Issue
Block a user