diff --git a/libguile/posix.c b/libguile/posix.c index 3adc743c4..2d55d985c 100644 --- a/libguile/posix.c +++ b/libguile/posix.c @@ -1388,11 +1388,27 @@ do_spawn (char *exec_file, char **exec_argv, char **exec_env, } /* Move the fds out of the way, so that duplicate fds or fds equal - to 0, 1, 2 don't trample each other */ + to 0, 1, 2 don't trample each other. Since 'system*' might give + us -1 for IN, OUT, or ERR, open /dev/null when that's the case. */ + + if (in < 0) + posix_spawn_file_actions_addopen (&actions, fd_slot[0], + "/dev/null", O_RDONLY | O_CLOEXEC, 0); + else + posix_spawn_file_actions_adddup2 (&actions, in, fd_slot[0]); + + if (out < 0) + posix_spawn_file_actions_addopen (&actions, fd_slot[1], + "/dev/null", O_WRONLY | O_CLOEXEC, 0); + else + posix_spawn_file_actions_adddup2 (&actions, out, fd_slot[1]); + + if (err < 0) + posix_spawn_file_actions_addopen (&actions, fd_slot[2], + "/dev/null", O_WRONLY | O_CLOEXEC, 0); + else + posix_spawn_file_actions_adddup2 (&actions, err, fd_slot[2]); - posix_spawn_file_actions_adddup2 (&actions, in, fd_slot[0]); - posix_spawn_file_actions_adddup2 (&actions, out, fd_slot[1]); - posix_spawn_file_actions_adddup2 (&actions, err, fd_slot[2]); posix_spawn_file_actions_adddup2 (&actions, fd_slot[0], 0); posix_spawn_file_actions_adddup2 (&actions, fd_slot[1], 1); posix_spawn_file_actions_adddup2 (&actions, fd_slot[2], 2); diff --git a/test-suite/tests/posix.test b/test-suite/tests/posix.test index d5cf47cda..18dad8902 100644 --- a/test-suite/tests/posix.test +++ b/test-suite/tests/posix.test @@ -374,7 +374,17 @@ (system* "sh" "-c" "echo bong >&2")))))))) (and (zero? (status:exit-val status)) - (call-with-input-file file get-string-all))))) + (call-with-input-file file get-string-all)))) + + (pass-if-equal "https://bugs.gnu.org/63024" + 0 + (if (file-exists? "/proc/self/fd/0") ;on GNU/Linux? + (parameterize ((current-output-port (%make-void-port "w0"))) + (system* "guile" "-c" + (object->string + '(exit (string=? "/dev/null" + (readlink "/proc/self/fd/1")))))) + (throw 'unresolved)))) ;; ;; spawn