about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-06-20 14:50:29 -0400
committerRich Felker <dalias@aerifal.cx>2012-06-20 14:50:29 -0400
commit1af8c255040b3e1ba4913fd935d117490bfe8774 (patch)
tree3ae16b28fd9a6eaffa3c57793c703453bd2c1b24
parent9799560f79d37fb53d821b2f0b591a6ff260ebc3 (diff)
downloadmusl-1af8c255040b3e1ba4913fd935d117490bfe8774.tar.gz
musl-1af8c255040b3e1ba4913fd935d117490bfe8774.tar.xz
musl-1af8c255040b3e1ba4913fd935d117490bfe8774.zip
avoid cancellation in pclose
at the point pclose might receive and act on cancellation, it has
already invalidated the FILE passed to it. thus, per musl's QOI
guarantees about cancellation and resource allocation/deallocation,
it's not a candidate for cancellation.

if it were required to be a cancellation point by posix, we would have
to switch the order of deallocation, but somehow still close the pipe
in order to trigger the child process to exit. i looked into doing
this, but the logic gets ugly, and i'm not sure the semantics are
conformant, so i'd rather just leave it alone unless there's a need to
change it.
-rw-r--r--src/stdio/pclose.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/src/stdio/pclose.c b/src/stdio/pclose.c
index 7c777966..7fb76ed4 100644
--- a/src/stdio/pclose.c
+++ b/src/stdio/pclose.c
@@ -1,11 +1,12 @@
 #include "stdio_impl.h"
+#include "syscall.h"
 
 int pclose(FILE *f)
 {
-	int status;
+	int status, r;
 	pid_t pid = f->pipe_pid;
 	fclose(f);
-	while (waitpid(pid, &status, 0) == -1)
-		if (errno != EINTR) return -1;
+	while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR);
+	if (r<0) return __syscall_ret(r);
 	return status;
 }