ww: driver/coordinator robustness — dirent errors, EINTR, block comments
Three same-cluster robustness holes. enumeratedir treated a failed getdents64 (r<0) as EOF: a mid-walk error silently truncated the package source list, and a first-read error was misdiagnosed as "directory contains no WW package sources" -- it now routes the caller's "cannot read directory" arm. run_test_bin's waitpid had no EINTR retry and its return was unchecked, so an interrupted wait left status==0 and reported a false test PASS (the do_run twin already retried). The coordinator's pkgskipspace now also skips /* */ before the package clause like the driver's sep_skip_space -- a source opening with a block comment built under ww but failed coordinator discovery.
This commit is contained in:
@@ -72,7 +72,12 @@ run_test_bin(const char *bin, const char *pattern)
|
|||||||
_exit(127);
|
_exit(127);
|
||||||
}
|
}
|
||||||
int status = 0;
|
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);
|
if (WIFEXITED(status)) return WEXITSTATUS(status);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,6 +164,22 @@ fn pkgskipspace(src: str, start: i32) i32 = {
|
|||||||
for (i < src.len && src[i] != '\n') { i += 1; };
|
for (i < src.len && src[i] != '\n') { i += 1; };
|
||||||
continue;
|
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;
|
break;
|
||||||
};
|
};
|
||||||
return i;
|
return i;
|
||||||
|
|||||||
@@ -469,6 +469,14 @@ fn enumeratedir(dirpath: *u8) (**u8, i32) = {
|
|||||||
r = os.getdents64(fd, buf.ptr, 8192u64);
|
r = os.getdents64(fd, buf.ptr, 8192u64);
|
||||||
};
|
};
|
||||||
os.close(fd);
|
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).
|
// Insertion sort, byte-wise. n is small (≤16 in practice).
|
||||||
let i: i32 = 1;
|
let i: i32 = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user