diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-03-11 22:25:15 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-03-11 22:25:15 -0700 |
commit | 5382f4a6aa4a38c5f2f229f79bee55dfcb3843fc (patch) | |
tree | 7ae07decfd27a60929b2168bcd42382a84101ef1 | |
parent | d5915cf610b71691a95f5af3fe09848adb3f0d3d (diff) | |
download | txr-5382f4a6aa4a38c5f2f229f79bee55dfcb3843fc.tar.gz txr-5382f4a6aa4a38c5f2f229f79bee55dfcb3843fc.tar.bz2 txr-5382f4a6aa4a38c5f2f229f79bee55dfcb3843fc.zip |
* configure: new test for fcntl.
* stream.c (open_process): Fixed off-by one erroneous value of nargs,
causing memory leak of one string. Fixed memory leak on fork failure.
Fixed a deadlock that can occur in the pipe close function when
multiple pipes are in existence. This is fixed by setting the
FD_CLOEXEC flag on the pipe file descriptor. Without this, one child
process can hold another's pipe open, causing that other one not to
terminate when we're trying to shut it down, resulting in that child
blocked on a write, while we block on waitpid.
-rw-r--r-- | ChangeLog | 13 | ||||
-rwxr-xr-x | configure | 24 | ||||
-rw-r--r-- | stream.c | 12 |
3 files changed, 48 insertions, 1 deletions
@@ -1,5 +1,18 @@ 2014-03-11 Kaz Kylheku <kaz@kylheku.com> + * configure: new test for fcntl. + + * stream.c (open_process): Fixed off-by one erroneous value of nargs, + causing memory leak of one string. Fixed memory leak on fork failure. + Fixed a deadlock that can occur in the pipe close function when + multiple pipes are in existence. This is fixed by setting the + FD_CLOEXEC flag on the pipe file descriptor. Without this, one child + process can hold another's pipe open, causing that other one not to + terminate when we're trying to shut it down, resulting in that child + blocked on a write, while we block on waitpid. + +2014-03-11 Kaz Kylheku <kaz@kylheku.com> + * stream.c (open_process): In the event of fdopen failure, kill the child process less abruptly by hitting it with SIGINT and SIGTERM, rather than with SIGKILL. Also, collect the child @@ -1330,6 +1330,30 @@ else fi # +# fcntl +# + +printf "Checking for POSIX fcntl ... " + +cat > conftest.c <<! +#include "config.h" +#include <fcntl.h> + +int main(int argc, char **argv) +{ + int err = fcntl(0, F_SETFD, FD_CLOEXEC); + return 0; +} +! + +if conftest ; then + printf "yes\n" + printf "#define HAVE_FCNTL_H 1\n" >> config.h +else + printf "no\n" +fi + +# # Check for fields inside struct tm # @@ -38,6 +38,9 @@ #if HAVE_UNISTD_H #include <unistd.h> #endif +#if HAVE_FCNTL_H +#include <fcntl.h> +#endif #include <float.h> #if HAVE_SYS_WAIT #include <sys/wait.h> @@ -2131,7 +2134,7 @@ val open_process(val name, val mode_str, val args) int i, nargs; args = default_bool_arg(args); - nargs = c_num(length(args)); + nargs = c_num(length(args)) + 1; if (pipe(fd) == -1) { uw_throwf(file_error_s, lit("opening pipe ~a, pipe syscall failed: ~a/~s"), @@ -2151,6 +2154,9 @@ val open_process(val name, val mode_str, val args) pid = fork(); if (pid == -1) { + for (i = 0; i < nargs; i++) + free(argv[i]); + free(argv); uw_throwf(file_error_s, lit("opening pipe ~a, fork syscall failed: ~a/~s"), name, num(errno), string_utf8(strerror(errno)), nao); } @@ -2187,6 +2193,10 @@ val open_process(val name, val mode_str, val args) free(argv[i]); free(argv); +#if HAVE_FCNTL_H + fcntl(whichfd, F_SETFD, FD_CLOEXEC); +#endif + if ((f = fdopen(whichfd, utf8mode)) == 0) { int status; kill(pid, SIGINT); |