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