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 */ 277