summaryrefslogtreecommitdiffstats
path: root/usr.bin/make/job.c
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2005-05-10 13:18:58 +0000
committerharti <harti@FreeBSD.org>2005-05-10 13:18:58 +0000
commita521f4fbfdded78ae8f8cb02085c252293975ca6 (patch)
tree0f0b7bb7b8694f1b5a99997b97103451a561847d /usr.bin/make/job.c
parent67950e3bcf0fc3b0a3cce07d5ffac3c41c4e7145 (diff)
downloadFreeBSD-src-a521f4fbfdded78ae8f8cb02085c252293975ca6.zip
FreeBSD-src-a521f4fbfdded78ae8f8cb02085c252293975ca6.tar.gz
Move Cmd_Exec() from main.c to job.c and fix its prototype. This
results in a warning that will go away soon. Patch: 7.198 Submitted by: Max Okumoto <okumoto@ucsd.edu>
Diffstat (limited to 'usr.bin/make/job.c')
-rw-r--r--usr.bin/make/job.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index ba2af78..6bf2427 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -2851,3 +2851,113 @@ JobRestartJobs(void)
JobRestart(job);
}
}
+
+/**
+ * Cmd_Exec
+ * Execute the command in cmd, and return the output of that command
+ * in a string.
+ *
+ * Results:
+ * A string containing the output of the command, or the empty string
+ * If error is not NULL, it contains the reason for the command failure
+ *
+ * Side Effects:
+ * The string must be freed by the caller.
+ */
+Buffer *
+Cmd_Exec(const char *cmd, const char **error)
+{
+ int fds[2]; /* Pipe streams */
+ int cpid; /* Child PID */
+ int pid; /* PID from wait() */
+ int status; /* command exit status */
+ Buffer *buf; /* buffer to store the result */
+ ssize_t rcnt;
+
+ *error = NULL;
+ buf = Buf_Init(0);
+
+ if (shellPath == NULL)
+ Shell_Init();
+ /*
+ * Open a pipe for fetching its output
+ */
+ if (pipe(fds) == -1) {
+ *error = "Couldn't create pipe for \"%s\"";
+ return (buf);
+ }
+
+ /*
+ * Fork
+ */
+ switch (cpid = vfork()) {
+ case 0:
+ /*
+ * Close input side of pipe
+ */
+ close(fds[0]);
+
+ /*
+ * Duplicate the output stream to the shell's output, then
+ * shut the extra thing down. Note we don't fetch the error
+ * stream...why not? Why?
+ */
+ dup2(fds[1], 1);
+ close(fds[1]);
+
+ {
+ char *args[4];
+
+ /* Set up arguments for shell */
+ args[0] = shellName;
+ args[1] = "-c";
+ args[2] = cmd;
+ args[3] = NULL;
+
+ execv(shellPath, args);
+ _exit(1);
+ /*NOTREACHED*/
+ }
+
+ case -1:
+ *error = "Couldn't exec \"%s\"";
+ return (buf);
+
+ default:
+ /*
+ * No need for the writing half
+ */
+ close(fds[1]);
+
+ do {
+ char result[BUFSIZ];
+
+ rcnt = read(fds[0], result, sizeof(result));
+ if (rcnt != -1)
+ Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result);
+ } while (rcnt > 0 || (rcnt == -1 && errno == EINTR));
+
+ if (rcnt == -1)
+ *error = "Error reading shell's output for \"%s\"";
+
+ /*
+ * Close the input side of the pipe.
+ */
+ close(fds[0]);
+
+ /*
+ * Wait for the process to exit.
+ */
+ while (((pid = wait(&status)) != cpid) && (pid >= 0))
+ continue;
+
+ if (status)
+ *error = "\"%s\" returned non-zero status";
+
+ Buf_StripNewlines(buf);
+
+ break;
+ }
+ return (buf);
+}
+
OpenPOWER on IntegriCloud