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

Chandra Seetharaman sekharan at us.ibm.com
Tue Sep 21 03:40:57 CEST 2010


Convert run_ext_program() function 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.

Change the name the function to call_program().

Signed-Off-By: Chandra Seetharaman <sekharan at us.ibm.com>
---
 usr/tgtd.c |   90 +++++++++++++++++++++++++++++++++----------------------------
 usr/tgtd.h |    5 ++-
 2 files changed, 52 insertions(+), 43 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,72 @@ 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)
+int call_program(const char *cmd, void (*callback)(void *data, int result),
+		void *data, char *output, int op_len, int flags)
 {
 	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
@@ -334,6 +334,7 @@ struct event_data {
 	struct list_head e_list;
 };
 
-int run_ext_program(const char *cmd,
-		    void (*callback)(void *data, int result), void *data);
+int call_program(const char *cmd,
+		    void (*callback)(void *data, int result), void *data,
+		    char *output, int op_len, int flags);
 #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