diff --git a/cmd/ww/main.c b/cmd/ww/main.c index 37baccc6..51357e3b 100644 --- a/cmd/ww/main.c +++ b/cmd/ww/main.c @@ -72,7 +72,12 @@ run_test_bin(const char *bin, const char *pattern) _exit(127); } int status = 0; - waitpid(pid, &status, 0); + /* the do_run twin's EINTR discipline: an interrupted wait left + * status==0, so WIFEXITED(0)/WEXITSTATUS(0) reported a false + * test PASS. */ + pid_t got; + do { got = waitpid(pid, &status, 0); } while (got < 0 && errno == EINTR); + if (got < 0) { perror("ww: waitpid"); return -1; } if (WIFEXITED(status)) return WEXITSTATUS(status); return 1; } diff --git a/internal/wwpackage/package.ww b/internal/wwpackage/package.ww index 01c80ce0..455d847a 100644 --- a/internal/wwpackage/package.ww +++ b/internal/wwpackage/package.ww @@ -164,6 +164,22 @@ fn pkgskipspace(src: str, start: i32) i32 = { for (i < src.len && src[i] != '\n') { i += 1; }; continue; }; + // The driver's sep_skip_space (cmd/ww/main.c) also skips + // /* */ before the package clause; without this arm a source + // opening with a block comment built under ww but failed + // coordinator discovery ("invalid or missing package + // clause"). An unterminated comment runs to EOF and the + // clause parse fails loud. + if (c == '/' && i + 1 < src.len && src[i + 1] == '*') { + i += 2; + for (i + 1 < src.len + && !(src[i] == '*' && src[i + 1] == '/')) { + i += 1; + }; + if (i + 1 >= src.len) { return src.len; }; + i += 2; + continue; + }; break; }; return i; diff --git a/selfhost/cmd/ww/main.ww b/selfhost/cmd/ww/main.ww index bac5f7db..c4ca6de3 100644 --- a/selfhost/cmd/ww/main.ww +++ b/selfhost/cmd/ww/main.ww @@ -469,6 +469,14 @@ fn enumeratedir(dirpath: *u8) (**u8, i32) = { r = os.getdents64(fd, buf.ptr, 8192u64); }; os.close(fd); + // A failed directory read is an ERROR, not EOF: mid-walk it + // silently truncated the package source list, and on the first + // read it was misdiagnosed as "directory contains no WW package + // sources". -1 routes the caller's "cannot read directory" arm + // (the cstage caller mapping). + if (r < 0i64) { + return nil: **u8, -1; + }; // Insertion sort, byte-wise. n is small (≤16 in practice). let i: i32 = 1;