[stgt] [PATCH] fixes in call_program (closing pipe fds, waitpid interrupted by a signal)
Alexander Nezhinsky
alexandern at Voltaire.COM
Thu Feb 10 10:27:55 CET 2011
Some fixes in call_program():
1) if fork() fails, previously open pipe file descriptors should be closed.
2) the redirect script is invoked from a fork'ed process so tgt has to wait
for its child. Currently this is done synchronously using waitpid().
Sometimes the system call is interrupted by a signal (most probably by
a SIGCHLD signal from the very process that is being waited upon).
To overcome this, waitpid() is called repeatedly while the error code
is "Interrupted by a signal". Other reasons for failure are non-existing
process or invalid arguments, so in these cases we shall just give up.
Signed-off-by: Alexander Nezhinsky <alexandern at voltaire.com>
---
usr/tgtd.c | 32 +++++++++++++++++++++++++-------
1 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/usr/tgtd.c b/usr/tgtd.c
index c3abca8..066f46e 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -285,27 +285,45 @@ int call_program(const char *cmd, void (*callback)(void *data, int result),
argv[i] = NULL;
ret = pipe(fds);
- if (ret < 0)
+ if (ret < 0) {
+ eprintf("pipe create failed for %s, %m\n", cmd);
return ret;
+ }
- eprintf("%d %d\n", fds[0], fds[1]);
+ dprintf("%s, pipe: %d %d\n", cmd, fds[0], fds[1]);
pid = fork();
- if (pid < 0)
+ if (pid < 0) {
+ eprintf("fork failed for: %s, %m\n", cmd);
+ close(fds[0]);
+ close(fds[1]);
return pid;
+ }
if (!pid) {
close(1);
dup(fds[1]);
close(fds[0]);
- ret = execv(argv[0], argv);
+ execv(argv[0], argv);
+
+ eprintf("execv failed for: %s, %m\n", cmd);
exit(-1);
} else {
close(fds[1]);
- waitpid(pid, &i, 0);
+ do {
+ ret = waitpid(pid, &i, 0);
+ } while (ret < 0 && errno == EINTR);
+ if (ret < 0) {
+ eprintf("waitpid failed for: %s, %m\n", cmd);
+ close(fds[0]);
+ return ret;
+ }
ret = read(fds[0], output, op_len);
- if (ret < 0)
- eprintf("failed to get the output from <%s>.", cmd);
+ if (ret < 0) {
+ eprintf("failed to get the output from: %s\n", cmd);
+ close(fds[0]);
+ return ret;
+ }
if (callback)
callback(data, WEXITSTATUS(i));
--
1.6.5.5
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list