diff options
author | harti <harti@FreeBSD.org> | 2005-05-10 13:18:58 +0000 |
---|---|---|
committer | harti <harti@FreeBSD.org> | 2005-05-10 13:18:58 +0000 |
commit | a521f4fbfdded78ae8f8cb02085c252293975ca6 (patch) | |
tree | 0f0b7bb7b8694f1b5a99997b97103451a561847d /usr.bin/make/job.c | |
parent | 67950e3bcf0fc3b0a3cce07d5ffac3c41c4e7145 (diff) | |
download | FreeBSD-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.c | 110 |
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); +} + |