OLD | NEW |
(Empty) | |
| 1 /* I built this with "gcc -lutil test.c -otest" */ |
| 2 #include <sys/types.h> /* include this before any other sys headers */ |
| 3 #include <sys/wait.h> /* header for waitpid() and various macros */ |
| 4 #include <signal.h> /* header for signal functions */ |
| 5 #include <stdio.h> /* header for fprintf() */ |
| 6 #include <unistd.h> /* header for fork() */ |
| 7 #ifdef LINUX |
| 8 #include <pty.h> |
| 9 #else |
| 10 #include <util.h> /* header for forkpty, compile with -lutil */ |
| 11 #endif |
| 12 |
| 13 void sig_chld(int); /* prototype for our SIGCHLD handler */ |
| 14 |
| 15 int main() |
| 16 { |
| 17 struct sigaction act; |
| 18 int pid; |
| 19 int fdm; |
| 20 char slave_name [20]; |
| 21 |
| 22 |
| 23 /* Assign sig_chld as our SIGCHLD handler. |
| 24 We don't want to block any other signals in this example |
| 25 We're only interested in children that have terminated, not ones |
| 26 which have been stopped (eg user pressing control-Z at terminal). |
| 27 Finally, make these values effective. If we were writing a real |
| 28 application, we would save the old value instead of passing NULL. |
| 29 */ |
| 30 act.sa_handler = sig_chld; |
| 31 sigemptyset(&act.sa_mask); |
| 32 act.sa_flags = SA_NOCLDSTOP; |
| 33 if (sigaction(SIGCHLD, &act, NULL) < 0) |
| 34 { |
| 35 fprintf(stderr, "sigaction failed\n"); |
| 36 return 1; |
| 37 } |
| 38 |
| 39 /* Do the Fork thing. |
| 40 */ |
| 41 pid = forkpty (&fdm, slave_name, NULL, NULL); |
| 42 /* pid = fork(); */ |
| 43 |
| 44 switch (pid) |
| 45 { |
| 46 case -1: |
| 47 fprintf(stderr, "fork failed\n"); |
| 48 return 1; |
| 49 break; |
| 50 |
| 51 case 0: /* Child process. */ |
| 52 printf ("This child output will cause trouble.\n"); |
| 53 _exit(7); |
| 54 break; |
| 55 |
| 56 default: /* Parent process. */ |
| 57 sleep(1); |
| 58 printf ("Child pid: %d\n", pid); |
| 59 sleep(10); /* let child finish -- crappy way to avoid race. */ |
| 60 break; |
| 61 } |
| 62 |
| 63 return 0; |
| 64 } |
| 65 |
| 66 void sig_chld(int signo) |
| 67 { |
| 68 int status, wpid, child_val; |
| 69 |
| 70 printf ("In sig_chld signal handler.\n"); |
| 71 |
| 72 /* Wait for any child without blocking */ |
| 73 wpid = waitpid (-1, & status, WNOHANG); |
| 74 printf ("\tWaitpid found status for pid: %d\n", wpid); |
| 75 if (wpid < 0) |
| 76 { |
| 77 fprintf(stderr, "\twaitpid failed\n"); |
| 78 return; |
| 79 } |
| 80 printf("\tWaitpid status: %d\n", status); |
| 81 |
| 82 if (WIFEXITED(status)) /* did child exit normally? */ |
| 83 { |
| 84 child_val = WEXITSTATUS(status); |
| 85 printf("\tchild exited normally with status %d\n", child_val); |
| 86 } |
| 87 printf ("End of sig_chld.\n"); |
| 88 } |
| 89 |
| 90 |
OLD | NEW |