Convert run_ext_program() fucntion to use fork() and exec() instead of system(), so that the caller can get stdout of the called program in addition to the return status. Signed-Off-By: Chandra Seetharaman <sekharan at us.ibm.com> --- usr/tgtd.c | 89 ++++++++++++++++++++++++++++++++++--------------------------- usr/tgtd.h | 5 +++- 2 files changed, 53 insertions(+), 41 deletions(-) Index: tgt-1.0.8/usr/tgtd.c =================================================================== --- tgt-1.0.8.orig/usr/tgtd.c +++ tgt-1.0.8/usr/tgtd.c @@ -30,8 +30,11 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <ctype.h> #include <sys/resource.h> #include <sys/epoll.h> +#include <sys/types.h> +#include <sys/wait.h> #include "list.h" #include "tgtd.h" @@ -235,67 +238,73 @@ void tgt_remove_sched_event(struct event } } -struct ext_prog_info { - void (*callback)(void *data, int result); - void *data; -}; - -static void run_ext_callback(int fd, int events, void *data) +/* strcpy, while eating multiple white spaces */ +void str_spacecpy(char **dest, const char *src) { - int ret, result; - struct ext_prog_info *ex = data; + const char *s = src; + char *d = *dest; - ret = read(fd, &result, sizeof(result)); - if (ret != sizeof(result)) { - result = -EINVAL; - eprintf("failed to get the result."); + while (*s) { + if (isspace(*s)) { + if (!*(s+1)) + break; + if (isspace(*(s+1))) { + s++; + continue; + } + } + *d++ = *s++; } - - if (ex->callback) - ex->callback(ex->data, result); - - tgt_event_del(fd); - close(fd); - free(data); + *d = '\0'; } int run_ext_program(const char *cmd, - void (*callback)(void *data, int result), void *data) + void (*callback)(void *data, int result), void *data, + char *output, int op_len) { pid_t pid; - int fds[2], ret; - struct ext_prog_info *ex; - ssize_t ignored; - - ex = zalloc(sizeof(*ex)); - if (!ex) - return -ENOMEM; + int fds[2], ret, i; + char *pos, arg[256]; + char *argv[sizeof(arg) / 2]; + + i = 0; + pos = arg; + str_spacecpy(&pos, cmd); + if (strchr(cmd, ' ')) { + while (pos != '\0') + argv[i++] = strsep(&pos, " "); + } else + argv[i++] = arg; + argv[i] = NULL; ret = pipe(fds); - if (ret < 0) { - free(ex); + if (ret < 0) return ret; - } eprintf("%d %d\n", fds[0], fds[1]); - ex->callback = callback; - ex->data = data; - - tgt_event_add(fds[0], EPOLLIN, run_ext_callback, ex); - pid = fork(); if (pid < 0) return pid; if (!pid) { - ret = system(cmd); - ignored = write(fds[1], &ret, sizeof(ret)); - return 0; + close(1); + dup(fds[1]); + close(fds[0]); + ret = execv(argv[0], argv); + exit(-1); + } else { + close(fds[1]); + waitpid(pid, &i, 0); + ret = read(fds[0], output, op_len); + if (ret < 0) + eprintf("failed to get the output from <%s>.", cmd); + + if (callback) + callback(data, WEXITSTATUS(i)); + close(fds[0]); } - close(fds[1]); - return 0; } Index: tgt-1.0.8/usr/tgtd.h =================================================================== --- tgt-1.0.8.orig/usr/tgtd.h +++ tgt-1.0.8/usr/tgtd.h @@ -335,5 +335,8 @@ struct event_data { }; int run_ext_program(const char *cmd, - void (*callback)(void *data, int result), void *data); + void (*callback)(void *data, int result), void *data, + char *output, int op_len); +#define call_program(cmd, output, len) \ + run_ext_program(cmd, NULL, NULL, output, len) #endif -- 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 |