Skip to content

Instantly share code, notes, and snippets.

@vstk
Created April 2, 2016 18:21
Show Gist options
  • Save vstk/2fd2015948a2c8443eb28b5110db0a72 to your computer and use it in GitHub Desktop.
Save vstk/2fd2015948a2c8443eb28b5110db0a72 to your computer and use it in GitHub Desktop.
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <poll.h>
void test_exec_fork()
{
pid_t pid;
int status;
int out_pipe[2];
int err_pipe[2];
if (pipe(out_pipe) || pipe(err_pipe)) {
perror("ERROR: pipe()");
return;
}
pid = vfork();
if (pid == 0) {
close(out_pipe[0]);
close(err_pipe[0]);
// while loop because of posible signal interrupt
while ((dup2(out_pipe[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
while ((dup2(err_pipe[1], STDERR_FILENO) == -1) && (errno == EINTR)) {}
close(out_pipe[1]);
close(err_pipe[1]);
char *command = "ping -c 5 localhost";
char *argv[] = { "sh", "-c", command, NULL };
execve("/bin/sh", argv, NULL);
perror("execve() failure");
_exit(1);
}
if(pid < 0) {
perror("vfork() failure");
return;
}
close(out_pipe[1]);
close(err_pipe[1]);
printf("Forked PID: %d, waiting...\n", pid);
char buffer[1024];
struct pollfd plist[] = { { out_pipe[0], POLLIN }, { err_pipe[0], POLLIN } };
while (1) {
if (poll(plist, 2, -1) < 0) {
perror("fork failure!");
break;
}
if (plist[0].revents & POLLIN) {
int n = read(out_pipe[0], buffer, sizeof(buffer)-1);
buffer[n] = 0;
printf(">OUT> %s", buffer);
}
else if (plist[1].revents & POLLIN) {
int n = read(err_pipe[0], buffer, sizeof(buffer)-1);
buffer[n] = 0;
printf(">ERR> %s", buffer);
}
else {
break;
}
}
close(out_pipe[0]);
close(err_pipe[0]);
pid_t rpid = waitpid(pid, &status, 0);
printf("Done: %d: %d\n", rpid, status);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment