1/*
| 1/*
|
2 * Copyright (c) 2000-2001, 2005-2008 Proofpoint, Inc. and its suppliers.
| 2 * Copyright (c) 2000-2001 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>
| 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>
|
11SM_RCSID("@(#)$Id: t-sem.c,v 1.18 2013-11-22 20:51:43 ca Exp $")
| 11SM_RCSID("@(#)$Id: t-sem.c,v 1.14 2005/03/25 21:27:41 ca Exp $")
|
12 13#include <stdio.h> 14 15#if SM_CONF_SEM 16# include <stdlib.h> 17# include <unistd.h> 18# include <sysexits.h> 19# include <sm/heap.h> 20# include <sm/string.h> 21# include <sm/signal.h> 22# include <sm/test.h> 23# include <sm/sem.h> 24
| 12 13#include <stdio.h> 14 15#if SM_CONF_SEM 16# include <stdlib.h> 17# include <unistd.h> 18# include <sysexits.h> 19# include <sm/heap.h> 20# include <sm/string.h> 21# include <sm/signal.h> 22# include <sm/test.h> 23# include <sm/sem.h> 24
|
25# define T_SM_SEM_KEY (4321L) 26
| |
27static void 28delay(t, s) 29 int t; 30 char *s; 31{ 32 if (t > 0) 33 { 34#if DEBUG 35 fprintf(stderr, "sleep(%d) before %s\n", t, s); 36#endif /* DEBUG */ 37 sleep(t); 38 } 39#if DEBUG 40 fprintf(stderr, "%s\n", s); 41#endif /* DEBUG */ 42} 43 44 45/* 46** SEMINTER -- interactive testing of semaphores. 47** 48** Parameters: 49** owner -- create semaphores. 50** 51** Returns: 52** 0 on success 53** < 0 on failure. 54*/ 55 56static int 57seminter(owner) 58 bool owner; 59{ 60 int semid; 61 int t; 62
| 25static void 26delay(t, s) 27 int t; 28 char *s; 29{ 30 if (t > 0) 31 { 32#if DEBUG 33 fprintf(stderr, "sleep(%d) before %s\n", t, s); 34#endif /* DEBUG */ 35 sleep(t); 36 } 37#if DEBUG 38 fprintf(stderr, "%s\n", s); 39#endif /* DEBUG */ 40} 41 42 43/* 44** SEMINTER -- interactive testing of semaphores. 45** 46** Parameters: 47** owner -- create semaphores. 48** 49** Returns: 50** 0 on success 51** < 0 on failure. 52*/ 53 54static int 55seminter(owner) 56 bool owner; 57{ 58 int semid; 59 int t; 60
|
63 semid = sm_sem_start(T_SM_SEM_KEY, SM_NSEM, 0, owner);
| 61 semid = sm_sem_start(SM_SEM_KEY, SM_NSEM, 0, owner);
|
64 if (semid < 0) 65 { 66 perror("sm_sem_start failed"); 67 return 1; 68 } 69 70 while ((t = getchar()) != EOF) 71 { 72 switch (t) 73 { 74 case 'a': 75 delay(0, "try to acq"); 76 if (sm_sem_acq(semid, 0, 2) < 0) 77 { 78 perror("sm_sem_acq failed"); 79 return 1; 80 } 81 delay(0, "acquired"); 82 break; 83 84 case 'r': 85 delay(0, "try to rel"); 86 if (sm_sem_rel(semid, 0, 2) < 0) 87 { 88 perror("sm_sem_rel failed"); 89 return 1; 90 } 91 delay(0, "released"); 92 break; 93 94 case 'v': 95 if ((t = sm_sem_get(semid, 0)) < 0) 96 { 97 perror("get_sem failed"); 98 return 1; 99 } 100 printf("semval: %d\n", t); 101 break; 102 103 } 104 } 105 if (owner) 106 return sm_sem_stop(semid); 107 return 0; 108} 109 110/* 111** SEM_CLEANUP -- cleanup if something breaks 112** 113** Parameters: 114** sig -- signal. 115** 116** Returns: 117** none. 118*/ 119 120static int semid_c = -1; 121void 122sem_cleanup(sig) 123 int sig; 124{ 125 if (semid_c >= 0) 126 (void) sm_sem_stop(semid_c); 127 exit(EX_UNAVAILABLE); 128} 129
| 62 if (semid < 0) 63 { 64 perror("sm_sem_start failed"); 65 return 1; 66 } 67 68 while ((t = getchar()) != EOF) 69 { 70 switch (t) 71 { 72 case 'a': 73 delay(0, "try to acq"); 74 if (sm_sem_acq(semid, 0, 2) < 0) 75 { 76 perror("sm_sem_acq failed"); 77 return 1; 78 } 79 delay(0, "acquired"); 80 break; 81 82 case 'r': 83 delay(0, "try to rel"); 84 if (sm_sem_rel(semid, 0, 2) < 0) 85 { 86 perror("sm_sem_rel failed"); 87 return 1; 88 } 89 delay(0, "released"); 90 break; 91 92 case 'v': 93 if ((t = sm_sem_get(semid, 0)) < 0) 94 { 95 perror("get_sem failed"); 96 return 1; 97 } 98 printf("semval: %d\n", t); 99 break; 100 101 } 102 } 103 if (owner) 104 return sm_sem_stop(semid); 105 return 0; 106} 107 108/* 109** SEM_CLEANUP -- cleanup if something breaks 110** 111** Parameters: 112** sig -- signal. 113** 114** Returns: 115** none. 116*/ 117 118static int semid_c = -1; 119void 120sem_cleanup(sig) 121 int sig; 122{ 123 if (semid_c >= 0) 124 (void) sm_sem_stop(semid_c); 125 exit(EX_UNAVAILABLE); 126} 127
|
130static int 131drop_priv(uid, gid) 132 uid_t uid; 133 gid_t gid; 134{ 135 int r; 136 137 r = setgid(gid); 138 if (r != 0) 139 return r; 140 r = setuid(uid); 141 return r; 142} 143
| |
144/* 145** SEMTEST -- test of semaphores 146** 147** Parameters: 148** owner -- create semaphores. 149** 150** Returns: 151** 0 on success 152** < 0 on failure. 153*/ 154 155# define MAX_CNT 10 156 157static int
| 128/* 129** SEMTEST -- test of semaphores 130** 131** Parameters: 132** owner -- create semaphores. 133** 134** Returns: 135** 0 on success 136** < 0 on failure. 137*/ 138 139# define MAX_CNT 10 140 141static int
|
158semtest(owner, uid, gid)
| 142semtest(owner)
|
159 int owner;
| 143 int owner;
|
160 uid_t uid; 161 gid_t gid;
| |
162{ 163 int semid, r; 164 int cnt = 0; 165
| 144{ 145 int semid, r; 146 int cnt = 0; 147
|
166 if (!owner && uid != 0) 167 { 168 r = drop_priv(uid, gid); 169 if (r < 0) 170 { 171 perror("drop_priv child failed"); 172 return -1; 173 } 174 } 175 semid = sm_sem_start(T_SM_SEM_KEY, 1, 0, owner);
| 148 semid = sm_sem_start(SM_SEM_KEY, 1, 0, owner);
|
176 if (semid < 0) 177 { 178 perror("sm_sem_start failed"); 179 return -1; 180 } 181 182 if (owner) 183 {
| 149 if (semid < 0) 150 { 151 perror("sm_sem_start failed"); 152 return -1; 153 } 154 155 if (owner) 156 {
|
184 if (uid != 0) 185 { 186 r = sm_semsetowner(semid, uid, gid, 0660); 187 if (r < 0) 188 { 189 perror("sm_semsetowner failed"); 190 return -1; 191 } 192 r = drop_priv(uid, gid); 193 if (r < 0) 194 { 195 perror("drop_priv owner failed"); 196 return -1; 197 } 198 } 199
| |
200 /* just in case someone kills the program... */ 201 semid_c = semid; 202 (void) sm_signal(SIGHUP, sem_cleanup); 203 (void) sm_signal(SIGINT, sem_cleanup); 204 (void) sm_signal(SIGTERM, sem_cleanup); 205 206 delay(1, "parent: acquire 1"); 207 cnt = 0; 208 do 209 { 210 r = sm_sem_acq(semid, 0, 0); 211 if (r < 0) 212 { 213 sleep(1); 214 ++cnt; 215 } 216 } while (r < 0 && cnt <= MAX_CNT); 217 SM_TEST(r >= 0); 218 if (r < 0) 219 return r; 220 221 delay(3, "parent: release 1"); 222 cnt = 0; 223 do 224 { 225 r = sm_sem_rel(semid, 0, 0); 226 if (r < 0) 227 { 228 sleep(1); 229 ++cnt; 230 } 231 } while (r < 0 && cnt <= MAX_CNT); 232 SM_TEST(r >= 0); 233 if (r < 0) 234 return r; 235 236 delay(1, "parent: getval"); 237 cnt = 0; 238 do 239 { 240 r = sm_sem_get(semid, 0); 241 if (r <= 0) 242 { 243 sleep(1); 244 ++cnt; 245 } 246 } while (r <= 0 && cnt <= MAX_CNT); 247 SM_TEST(r > 0); 248 if (r <= 0) 249 return r; 250 251 delay(1, "parent: acquire 2"); 252 cnt = 0; 253 do 254 { 255 r = sm_sem_acq(semid, 0, 0); 256 if (r < 0) 257 { 258 sleep(1); 259 ++cnt; 260 } 261 } while (r < 0 && cnt <= MAX_CNT); 262 SM_TEST(r >= 0); 263 if (r < 0) 264 return r; 265 266 cnt = 0; 267 do 268 { 269 r = sm_sem_rel(semid, 0, 0); 270 if (r < 0) 271 { 272 sleep(1); 273 ++cnt; 274 } 275 } while (r < 0 && cnt <= MAX_CNT); 276 SM_TEST(r >= 0); 277 if (r < 0) 278 return r; 279 } 280 else 281 { 282 delay(1, "child: acquire 1"); 283 cnt = 0; 284 do 285 { 286 r = sm_sem_acq(semid, 0, 0); 287 if (r < 0) 288 { 289 sleep(1); 290 ++cnt; 291 } 292 } while (r < 0 && cnt <= MAX_CNT); 293 SM_TEST(r >= 0); 294 if (r < 0) 295 return r; 296 297 delay(1, "child: release 1"); 298 cnt = 0; 299 do 300 { 301 r = sm_sem_rel(semid, 0, 0); 302 if (r < 0) 303 { 304 sleep(1); 305 ++cnt; 306 } 307 } while (r < 0 && cnt <= MAX_CNT); 308 SM_TEST(r >= 0); 309 if (r < 0) 310 return r; 311 312 } 313 if (owner) 314 return sm_sem_stop(semid); 315 return 0; 316} 317 318int 319main(argc, argv) 320 int argc; 321 char *argv[]; 322{ 323 bool interactive = false; 324 bool owner = false;
| 157 /* just in case someone kills the program... */ 158 semid_c = semid; 159 (void) sm_signal(SIGHUP, sem_cleanup); 160 (void) sm_signal(SIGINT, sem_cleanup); 161 (void) sm_signal(SIGTERM, sem_cleanup); 162 163 delay(1, "parent: acquire 1"); 164 cnt = 0; 165 do 166 { 167 r = sm_sem_acq(semid, 0, 0); 168 if (r < 0) 169 { 170 sleep(1); 171 ++cnt; 172 } 173 } while (r < 0 && cnt <= MAX_CNT); 174 SM_TEST(r >= 0); 175 if (r < 0) 176 return r; 177 178 delay(3, "parent: release 1"); 179 cnt = 0; 180 do 181 { 182 r = sm_sem_rel(semid, 0, 0); 183 if (r < 0) 184 { 185 sleep(1); 186 ++cnt; 187 } 188 } while (r < 0 && cnt <= MAX_CNT); 189 SM_TEST(r >= 0); 190 if (r < 0) 191 return r; 192 193 delay(1, "parent: getval"); 194 cnt = 0; 195 do 196 { 197 r = sm_sem_get(semid, 0); 198 if (r <= 0) 199 { 200 sleep(1); 201 ++cnt; 202 } 203 } while (r <= 0 && cnt <= MAX_CNT); 204 SM_TEST(r > 0); 205 if (r <= 0) 206 return r; 207 208 delay(1, "parent: acquire 2"); 209 cnt = 0; 210 do 211 { 212 r = sm_sem_acq(semid, 0, 0); 213 if (r < 0) 214 { 215 sleep(1); 216 ++cnt; 217 } 218 } while (r < 0 && cnt <= MAX_CNT); 219 SM_TEST(r >= 0); 220 if (r < 0) 221 return r; 222 223 cnt = 0; 224 do 225 { 226 r = sm_sem_rel(semid, 0, 0); 227 if (r < 0) 228 { 229 sleep(1); 230 ++cnt; 231 } 232 } while (r < 0 && cnt <= MAX_CNT); 233 SM_TEST(r >= 0); 234 if (r < 0) 235 return r; 236 } 237 else 238 { 239 delay(1, "child: acquire 1"); 240 cnt = 0; 241 do 242 { 243 r = sm_sem_acq(semid, 0, 0); 244 if (r < 0) 245 { 246 sleep(1); 247 ++cnt; 248 } 249 } while (r < 0 && cnt <= MAX_CNT); 250 SM_TEST(r >= 0); 251 if (r < 0) 252 return r; 253 254 delay(1, "child: release 1"); 255 cnt = 0; 256 do 257 { 258 r = sm_sem_rel(semid, 0, 0); 259 if (r < 0) 260 { 261 sleep(1); 262 ++cnt; 263 } 264 } while (r < 0 && cnt <= MAX_CNT); 265 SM_TEST(r >= 0); 266 if (r < 0) 267 return r; 268 269 } 270 if (owner) 271 return sm_sem_stop(semid); 272 return 0; 273} 274 275int 276main(argc, argv) 277 int argc; 278 char *argv[]; 279{ 280 bool interactive = false; 281 bool owner = false;
|
325 int ch, r; 326 uid_t uid; 327 gid_t gid;
| 282 int ch; 283 int r = 0;
|
328
| 284
|
329 uid = 0; 330 gid = 0; 331 r = 0; 332 333# define OPTIONS "iog:u:"
| 285# define OPTIONS "io"
|
334 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 335 { 336 switch ((char) ch) 337 {
| 286 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 287 { 288 switch ((char) ch) 289 {
|
338 case 'g': 339 gid = (gid_t)strtoul(optarg, 0, 0); 340 break; 341
| |
342 case 'i': 343 interactive = true; 344 break; 345
| 290 case 'i': 291 interactive = true; 292 break; 293
|
346 case 'u': 347 uid = (uid_t)strtoul(optarg, 0, 0); 348 break; 349
| |
350 case 'o': 351 owner = true; 352 break; 353 354 default: 355 break; 356 } 357 } 358 359 if (interactive) 360 r = seminter(owner); 361 else 362 { 363 pid_t pid; 364 365 printf("This test takes about 8 seconds.\n");
| 294 case 'o': 295 owner = true; 296 break; 297 298 default: 299 break; 300 } 301 } 302 303 if (interactive) 304 r = seminter(owner); 305 else 306 { 307 pid_t pid; 308 309 printf("This test takes about 8 seconds.\n");
|
366 printf("If it takes longer than 30 seconds, please interrupt it\n");
| 310 printf("If it takes longer than 30 second, please interrupt it\n");
|
367 printf("and compile again without semaphore support, i.e.,"); 368 printf("-DSM_CONF_SEM=0\n"); 369 if ((pid = fork()) < 0) 370 { 371 perror("fork failed\n"); 372 return -1; 373 } 374 375 sm_test_begin(argc, argv, "test semaphores"); 376 if (pid == 0) 377 { 378 /* give the parent the chance to setup data */ 379 sleep(1);
| 311 printf("and compile again without semaphore support, i.e.,"); 312 printf("-DSM_CONF_SEM=0\n"); 313 if ((pid = fork()) < 0) 314 { 315 perror("fork failed\n"); 316 return -1; 317 } 318 319 sm_test_begin(argc, argv, "test semaphores"); 320 if (pid == 0) 321 { 322 /* give the parent the chance to setup data */ 323 sleep(1);
|
380 r = semtest(false, uid, gid);
| 324 r = semtest(false);
|
381 } 382 else 383 {
| 325 } 326 else 327 {
|
384 r = semtest(true, uid, gid);
| 328 r = semtest(true);
|
385 } 386 SM_TEST(r == 0); 387 return sm_test_end(); 388 } 389 return r; 390} 391#else /* SM_CONF_SEM */ 392int 393main(argc, argv) 394 int argc; 395 char *argv[]; 396{ 397 printf("No support for semaphores configured on this machine\n"); 398 return 0; 399} 400#endif /* SM_CONF_SEM */
| 329 } 330 SM_TEST(r == 0); 331 return sm_test_end(); 332 } 333 return r; 334} 335#else /* SM_CONF_SEM */ 336int 337main(argc, argv) 338 int argc; 339 char *argv[]; 340{ 341 printf("No support for semaphores configured on this machine\n"); 342 return 0; 343} 344#endif /* SM_CONF_SEM */
|