test/wcc: carrier ownership repair and driver-contract adaptation
Every surviving carrier now owns its artifacts: checked mkdir/mkdtemp/ fopen acquisition, one all-exit cleanup funnel per carrier, ENOENT- tolerant checked unlinks, exact-path deletion (rm -rf only for an owned pid-keyed dir or a .sepwork beneath one), and cleanup failure fails a passing carrier without overwriting its diagnostic. In the same pass the carriers adapt to the driver contract this branch lands: --sep and WW_PKGCACHE are gone, -S and the /tmp/ww_run_<pid> scratch contract are asserted, and rows whose runtime or reject coverage moved to test/wcc/data fixtures or test/lang @test owners are trimmed to the byte/artifact/diagnostic observations only they can make. Repair and adaptation ride together because most files interleave both in the same hunks; splitting would manufacture intermediate carrier states that never existed and cannot run against either driver.
This commit is contained in:
@@ -16,7 +16,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
@@ -49,8 +51,8 @@ runwait(const char *cmd)
|
||||
static int
|
||||
linkwith(const char *lnk, const char *obj, const char *libdir, int nflags)
|
||||
{
|
||||
char exe[64];
|
||||
snprintf(exe, sizeof exe, "/tmp/wwfc_%d_x", getpid());
|
||||
char exe[128];
|
||||
snprintf(exe, sizeof exe, "%s/wwfc_x", libdir);
|
||||
|
||||
char junk[8192];
|
||||
size_t off = 0;
|
||||
@@ -63,19 +65,30 @@ linkwith(const char *lnk, const char *obj, const char *libdir, int nflags)
|
||||
"%s -o %s %s%s -L%s -lfoo 2>/dev/null",
|
||||
lnk, exe, obj, junk, libdir);
|
||||
int rc = runwait(cmd);
|
||||
if (rc != 0) { unlink(exe); return rc; }
|
||||
if (rc != 0) goto cleanup;
|
||||
|
||||
FILE *f = fopen(exe, "rb");
|
||||
if (!f) return -1;
|
||||
if (!f) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
unsigned char hdr[20];
|
||||
int ok = fread(hdr, 1, sizeof hdr, f) == sizeof hdr;
|
||||
fclose(f);
|
||||
unlink(exe);
|
||||
if (!ok || memcmp(hdr, "\x7f""ELF", 4) != 0) return -1;
|
||||
if (!ok || memcmp(hdr, "\x7f""ELF", 4) != 0) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
unsigned short etype = (unsigned short)hdr[16]
|
||||
| ((unsigned short)hdr[17] << 8);
|
||||
if (etype != 2) return -1; /* ET_EXEC */
|
||||
return 0;
|
||||
if (etype != 2) rc = -1; /* ET_EXEC */
|
||||
|
||||
cleanup:
|
||||
if (unlink(exe) != 0 && errno != ENOENT) {
|
||||
perror(exe);
|
||||
if (rc == 0) rc = -1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -84,37 +97,44 @@ main(void)
|
||||
const char *bin = absbin();
|
||||
if (!bin) return 1;
|
||||
|
||||
char src[64], asmf[64], obj[64];
|
||||
char fsrc[64], fasm[64], fobj[64];
|
||||
char src[128], asmf[128], obj[128];
|
||||
char fsrc[128], fasm[128], fobj[128];
|
||||
char libdir[64], lib[128], cmd[1024];
|
||||
int pid = getpid();
|
||||
snprintf(src, sizeof src, "/tmp/wwfc_%d_m.ww", pid);
|
||||
snprintf(asmf, sizeof asmf, "/tmp/wwfc_%d_m.s", pid);
|
||||
snprintf(obj, sizeof obj, "/tmp/wwfc_%d_m.o", pid);
|
||||
snprintf(fsrc, sizeof fsrc, "/tmp/wwfc_%d_f.ww", pid);
|
||||
snprintf(fasm, sizeof fasm, "/tmp/wwfc_%d_f.s", pid);
|
||||
snprintf(fobj, sizeof fobj, "/tmp/wwfc_%d_f.o", pid);
|
||||
snprintf(libdir, sizeof libdir, "/tmp/wwfc_%d_lib", pid);
|
||||
if (mkdir(libdir, 0755) != 0) {
|
||||
perror(libdir);
|
||||
return 1;
|
||||
}
|
||||
int result = 1;
|
||||
snprintf(src, sizeof src, "%s/m.ww", libdir);
|
||||
snprintf(asmf, sizeof asmf, "%s/m.s", libdir);
|
||||
snprintf(obj, sizeof obj, "%s/m.o", libdir);
|
||||
snprintf(fsrc, sizeof fsrc, "%s/f.ww", libdir);
|
||||
snprintf(fasm, sizeof fasm, "%s/f.s", libdir);
|
||||
snprintf(fobj, sizeof fobj, "%s/f.o", libdir);
|
||||
snprintf(lib, sizeof lib, "%s/libfoo.a", libdir);
|
||||
|
||||
/* a standalone main.o (no undefs) + an unrelated archived foo.o. */
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { perror(src); goto cleanup; }
|
||||
wwtest_fputs("fn main() i32 = { return 42; };", f);
|
||||
fclose(f);
|
||||
if (fclose(f) != 0) { perror(src); goto cleanup; }
|
||||
f = fopen(fsrc, "wb");
|
||||
if (!f) { perror(fsrc); goto cleanup; }
|
||||
wwtest_fputs("export fn foo() i32 = { return 7; };", f);
|
||||
fclose(f);
|
||||
if (fclose(f) != 0) { perror(fsrc); goto cleanup; }
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s", bin, asmf, src);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "w6c main failed\n"); return 1; }
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "w6c main failed\n"); goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s", bin, obj, asmf);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "w6a main failed\n"); return 1; }
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "w6a main failed\n"); goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s", bin, fasm, fsrc);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "w6c foo failed\n"); return 1; }
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "w6c foo failed\n"); goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s", bin, fobj, fasm);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "w6a foo failed\n"); return 1; }
|
||||
snprintf(cmd, sizeof cmd, "mkdir -p %s && ar rcs %s %s", libdir, lib, fobj);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "ar failed\n"); return 1; }
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "w6a foo failed\n"); goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "ar rcs %s %s", lib, fobj);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "ar failed\n"); goto cleanup; }
|
||||
|
||||
int counts[] = { 1, 64, 65, 100, 128 };
|
||||
int fail = 0;
|
||||
@@ -138,15 +158,50 @@ main(void)
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s %s %s %s %s %s %s",
|
||||
src, asmf, obj, fsrc, fasm, fobj, libdir);
|
||||
(void)runwait(cmd);
|
||||
|
||||
if (fail) {
|
||||
fprintf(stderr, "w6l_manyflags: %d failure(s)\n", fail);
|
||||
return 1;
|
||||
goto cleanup;
|
||||
}
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
{
|
||||
int cleanfail = 0;
|
||||
if (unlink(src) != 0 && errno != ENOENT) {
|
||||
perror(src); cleanfail = 1;
|
||||
}
|
||||
if (unlink(asmf) != 0 && errno != ENOENT) {
|
||||
perror(asmf); cleanfail = 1;
|
||||
}
|
||||
if (unlink(obj) != 0 && errno != ENOENT) {
|
||||
perror(obj); cleanfail = 1;
|
||||
}
|
||||
if (unlink(fsrc) != 0 && errno != ENOENT) {
|
||||
perror(fsrc); cleanfail = 1;
|
||||
}
|
||||
if (unlink(fasm) != 0 && errno != ENOENT) {
|
||||
perror(fasm); cleanfail = 1;
|
||||
}
|
||||
if (unlink(fobj) != 0 && errno != ENOENT) {
|
||||
perror(fobj); cleanfail = 1;
|
||||
}
|
||||
if (unlink(lib) != 0 && errno != ENOENT) {
|
||||
perror(lib); cleanfail = 1;
|
||||
}
|
||||
char exe[128];
|
||||
snprintf(exe, sizeof exe, "%s/wwfc_x", libdir);
|
||||
if (unlink(exe) != 0 && errno != ENOENT) {
|
||||
perror(exe);
|
||||
cleanfail = 1;
|
||||
}
|
||||
if (rmdir(libdir) != 0) {
|
||||
perror(libdir);
|
||||
cleanfail = 1;
|
||||
}
|
||||
if (cleanfail && result == 0) result = 1;
|
||||
}
|
||||
if (result != 0) return result;
|
||||
printf("w6l_manyflags: -L past slot 64 honoured by both stages "
|
||||
"(1/64/65/100/128 flags)\n");
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user