Skip to content

Commit f4bd37d

Browse files
committed
Clean unused artifacts and fix tests
1 parent 234d12e commit f4bd37d

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

src/posix.zig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,26 @@ fn waitForPidStatus(pid: PopenPid) c_int {
365365
}
366366
}
367367

368+
fn drainWindowsPipeStream(stream: *c.FILE) void {
369+
if (comptime builtin.os.tag != .windows) return;
370+
const fd = fileno(stream);
371+
if (fd < 0) return;
372+
const status_flags = winfd.getStatusFlags(fd) orelse return;
373+
if ((status_flags & 0x3) != c.O_RDONLY) return;
374+
375+
var buf: [256]u8 = undefined;
376+
while (true) {
377+
var amt_read: u32 = 0;
378+
if (std.os.windows.kernel32.ReadFile(stream.fd.?, &buf, buf.len, &amt_read, null) == 0) {
379+
switch (std.os.windows.kernel32.GetLastError()) {
380+
.BROKEN_PIPE, .HANDLE_EOF => break,
381+
else => break,
382+
}
383+
}
384+
if (amt_read == 0) break;
385+
}
386+
}
387+
368388
fn populateLinuxExecEnviron(buf: []u8, ptrs: [*:null]?[*:0]u8, ptr_cap: usize) bool {
369389
if (comptime builtin.os.tag != .linux) return false;
370390
var file = std.fs.openFileAbsolute("/proc/self/environ", .{}) catch return false;
@@ -1138,6 +1158,13 @@ export fn pclose(stream: *c.FILE) callconv(.c) c_int {
11381158
c.errno = c.EINVAL;
11391159
return -1;
11401160
};
1161+
if (builtin.os.tag == .windows) {
1162+
// Native Windows shells can surface a broken-pipe exit status if the
1163+
// parent closes the read end before draining the child's final writes.
1164+
// Drain any unread pipe data first so `_pclose`-style callers get the
1165+
// child exit code rather than an artifact of our teardown ordering.
1166+
drainWindowsPipeStream(stream);
1167+
}
11411168
const close_rc = c.fclose(stream);
11421169
const wait_rc = waitForPidStatus(pid);
11431170
if (wait_rc == -1) return -1;

test/posix_extensive.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,15 @@ int main(int argc, char *argv[])
350350
expect(0 == pclose(p));
351351
}
352352

353+
{
354+
FILE *p = popen("for /l %i in (1,1,1024) do @<nul set /p =x", "r");
355+
char buf[8];
356+
expect(p != NULL);
357+
expect(NULL != fgets(buf, sizeof(buf), p));
358+
expect(buf[0] == 'x');
359+
expect(0 == pclose(p));
360+
}
361+
353362
{
354363
FILE *p = popen("exit /b 5", "r");
355364
expect(p != NULL);

0 commit comments

Comments
 (0)