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