diff options
Diffstat (limited to 'contrib/sendmail/libsm/t-shm.c')
-rw-r--r-- | contrib/sendmail/libsm/t-shm.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/contrib/sendmail/libsm/t-shm.c b/contrib/sendmail/libsm/t-shm.c new file mode 100644 index 0000000..ba0bc6c --- /dev/null +++ b/contrib/sendmail/libsm/t-shm.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2000-2002, 2004, 2005 Sendmail, Inc. and its suppliers. + * All rights reserved. + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the sendmail distribution. + */ + +#include <sm/gen.h> +SM_RCSID("@(#)$Id: t-shm.c,v 1.22 2005/01/14 02:14:10 ca Exp $") + +#include <stdio.h> + +#if SM_CONF_SHM +# include <stdlib.h> +# include <unistd.h> +# include <sys/wait.h> + +# include <sm/heap.h> +# include <sm/string.h> +# include <sm/test.h> +# include <sm/shm.h> + +# define SHMSIZE 1024 +# define SHM_MAX 6400000 +# define T_SHMKEY 21 + + +/* +** SHMINTER -- interactive testing of shared memory +** +** Parameters: +** owner -- create segment. +** +** Returns: +** 0 on success +** < 0 on failure. +*/ + +int shminter __P((bool)); + +int +shminter(owner) + bool owner; +{ + int *shm, shmid; + int i, t; + + shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); + if (shm == (int *) 0) + { + perror("shminit failed"); + return -1; + } + + while ((t = getchar()) != EOF) + { + switch (t) + { + case 'c': + *shm = 0; + break; + case 'i': + ++*shm; + break; + case 'd': + --*shm; + break; + case 's': + sleep(1); + break; + case 'l': + t = *shm; + for (i = 0; i < SHM_MAX; i++) + { + ++*shm; + } + if (*shm != SHM_MAX + t) + fprintf(stderr, "error: %d != %d\n", + *shm, SHM_MAX + t); + break; + case 'v': + printf("shmval: %d\n", *shm); + break; + case 'S': + i = sm_shmsetowner(shmid, getuid(), getgid(), 0644); + printf("sm_shmsetowner=%d\n", i); + break; + } + } + return sm_shmstop((void *) shm, shmid, owner); +} + + +/* +** SHMBIG -- testing of shared memory +** +** Parameters: +** owner -- create segment. +** size -- size of segment. +** +** Returns: +** 0 on success +** < 0 on failure. +*/ + +int shmbig __P((bool, int)); + +int +shmbig(owner, size) + bool owner; + int size; +{ + int *shm, shmid; + int i; + + shm = (int *) sm_shmstart(T_SHMKEY, size, 0, &shmid, owner); + if (shm == (int *) 0) + { + perror("shminit failed"); + return -1; + } + + for (i = 0; i < size / sizeof(int); i++) + shm[i] = i; + for (i = 0; i < size / sizeof(int); i++) + { + if (shm[i] != i) + { + fprintf(stderr, "failed at %d: %d", i, shm[i]); + } + } + + return sm_shmstop((void *) shm, shmid, owner); +} + + +/* +** SHMTEST -- test of shared memory +** +** Parameters: +** owner -- create segment. +** +** Returns: +** 0 on success +** < 0 on failure. +*/ + +# define MAX_CNT 10 + +int shmtest __P((int)); + +int +shmtest(owner) + int owner; +{ + int *shm, shmid; + int cnt = 0; + + shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); + if (shm == (int *) 0) + { + perror("shminit failed"); + return -1; + } + + if (owner) + { + int r; + + r = sm_shmsetowner(shmid, getuid(), getgid(), 0660); + SM_TEST(r == 0); + *shm = 1; + while (*shm == 1 && cnt++ < MAX_CNT) + sleep(1); + SM_TEST(cnt <= MAX_CNT); + + /* release and re-acquire the segment */ + r = sm_shmstop((void *) shm, shmid, owner); + SM_TEST(r == 0); + shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); + SM_TEST(shm != (int *) 0); + } + else + { + while (*shm != 1 && cnt++ < MAX_CNT) + sleep(1); + SM_TEST(cnt <= MAX_CNT); + *shm = 2; + + /* wait a momemt so the segment is still in use */ + sleep(2); + } + return sm_shmstop((void *) shm, shmid, owner); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + bool interactive = false; + bool owner = false; + int big = -1; + int ch; + int r = 0; + int status; + extern char *optarg; + +# define OPTIONS "b:io" + while ((ch = getopt(argc, argv, OPTIONS)) != -1) + { + switch ((char) ch) + { + case 'b': + big = atoi(optarg); + break; + + case 'i': + interactive = true; + break; + + case 'o': + owner = true; + break; + + default: + break; + } + } + + if (interactive) + r = shminter(owner); + else if (big > 0) + r = shmbig(true, big); + else + { + pid_t pid; + extern int SmTestNumErrors; + + if ((pid = fork()) < 0) + { + perror("fork failed\n"); + return -1; + } + + sm_test_begin(argc, argv, "test shared memory"); + if (pid == 0) + { + /* give the parent the chance to setup data */ + sleep(1); + r = shmtest(false); + } + else + { + r = shmtest(true); + (void) wait(&status); + } + SM_TEST(r == 0); + if (SmTestNumErrors > 0) + printf("add -DSM_CONF_SHM=0 to confENVDEF in devtools/Site/site.config.m4\nand start over.\n"); + return sm_test_end(); + } + return r; +} +#else /* SM_CONF_SHM */ +int +main(argc, argv) + int argc; + char *argv[]; +{ + printf("No support for shared memory configured on this machine\n"); + return 0; +} +#endif /* SM_CONF_SHM */ |