Hello, I'm trying to understand how pipes work when terminating a forked process. It seems when sending kill to the forked process, connected pipes don't always break. At least a subsequent write might work. Is it possible to make it reliably fail anyway or is it necessary to close the file descriptors from the calling process?
#include <u.h> #include <libc.h> #include <stdio.h> void sendnote(int cpid) { int fd; char fn[20], buf[20]; sprintf(fn, "/proc/%d/note", cpid); if ((fd = open(fn, OWRITE)) <= 0) { printf("open %s\n", fd); } if (write(fd, "kill", 5) == 0) { printf("write error\n"); } close(fd); return; } int main() { int cpid, infd[2], outfd[2], n; char outbuf[20], inbuf[20]; char *args[] = {"/bin/cat", NULL}; pipe(infd); pipe(outfd); if ((cpid = fork()) != 0) { close(infd[1]); close(outfd[1]); n = write(infd[0], "test", 4); printf("check process: wrote %d bytes\n", n); sendnote(cpid); // close(infd[0]); // <--- uncomment to make write fail // close(outfd[0]); n = write(infd[0], "test2", 5); printf("write: wrote %d bytes\n", n); n = read(outfd[0], outbuf, 20); printf("outbuf=%s (n=%d)\n", outbuf, n); wait(); return 0; } dup(infd[1], 0); close(infd[0]); close(infd[1]); dup(outfd[1], 1); close(outfd[0]); close(outfd[1]); exec("/bin/cat", args); return 0; } Will output: check process: wrote 4 bytes write: wrote 5 bytes outbuf=test (n=4) 6.out 82435: main Closing the FDs after sending the note: check process: wrote 4 bytes write: wrote -1 bytes outbuf= (n=-1) 6.out 82423: main On the other hand instead of closing just adding sleep(1) after sendnote() produces: check process: wrote 4 bytes 6.out 82595: sys: write on closed pipe pc=0x202603 (That's more or less also reproducing a part of Go's os/exec TestContextCancel) Greetings, Philip ------------------------------------------ 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/T3392001a02ee7ec8-Ma261d9fb098775daa526c6b3 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription