Import sendmail 8.13.8
[dragonfly.git] / contrib / sendmail-8.13.8 / libsm / t-shm.c
1 /*
2  * Copyright (c) 2000-2002, 2004, 2005 Sendmail, Inc. and its suppliers.
3  *      All rights reserved.
4  *
5  * By using this file, you agree to the terms and conditions set
6  * forth in the LICENSE file which can be found at the top level of
7  * the sendmail distribution.
8  */
9
10 #include <sm/gen.h>
11 SM_RCSID("@(#)$Id: t-shm.c,v 1.22 2005/01/14 02:14:10 ca Exp $")
12
13 #include <stdio.h>
14
15 #if SM_CONF_SHM
16 # include <stdlib.h>
17 # include <unistd.h>
18 # include <sys/wait.h>
19
20 # include <sm/heap.h>
21 # include <sm/string.h>
22 # include <sm/test.h>
23 # include <sm/shm.h>
24
25 # define SHMSIZE        1024
26 # define SHM_MAX        6400000
27 # define T_SHMKEY       21
28
29
30 /*
31 **  SHMINTER -- interactive testing of shared memory
32 **
33 **      Parameters:
34 **              owner -- create segment.
35 **
36 **      Returns:
37 **              0 on success
38 **              < 0 on failure.
39 */
40
41 int shminter __P((bool));
42
43 int
44 shminter(owner)
45         bool owner;
46 {
47         int *shm, shmid;
48         int i, t;
49
50         shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
51         if (shm == (int *) 0)
52         {
53                 perror("shminit failed");
54                 return -1;
55         }
56
57         while ((t = getchar()) != EOF)
58         {
59                 switch (t)
60                 {
61                   case 'c':
62                         *shm = 0;
63                         break;
64                   case 'i':
65                         ++*shm;
66                         break;
67                   case 'd':
68                         --*shm;
69                         break;
70                   case 's':
71                         sleep(1);
72                         break;
73                   case 'l':
74                         t = *shm;
75                         for (i = 0; i < SHM_MAX; i++)
76                         {
77                                 ++*shm;
78                         }
79                         if (*shm != SHM_MAX + t)
80                                 fprintf(stderr, "error: %d != %d\n",
81                                         *shm, SHM_MAX + t);
82                         break;
83                   case 'v':
84                         printf("shmval: %d\n", *shm);
85                         break;
86                   case 'S':
87                         i = sm_shmsetowner(shmid, getuid(), getgid(), 0644);
88                         printf("sm_shmsetowner=%d\n", i);
89                         break;
90                 }
91         }
92         return sm_shmstop((void *) shm, shmid, owner);
93 }
94
95
96 /*
97 **  SHMBIG -- testing of shared memory
98 **
99 **      Parameters:
100 **              owner -- create segment.
101 **              size -- size of segment.
102 **
103 **      Returns:
104 **              0 on success
105 **              < 0 on failure.
106 */
107
108 int shmbig __P((bool, int));
109
110 int
111 shmbig(owner, size)
112         bool owner;
113         int size;
114 {
115         int *shm, shmid;
116         int i;
117
118         shm = (int *) sm_shmstart(T_SHMKEY, size, 0, &shmid, owner);
119         if (shm == (int *) 0)
120         {
121                 perror("shminit failed");
122                 return -1;
123         }
124
125         for (i = 0; i < size / sizeof(int); i++)
126                 shm[i] = i;
127         for (i = 0; i < size / sizeof(int); i++)
128         {
129                 if (shm[i] != i)
130                 {
131                         fprintf(stderr, "failed at %d: %d", i, shm[i]);
132                 }
133         }
134
135         return sm_shmstop((void *) shm, shmid, owner);
136 }
137
138
139 /*
140 **  SHMTEST -- test of shared memory
141 **
142 **      Parameters:
143 **              owner -- create segment.
144 **
145 **      Returns:
146 **              0 on success
147 **              < 0 on failure.
148 */
149
150 # define MAX_CNT        10
151
152 int shmtest __P((int));
153
154 int
155 shmtest(owner)
156         int owner;
157 {
158         int *shm, shmid;
159         int cnt = 0;
160
161         shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
162         if (shm == (int *) 0)
163         {
164                 perror("shminit failed");
165                 return -1;
166         }
167
168         if (owner)
169         {
170                 int r;
171
172                 r = sm_shmsetowner(shmid, getuid(), getgid(), 0660);
173                 SM_TEST(r == 0);
174                 *shm = 1;
175                 while (*shm == 1 && cnt++ < MAX_CNT)
176                         sleep(1);
177                 SM_TEST(cnt <= MAX_CNT);
178
179                 /* release and re-acquire the segment */
180                 r = sm_shmstop((void *) shm, shmid, owner);
181                 SM_TEST(r == 0);
182                 shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
183                 SM_TEST(shm != (int *) 0);
184         }
185         else
186         {
187                 while (*shm != 1 && cnt++ < MAX_CNT)
188                         sleep(1);
189                 SM_TEST(cnt <= MAX_CNT);
190                 *shm = 2;
191
192                 /* wait a momemt so the segment is still in use */
193                 sleep(2);
194         }
195         return sm_shmstop((void *) shm, shmid, owner);
196 }
197
198 int
199 main(argc, argv)
200         int argc;
201         char *argv[];
202 {
203         bool interactive = false;
204         bool owner = false;
205         int big = -1;
206         int ch;
207         int r = 0;
208         int status;
209         extern char *optarg;
210
211 # define OPTIONS        "b:io"
212         while ((ch = getopt(argc, argv, OPTIONS)) != -1)
213         {
214                 switch ((char) ch)
215                 {
216                   case 'b':
217                         big = atoi(optarg);
218                         break;
219
220                   case 'i':
221                         interactive = true;
222                         break;
223
224                   case 'o':
225                         owner = true;
226                         break;
227
228                   default:
229                         break;
230                 }
231         }
232
233         if (interactive)
234                 r = shminter(owner);
235         else if (big > 0)
236                 r = shmbig(true, big);
237         else
238         {
239                 pid_t pid;
240                 extern int SmTestNumErrors;
241
242                 if ((pid = fork()) < 0)
243                 {
244                         perror("fork failed\n");
245                         return -1;
246                 }
247
248                 sm_test_begin(argc, argv, "test shared memory");
249                 if (pid == 0)
250                 {
251                         /* give the parent the chance to setup data */
252                         sleep(1);
253                         r = shmtest(false);
254                 }
255                 else
256                 {
257                         r = shmtest(true);
258                         (void) wait(&status);
259                 }
260                 SM_TEST(r == 0);
261                 if (SmTestNumErrors > 0)
262                         printf("add -DSM_CONF_SHM=0 to confENVDEF in devtools/Site/site.config.m4\nand start over.\n");
263                 return sm_test_end();
264         }
265         return r;
266 }
267 #else /* SM_CONF_SHM */
268 int
269 main(argc, argv)
270         int argc;
271         char *argv[];
272 {
273         printf("No support for shared memory configured on this machine\n");
274         return 0;
275 }
276 #endif /* SM_CONF_SHM */