Created
October 2, 2012 15:00
-
-
Save miikka/3819839 to your computer and use it in GitHub Desktop.
Capturing the output of an external program in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
int my_popen(char *cmd, FILE *handles[2]) { | |
/* Naming convention: the child's input and output */ | |
int input[2]; | |
int output[2]; | |
pipe(input); | |
pipe(output); | |
pid_t child_pid = fork(); | |
if (child_pid == -1) { | |
for (int i = 0; i < 2; i++) { | |
close(input[i]); close(output[i]); | |
} | |
return -1; | |
} else if (!child_pid) { | |
/* Redirect stdin and stdout to our pipes. */ | |
dup2(input[0], STDIN_FILENO); | |
dup2(output[1], STDOUT_FILENO); | |
/* The pipes have to be closed by both the parent and the child. Closing a | |
* file descriptor in the child does not close it in the parent and vice | |
* versa, even though the child inherits the parent's file descriptors. | |
* Hence we close the parents ends of pipes here in the child. */ | |
close(input[1]); | |
close(output[0]); | |
/* The second parameter of execlp is argv[0] for the executed program, | |
* hence there's "sh" twice. */ | |
execlp("sh", "sh", "-c", cmd, (char*)NULL); | |
_exit(127); | |
} else { | |
/* Close the child's ends of pipes. */ | |
close(input[0]); | |
close(output[1]); | |
} | |
/* For the handles, we use the same convention as pipe(2): handles[1] is the | |
* write end and handles[0] the read end. */ | |
handles[0] = fdopen(output[0], "r"); | |
handles[1] = fdopen(input[1], "w"); | |
return 0; | |
} | |
int main(void) { | |
FILE *handles[3]; | |
char buffer[1024]; | |
if (my_popen("pandoc", handles) == -1) { perror("my_popen"); return -1; } | |
fputs("I don't to *emphasize* my role.", handles[1]); | |
fclose(handles[1]); | |
fread(buffer, 1, 1024, handles[0]); | |
fclose(handles[0]); | |
puts("pandoc says:"); | |
puts(buffer); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment