|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/prctl.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <pthread.h>
|
|
|
|
#define TRACEPOINT_DEFINE
|
|
#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
|
|
#include "ust_pipe_and_fork.h"
|
|
|
|
void *do_thread(void *arg) {
|
|
int id = *((int *) arg);
|
|
int stdout_pipe[2];
|
|
int stderr_pipe[2];
|
|
if (pipe(stdout_pipe) || pipe(stderr_pipe)) {
|
|
printf("[Thread %d]: pipe failed\n", id);
|
|
exit(1);
|
|
} else {
|
|
fcntl(stdout_pipe[0], F_SETFD, FD_CLOEXEC);
|
|
fcntl(stdout_pipe[0], F_SETFD, FD_CLOEXEC);
|
|
}
|
|
|
|
tracepoint(taidinh, ust_pipe_and_fork, id, "Starting to fork now");
|
|
pid_t pid = fork();
|
|
if (pid < 0) {
|
|
printf("[Thread %d]: Fork failed", id);
|
|
exit(1);
|
|
}
|
|
if (pid > 0) {
|
|
//Parent
|
|
close(stdout_pipe[1]);
|
|
close(stderr_pipe[1]);
|
|
sleep(1);
|
|
close(stdout_pipe[0]);
|
|
close(stderr_pipe[0]);
|
|
int ret;
|
|
tracepoint(taidinh, ust_pipe_and_fork, id, "Waiting for child");
|
|
printf("[Thread %d]: Waiting for child\n", id);
|
|
waitpid(pid, &ret, 0);
|
|
printf("[Thread %d]: Child exit with %d\n", id, ret);
|
|
tracepoint(taidinh, ust_pipe_and_fork, id, "Child exit");
|
|
} else {
|
|
tracepoint(taidinh, ust_pipe_and_fork, id, "Child starting...");
|
|
//Child
|
|
setpgid(0, 0);
|
|
if (prctl(PR_SET_PDEATHSIG, SIGHUP, 0, 0, 0)) {
|
|
fprintf(stderr, "[Thread %d]: Failed to set PDEATHSIG, %s\n", id, strerror(errno));
|
|
}
|
|
close(1);
|
|
dup2(stdout_pipe[1], 1);
|
|
close(stdout_pipe[1]);
|
|
close(2);
|
|
dup2(stderr_pipe[1], 2);
|
|
close(stderr_pipe[1]);
|
|
|
|
char *argv[3];
|
|
argv[0] = strdup("sleep");
|
|
argv[1] = strdup("1");
|
|
argv[2] = 0;
|
|
tracepoint(taidinh, ust_pipe_and_fork, id, "excecvp now...");
|
|
execvp(argv[0], argv);
|
|
printf("[Thread %d]: Should not ended here\n", id);
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
int i;
|
|
int round = 1;
|
|
pthread_t workers[10];
|
|
int index[10];
|
|
while(1) {
|
|
printf("--------------------[ %d ]---------------------------\n", round);
|
|
printf("Creating workers\n");
|
|
for (i = 0; i < 10; i++) {
|
|
index[i] = i;
|
|
pthread_create(&workers[i], NULL, do_thread, &index[i]);
|
|
}
|
|
printf("Waiting for workers to join\n");
|
|
for (i = 0; i < 10; i++) {
|
|
pthread_join(workers[i], NULL);
|
|
printf("Worker %d joined\n", i);
|
|
}
|
|
printf("All workers joined\n");
|
|
round += 1;
|
|
printf("-----------------------------------------------------\n");
|
|
}
|
|
}
|