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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 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@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux