9\10\11\12 Finished.

This commit is contained in:
Saturneric 2021-01-11 18:00:36 +08:00
parent c9fbf46d4b
commit e29fa7be44
16 changed files with 671 additions and 0 deletions

16
10/signal/pause.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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;
}

View 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
View 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
View 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
View 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;
}