9\10\11\12 Finished.
This commit is contained in:
parent
c9fbf46d4b
commit
e29fa7be44
16
10/signal/pause.c
Normal file
16
10/signal/pause.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void sig_alarm(int signo) {
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
if(signal(SIGALRM, sig_alarm) == SIG_ERR)
|
||||
return -1;
|
||||
|
||||
alarm(3);
|
||||
pause();
|
||||
return alarm(0);
|
||||
}
|
20
10/signal/pause2.c
Normal file
20
10/signal/pause2.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static jmp_buf env_alrm;
|
||||
|
||||
static void sig_alrm(int signo) {
|
||||
longjmp(env_alrm, 1);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
if(signal(SIGALRM, sig_alrm) == SIG_ERR)
|
||||
return -1;
|
||||
if(setjmp(env_alrm) == 0) {
|
||||
alarm(3);
|
||||
pause();
|
||||
}
|
||||
return 0;
|
||||
}
|
50
10/signal/pending.c
Normal file
50
10/signal/pending.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void sig_quit(int);
|
||||
|
||||
int main(void) {
|
||||
sigset_t newmask, oldmask, pendmask;
|
||||
|
||||
if (signal(SIGQUIT, sig_quit) == SIG_ERR) {
|
||||
printf("can't catch SIGQUIT\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sigemptyset(&newmask);
|
||||
sigaddset(&newmask, SIGQUIT);
|
||||
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
|
||||
printf("SIG_BLOCK error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sleep(5);
|
||||
|
||||
if (sigpending(&pendmask) < 0) {
|
||||
printf("sigpeding error\n");
|
||||
return -1;
|
||||
}
|
||||
if (sigismember(&pendmask, SIGQUIT)) {
|
||||
printf("\nSIGQUIT pending\n");
|
||||
}
|
||||
|
||||
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
|
||||
printf("SIG_SETMASK error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("SIGQUIT unblocked\n");
|
||||
|
||||
sleep(5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sig_quit(int signo) {
|
||||
printf("caught SIGQUIT\n");
|
||||
if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) {
|
||||
printf("can't reset SIGQUIT");
|
||||
}
|
||||
}
|
35
10/signal/read.c
Normal file
35
10/signal/read.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void sig_alrm(int);
|
||||
static jmp_buf env_alrm;
|
||||
|
||||
int main(void) {
|
||||
int n;
|
||||
char line[256];
|
||||
|
||||
if(signal(SIGALRM, sig_alrm) == SIG_ERR) {
|
||||
printf("signal(SIGALRM) error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(setjmp(env_alrm) != 0) {
|
||||
printf("read timeout\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
alarm(5);
|
||||
if((n = read(STDIN_FILENO, line, 256) < 0)) {
|
||||
printf("read error\n");
|
||||
return -1;
|
||||
}
|
||||
alarm(0);
|
||||
write(STDOUT_FILENO, line, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sig_alrm(int signo) {
|
||||
longjmp(env_alrm, 1);
|
||||
}
|
32
10/signal/recall.c
Normal file
32
10/signal/recall.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
|
||||
static void my_alarm(int signo) {
|
||||
struct passwd *rootptr;
|
||||
|
||||
printf("in signal handler signo = %d\n", signo);
|
||||
if ((rootptr = getpwnam("root")) == NULL) {
|
||||
printf("getpwnam(root) error");
|
||||
}
|
||||
|
||||
alarm(1);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct passwd *ptr;
|
||||
|
||||
signal(SIGALRM, my_alarm);
|
||||
alarm(1);
|
||||
|
||||
for(;;) {
|
||||
if((ptr = getpwnam("eric")) == NULL)
|
||||
printf("getpwnam(eric) error");
|
||||
if(strcmp(ptr->pw_name, "eric") != 0) {
|
||||
printf("return value corrupted, pw_name = %s\n", ptr->pw_name);
|
||||
}
|
||||
}
|
||||
}
|
34
10/signal/signal.c
Normal file
34
10/signal/signal.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include <sys/signal.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void sig_usr(int);
|
||||
|
||||
int main(void) {
|
||||
if(signal(SIGUSR1, sig_usr) == SIG_ERR) {
|
||||
printf("can't catch SIGUSR1\n");
|
||||
exit(-1);
|
||||
}
|
||||
if(signal(SIGUSR2, sig_usr) == SIG_ERR) {
|
||||
printf("can't catch SIGUSR2\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
pause();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sig_usr(int signo) {
|
||||
if(signo == SIGUSR1) {
|
||||
printf("SIGUSR1 received\n");
|
||||
}
|
||||
else if(signo == SIGUSR2) {
|
||||
printf("SIGUSR2 recieved\n");
|
||||
}
|
||||
else
|
||||
printf("error %d received", signo);
|
||||
}
|
38
10/signal/sleep.c
Normal file
38
10/signal/sleep.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
static void sig_alrm(int signo) {
|
||||
|
||||
}
|
||||
|
||||
unsigned int sleep(unsigned int seconds) {
|
||||
struct sigaction newact, oldact;
|
||||
sigset_t newmask, oldmask, suspmask;
|
||||
unsigned int unslept;
|
||||
|
||||
newact.sa_handler = sig_alrm;
|
||||
sigemptyset(&newact.sa_mask);
|
||||
newact.sa_flags = 0;
|
||||
sigaction(SIGALRM, &newact, &oldact);
|
||||
|
||||
sigemptyset(&newmask);
|
||||
sigaddset(&newmask, SIGALRM);
|
||||
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
|
||||
|
||||
alarm(seconds);
|
||||
suspmask = oldmask;
|
||||
|
||||
sigdelset(&suspmask, SIGALRM);
|
||||
sigsuspend(&suspmask);
|
||||
unslept = alarm(0);
|
||||
|
||||
sigaction(SIGALRM, &oldact, NULL);
|
||||
|
||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
return unslept;
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
return sleep(5);
|
||||
}
|
48
10/signal/suspend.c
Normal file
48
10/signal/suspend.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void sig_int(int);
|
||||
|
||||
int main(void) {
|
||||
sigset_t newmask, oldmask, waitmask;
|
||||
|
||||
printf("program start\n");
|
||||
|
||||
if(signal(SIGINT, sig_int) == SIG_ERR) {
|
||||
printf("signal(SIGINT) error\n");
|
||||
return -1;
|
||||
}
|
||||
sigemptyset(&waitmask);
|
||||
sigaddset(&waitmask, SIGUSR1);
|
||||
sigemptyset(&newmask);
|
||||
sigaddset(&newmask, SIGINT);
|
||||
|
||||
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
|
||||
printf("SIG_BLOCK error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("in critical region\n");
|
||||
|
||||
if(sigsuspend(&waitmask) != -1) {
|
||||
printf("sigsuspend error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("after return from sigsuspend\n");
|
||||
|
||||
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){
|
||||
printf("SIG_SETMASK error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("program exit\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sig_int(int signo) {
|
||||
printf("caught sigint = %d\n", signo);
|
||||
}
|
59
10/signal/system.c
Normal file
59
10/signal/system.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int system(const char *cmdstring) {
|
||||
pid_t pid;
|
||||
int status;
|
||||
struct sigaction ignore, saveintr, savequit;
|
||||
sigset_t chldmask, savemask;
|
||||
|
||||
if (cmdstring == NULL)
|
||||
return 1;
|
||||
|
||||
ignore.sa_handler = SIG_IGN;
|
||||
sigemptyset(&ignore.sa_mask);
|
||||
ignore.sa_flags = 0;
|
||||
if (sigaction(SIGINT, &ignore, &saveintr) < 0)
|
||||
return -1;
|
||||
if (sigaction(SIGQUIT, &ignore, &savequit) < 0)
|
||||
return -1;
|
||||
sigemptyset(&chldmask);
|
||||
sigaddset(&chldmask, SIGCHLD);
|
||||
if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)
|
||||
return -1;
|
||||
|
||||
if((pid = fork()) < 0) {
|
||||
status = -1;
|
||||
}
|
||||
else if (pid == 0) {
|
||||
sigaction(SIGINT, &saveintr, NULL);
|
||||
sigaction(SIGQUIT, &savequit, NULL);
|
||||
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
|
||||
_exit(127);
|
||||
}
|
||||
else {
|
||||
while (waitpid(pid, &status, 0) < 0)
|
||||
if (errno != EINTR) {
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(sigaction(SIGINT, &saveintr, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if(sigaction(SIGQUIT, &savequit, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if(sigprocmask(SIG_SETMASK, &savemask, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
return system("ls .");
|
||||
}
|
68
11/pthread/thread_clean.c
Normal file
68
11/pthread/thread_clean.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void cleanup(void *arg) {
|
||||
printf("cleanup: %s\n", (char *) arg);
|
||||
}
|
||||
|
||||
void *thr_fn1(void *arg) {
|
||||
printf("thread 1 start\n");
|
||||
pthread_cleanup_push(cleanup, (void *)"thread 1 first handler");
|
||||
pthread_cleanup_push(cleanup, (void *)"thread 1 second handler");
|
||||
|
||||
printf("thread 1 push complete\n");
|
||||
if(arg) {
|
||||
return (void *)1;
|
||||
}
|
||||
pthread_cleanup_pop(0);
|
||||
pthread_cleanup_pop(0);
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
void *thr_fn2(void *arg) {
|
||||
printf("thread 2 start\n");
|
||||
pthread_cleanup_push(cleanup, (void *)"thread 2 first handler");
|
||||
pthread_cleanup_push(cleanup, (void *)"thread 2 second handler");
|
||||
|
||||
printf("thread 2 push complete\n");
|
||||
if(arg) {
|
||||
pthread_exit((void *)2);
|
||||
}
|
||||
pthread_cleanup_pop(0);
|
||||
pthread_cleanup_pop(0);
|
||||
pthread_exit((void *)2);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int err;
|
||||
pthread_t tid1, tid2;
|
||||
void *tret;
|
||||
|
||||
err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);
|
||||
if(err != 0) {
|
||||
printf("thread 1 create error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);
|
||||
if(err != 0) {
|
||||
printf("thread 2 create error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = pthread_join(tid1, &tret);
|
||||
if(err != 0) {
|
||||
printf("thread 1 join error\n");
|
||||
return -1;
|
||||
}
|
||||
printf("thread 1 exit code %ld\n", (long)tret);
|
||||
err = pthread_join(tid2, &tret);
|
||||
if(err != 0) {
|
||||
printf("thread 2 join error\n");
|
||||
return -1;
|
||||
}
|
||||
printf("thread 2 exit code %ld\n", (long)tret);
|
||||
return 0;
|
||||
}
|
46
11/pthread/thread_exit.c
Normal file
46
11/pthread/thread_exit.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void *thr_fn1(void *arg) {
|
||||
printf("thread 1 returning\n");
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
void *thr_fn2(void *arg) {
|
||||
printf("thread 2 exiting\n");
|
||||
pthread_exit((void *)2);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int err;
|
||||
pthread_t tid1, tid2;
|
||||
void *tret;
|
||||
|
||||
err = pthread_create(&tid1, NULL, thr_fn1, NULL);
|
||||
if(err != 0) {
|
||||
printf("thread 1 create error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = pthread_create(&tid2, NULL, thr_fn2, NULL);
|
||||
if(err != 0) {
|
||||
printf("thread 2 create error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = pthread_join(tid1, &tret);
|
||||
if(err != 0) {
|
||||
printf("thread 1 join error\n");
|
||||
return -1;
|
||||
}
|
||||
printf("thread 1 exit code %ld\n", (long)tret);
|
||||
err = pthread_join(tid2, &tret);
|
||||
if(err != 0) {
|
||||
printf("thread 2 join error\n");
|
||||
return -1;
|
||||
}
|
||||
printf("thread 2 exit code %ld\n", (long)tret);
|
||||
return 0;
|
||||
}
|
33
11/pthread/thread_id.c
Normal file
33
11/pthread/thread_id.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
pthread_t ntid;
|
||||
|
||||
void printids(const char *s) {
|
||||
pid_t pid;
|
||||
pthread_t tid;
|
||||
|
||||
pid = getpid();
|
||||
tid = pthread_self();
|
||||
printf("%s pid %lu tid %lu (0x%lx)\n", s, (unsigned long) pid, (unsigned long) tid, (unsigned long) tid);
|
||||
}
|
||||
|
||||
void *thr_fn(void *arg) {
|
||||
printids("new thread:");
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int err;
|
||||
|
||||
err = pthread_create(&ntid, NULL, thr_fn, NULL);
|
||||
if(err != 0) {
|
||||
printf("create thread error\n");
|
||||
return -1;
|
||||
}
|
||||
printids("main thread:");
|
||||
sleep(1);
|
||||
return 0;
|
||||
}
|
36
11/pthread/thread_timedlock.c
Normal file
36
11/pthread/thread_timedlock.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(void) {
|
||||
int err;
|
||||
struct timespec tout;
|
||||
struct tm *tmp;
|
||||
char buf[64];
|
||||
|
||||
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_lock(&lock);
|
||||
printf("mutex is locked\n");
|
||||
clock_gettime(CLOCK_REALTIME, &tout);
|
||||
tmp = localtime(&tout.tv_sec);
|
||||
strftime(buf, sizeof(buf), "%r", tmp);
|
||||
printf("current time is %s\n", buf);
|
||||
|
||||
tout.tv_sec += 10;
|
||||
|
||||
err = pthread_mutex_timedlock(&lock, &tout);
|
||||
clock_gettime(CLOCK_REALTIME, &tout);
|
||||
tmp = localtime(&tout.tv_sec);
|
||||
strftime(buf, sizeof(buf), "%r", tmp);
|
||||
|
||||
printf("the time is now %s\n", buf);
|
||||
if(err == 0)
|
||||
printf("mutex locked again!n");
|
||||
else
|
||||
printf("can't lock mutex again: %s\n", strerror(err));
|
||||
|
||||
return 0;
|
||||
}
|
80
12/attr/atfork.c
Normal file
80
12/attr/atfork.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void prepare(void) {
|
||||
|
||||
int err;
|
||||
|
||||
printf("preparing locks...\n");
|
||||
if((err = pthread_mutex_lock(&lock1) != 0)) {
|
||||
printf("mutex lock error\n");
|
||||
}
|
||||
if((err = pthread_mutex_lock(&lock2)) != 0) {
|
||||
printf("mutex lock error\n");
|
||||
}
|
||||
}
|
||||
|
||||
void parent(void) {
|
||||
|
||||
int err;
|
||||
|
||||
printf("parent unlocking locks...\n");
|
||||
if((err = pthread_mutex_unlock(&lock1)) != 0)
|
||||
printf("mutex unlock error\n");
|
||||
if((err = pthread_mutex_unlock(&lock2)) != 0)
|
||||
printf("mutex unlock error\n");
|
||||
}
|
||||
|
||||
void child(void) {
|
||||
|
||||
int err;
|
||||
|
||||
printf("child unlocking locks...\n");
|
||||
if((err = pthread_mutex_unlock(&lock1)) != 0)
|
||||
printf("mutex unlock error\n");
|
||||
if((err = pthread_mutex_unlock(&lock2)) != 0)
|
||||
printf("mutex unlock error\n");
|
||||
}
|
||||
|
||||
void * thr_fn(void *arg) {
|
||||
printf("thread started...\n");
|
||||
pause();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int err;
|
||||
pid_t pid;
|
||||
pthread_t tid;
|
||||
|
||||
if((err = pthread_atfork(prepare, parent, child)) != 0) {
|
||||
printf("install fork handlers error\n");
|
||||
return -1;
|
||||
}
|
||||
if((err = pthread_create(&tid, NULL, thr_fn, 0)) != 0) {
|
||||
printf("create thread error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sleep(2);
|
||||
printf("parent about to fork...\n");
|
||||
|
||||
if((pid = fork()) < 0) {
|
||||
printf("fork failed\n");
|
||||
return -1;
|
||||
}
|
||||
else if (pid == 0) {
|
||||
printf("child return from fork\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
printf("parent return from fork\n");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
30
12/attr/makethread.c
Normal file
30
12/attr/makethread.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int makethread(void *(*fn)(void *), void *arg) {
|
||||
int err;
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr;
|
||||
|
||||
err = pthread_attr_init(&attr);
|
||||
if(err != 0)
|
||||
return err;
|
||||
err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
if(err == 0)
|
||||
err = pthread_create(&tid, &attr, fn, arg);
|
||||
pthread_attr_destroy(&attr);
|
||||
return err;
|
||||
}
|
||||
|
||||
void *td_fn(void *arg) {
|
||||
printf("thread executing\n");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int err = makethread(td_fn, NULL);
|
||||
sleep(3);
|
||||
return err;
|
||||
}
|
46
9/processGroup/orphan.c
Normal file
46
9/processGroup/orphan.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
static void sig_hup(int singo) {
|
||||
printf("SIGHUP received, pid = %ld, signo = %d\n", (long) getpid(), singo);
|
||||
}
|
||||
|
||||
static void pr_ids(char * name) {
|
||||
printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n",
|
||||
name, (long)getpid(), (long)getppid(), (long)getpgrp(), (long)tcgetpgrp(STDIN_FILENO));
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
char c;
|
||||
pid_t pid;
|
||||
|
||||
pr_ids("parent");
|
||||
|
||||
if((pid = fork()) < 0) {
|
||||
printf("fork error\n");
|
||||
exit(-1);
|
||||
}
|
||||
else if (pid > 0) {
|
||||
printf("parent sleep...\n");
|
||||
sleep(3);
|
||||
printf("parent exit.\n");
|
||||
}
|
||||
else {
|
||||
pr_ids("child");
|
||||
signal(SIGHUP, sig_hup);
|
||||
kill(getpid(), SIGTSTP);
|
||||
pr_ids("child2");
|
||||
if(read(STDIN_FILENO, &c, 1) != 1){
|
||||
printf("read error %d on controlling TTY\n", errno);
|
||||
exit(-1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user