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> 11SM_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/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 41int shminter __P((bool)); 42 43int 44shminter(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 108int shmbig __P((bool, int)); 109 110int 111shmbig(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 152int shmtest __P((int)); 153 154int 155shmtest(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 198int 199main(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 */ 268int 269main(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