Skip to content

Instantly share code, notes, and snippets.

@dontlaugh
Created October 18, 2018 03:02
Show Gist options
  • Save dontlaugh/56d91714eebbec28392fa48ee1d5ec3f to your computer and use it in GitHub Desktop.
Save dontlaugh/56d91714eebbec28392fa48ee1d5ec3f to your computer and use it in GitHub Desktop.
unnamed pipe between parent and child
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
void capture_output(char * cmd, char ** outstr, int max_lines)
{
// we must pass a len 2 array to pipe
int pipefds[2];
// fork() returns a process id
int pid;
FILE* output;
char line[256];
char * tempstr;
pipe(pipefds);
pid = fork();
if (pid == 0) {
// child process
// close the read half, child will only write.
close(pipefds[0]);
// redirect both streams to the write half of the pipe.
dup2(pipefds[1], STDOUT_FILENO);
dup2(pipefds[1], STDERR_FILENO);
// we MUST pass a null pointer to signal the end of our variadic args.
execl(cmd, cmd, "branch", "current", (char*) NULL);
} else {
// parent process
// we HANG FOREVER if we don't close the write half of the pipe. Dang!
char * splitted;
close(pipefds[1]);
output = fdopen(pipefds[0], "r");
for (int i = 0; i <= max_lines; i++) {
if (fgets(line, sizeof(line), output)) {
char * brkb;
if ((splitted = strtok_r(line, "\n", &brkb)))
tempstr = splitted;
}
}
// this will only be reached by the parent
int status;
if (waitpid(pid, &status, 0) == -1)
asprintf(outstr, "%s ", "internal error");
if (status == 0)
asprintf(outstr, "%s ", tempstr);
}
}
int main(int argc, char const *argv[])
{
// asprintf will extend this for us
char * prompt = NULL;
char cwd[1024];
capture_output("/usr/local/bin/fossil", &prompt, 1);
// Get pwd
getcwd(cwd, sizeof(cwd));
printf("%s$", prompt);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment