>From 88b0663e5388b464a0b88080c8449fe94ebbdba3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 27 Aug 2019 12:44:33 +0100 Subject: [PATCH] sh: Remove assert and replace with smarter file descriptor duplication. $ nbdsh -c 'h.connect_command (["nbdkit", "sh", "/tmp/min.sh", "-s", "--exit-with-parent"])' -c 'print ("%r" % h.get_size())' 1048576 nbdkit: call.c:155: call3: Assertion `in_fd[0] > STDERR_FILENO && in_fd[1] > STDERR_FILENO && out_fd[0] > STDERR_FILENO && out_fd[1] > STDERR_FILENO && err_fd[0] > STDERR_FILENO && err_fd[1] > STDERR_FILENO' failed. On the shutdown path when nbdkit -s is used stdin/stdout (connected to the client socket) have been closed already, so the assertion is obviously not valid. Remove the assertion and replace it with smarter file descriptor duplication. Fixes commit b5b38e4e585ec5f22ea86feba6260b314f803559. --- plugins/sh/call.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/plugins/sh/call.c b/plugins/sh/call.c index b86e7c9..c1245cd 100644 --- a/plugins/sh/call.c +++ b/plugins/sh/call.c @@ -148,14 +148,6 @@ call3 (const char *wbuf, size_t wbuflen, /* sent to stdin */ } #endif - /* Ensure that stdin/out/err of the current process were not empty - * before we started creating pipes (otherwise, the close and dup2 - * calls below become more complex to juggle fds around correctly). - */ - assert (in_fd[0] > STDERR_FILENO && in_fd[1] > STDERR_FILENO && - out_fd[0] > STDERR_FILENO && out_fd[1] > STDERR_FILENO && - err_fd[0] > STDERR_FILENO && err_fd[1] > STDERR_FILENO); - pid = fork (); if (pid == -1) { nbdkit_error ("%s: fork: %m", script); @@ -166,12 +158,18 @@ call3 (const char *wbuf, size_t wbuflen, /* sent to stdin */ close (in_fd[1]); close (out_fd[0]); close (err_fd[0]); - dup2 (in_fd[0], 0); - dup2 (out_fd[1], 1); - dup2 (err_fd[1], 2); - close (in_fd[0]); - close (out_fd[1]); - close (err_fd[1]); + if (in_fd[0] != STDIN_FILENO) { + dup2 (in_fd[0], STDIN_FILENO); + close (in_fd[0]); + } + if (out_fd[1] != STDOUT_FILENO) { + dup2 (out_fd[1], STDOUT_FILENO); + close (out_fd[1]); + } + if (err_fd[1] != STDERR_FILENO) { + dup2 (err_fd[1], STDERR_FILENO); + close (err_fd[1]); + } /* Restore SIGPIPE back to SIG_DFL, since shell can't undo SIG_IGN */ signal (SIGPIPE, SIG_DFL); -- 2.22.0