416f07ca1fe8236679925868c3dceff14b1bc407
[openafs.git] / tests / opr / softsig-helper.c
1 /*
2  * Copyright (c) 2012 Your File System Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 /* A test helper for the softsig code. This just sits and reports what signals
26  * it has received.
27  */
28
29 #include <afsconfig.h>
30 #include <afs/param.h>
31
32 #include <roken.h>
33 #include <pthread.h>
34 #include <sys/mman.h>
35
36 #include <afs/opr.h>
37 #include <opr/softsig.h>
38
39 #define SIGTABLEENTRY(name)     { #name, SIG##name }
40
41 static struct sigtable {
42         char *name;
43         int signo;
44 } sigtable[] = {
45         SIGTABLEENTRY(INT),
46         SIGTABLEENTRY(HUP),
47         SIGTABLEENTRY(QUIT),
48         SIGTABLEENTRY(ALRM),
49         SIGTABLEENTRY(TERM),
50         SIGTABLEENTRY(TSTP),
51         SIGTABLEENTRY(USR1),
52         SIGTABLEENTRY(USR2)
53         };
54
55 static char *signame(int signo) {
56     int i;
57
58     for (i = 0; i < sizeof(sigtable) / sizeof(sigtable[0]); ++i) {
59         if (sigtable[i].signo == signo) {
60             return sigtable[i].name;
61         }
62     }
63
64     return "UNK";
65 }
66
67 static void
68 handler(int signal) {
69     printf("Received %s\n", signame(signal));
70
71     fflush(stdout);
72 }
73
74 static void *
75 mythread(void *arg) {
76     while (1) {
77         sleep(60);
78     }
79     return NULL;
80 }
81
82 static void *
83 crashingThread(void *arg) {
84     *(char *)1 = 'a';  /* raises SIGSEGV */
85     return NULL; /* Ha! */
86 }
87
88 static void *
89 thrownUnderTheBusThread(void *arg) {
90     char *path = arg;
91     int fd = open(path, O_CREAT | O_APPEND, 0660);
92     char *m = mmap(NULL, 10, PROT_WRITE, MAP_PRIVATE, fd, 0);
93     *(m + 11) = 'a';  /* raises SIGBUS */
94     return NULL;
95 }
96
97
98 int
99 main(int argvc, char **argv)
100 {
101     char *path;
102     int i;
103     int threads = 10;
104
105     opr_softsig_Init();
106
107     opr_Verify(opr_softsig_Register(SIGINT, handler) == 0);
108     opr_Verify(opr_softsig_Register(SIGHUP, handler) == 0);
109     opr_Verify(opr_softsig_Register(SIGQUIT, handler) == 0);
110     opr_Verify(opr_softsig_Register(SIGALRM, handler) == 0);
111     opr_Verify(opr_softsig_Register(SIGTERM, handler) == 0);
112     opr_Verify(opr_softsig_Register(SIGTSTP, handler) == 0);
113     opr_Verify(opr_softsig_Register(SIGUSR1, handler) == 0);
114     opr_Verify(opr_softsig_Register(SIGUSR2, handler) == 0);
115
116     for (i=0; i<threads; i++) {
117         pthread_t id;
118         opr_Verify(pthread_create(&id, NULL, mythread, NULL) == 0);
119     }
120
121     if (argvc>1 && strcmp(argv[1], "-crash") == 0) {
122         pthread_t id;
123         opr_Verify(pthread_create(&id, NULL, crashingThread, NULL) == 0);
124     } else if (argvc>1 && strcmp(argv[1], "-buserror") == 0) {
125         if (argvc > 2)
126             path = argv[2];
127         else
128             opr_abort();
129         pthread_t id;
130         opr_Verify(pthread_create(&id, NULL, thrownUnderTheBusThread,
131                                   path) == 0);
132     } else {
133         printf("Ready\n");
134         fflush(stdout);
135     }
136
137     mythread(NULL);
138
139     return 0;
140 }