[stgt] [PATCH 1/5] Prepare run_ext_program() for getting stdout to the caller

Chandra Seetharaman sekharan at us.ibm.com
Thu Sep 2 02:45:51 CEST 2010


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



More information about the stgt mailing list