190792Sgshapiro/* 2261370Sgshapiro * Copyright (c) 2000-2002, 2004, 2005 Proofpoint, Inc. and its suppliers. 390792Sgshapiro * All rights reserved. 490792Sgshapiro * 590792Sgshapiro * By using this file, you agree to the terms and conditions set 690792Sgshapiro * forth in the LICENSE file which can be found at the top level of 790792Sgshapiro * the sendmail distribution. 890792Sgshapiro */ 990792Sgshapiro 1090792Sgshapiro#include <sm/gen.h> 11266711SgshapiroSM_RCSID("@(#)$Id: t-shm.c,v 1.23 2013-11-22 20:51:43 ca Exp $") 1290792Sgshapiro 1390792Sgshapiro#include <stdio.h> 1490792Sgshapiro 1590792Sgshapiro#if SM_CONF_SHM 1690792Sgshapiro# include <stdlib.h> 1790792Sgshapiro# include <unistd.h> 1890792Sgshapiro# include <sys/wait.h> 1990792Sgshapiro 2090792Sgshapiro# include <sm/heap.h> 2190792Sgshapiro# include <sm/string.h> 2290792Sgshapiro# include <sm/test.h> 2390792Sgshapiro# include <sm/shm.h> 2490792Sgshapiro 2590792Sgshapiro# define SHMSIZE 1024 2690792Sgshapiro# define SHM_MAX 6400000 2790792Sgshapiro# define T_SHMKEY 21 2890792Sgshapiro 2990792Sgshapiro 3090792Sgshapiro/* 3190792Sgshapiro** SHMINTER -- interactive testing of shared memory 3290792Sgshapiro** 3390792Sgshapiro** Parameters: 3490792Sgshapiro** owner -- create segment. 3590792Sgshapiro** 3690792Sgshapiro** Returns: 3790792Sgshapiro** 0 on success 3890792Sgshapiro** < 0 on failure. 3990792Sgshapiro*/ 4090792Sgshapiro 4190792Sgshapiroint shminter __P((bool)); 4290792Sgshapiro 4390792Sgshapiroint 4490792Sgshapiroshminter(owner) 4590792Sgshapiro bool owner; 4690792Sgshapiro{ 4790792Sgshapiro int *shm, shmid; 48132943Sgshapiro int i, t; 4990792Sgshapiro 5090792Sgshapiro shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 5190792Sgshapiro if (shm == (int *) 0) 5290792Sgshapiro { 5390792Sgshapiro perror("shminit failed"); 5490792Sgshapiro return -1; 5590792Sgshapiro } 5690792Sgshapiro 5790792Sgshapiro while ((t = getchar()) != EOF) 5890792Sgshapiro { 5990792Sgshapiro switch (t) 6090792Sgshapiro { 6190792Sgshapiro case 'c': 6290792Sgshapiro *shm = 0; 6390792Sgshapiro break; 6490792Sgshapiro case 'i': 6590792Sgshapiro ++*shm; 6690792Sgshapiro break; 6790792Sgshapiro case 'd': 6890792Sgshapiro --*shm; 6990792Sgshapiro break; 7090792Sgshapiro case 's': 7190792Sgshapiro sleep(1); 7290792Sgshapiro break; 7390792Sgshapiro case 'l': 7490792Sgshapiro t = *shm; 7590792Sgshapiro for (i = 0; i < SHM_MAX; i++) 7690792Sgshapiro { 7790792Sgshapiro ++*shm; 7890792Sgshapiro } 7990792Sgshapiro if (*shm != SHM_MAX + t) 8090792Sgshapiro fprintf(stderr, "error: %d != %d\n", 8190792Sgshapiro *shm, SHM_MAX + t); 8290792Sgshapiro break; 8390792Sgshapiro case 'v': 8490792Sgshapiro printf("shmval: %d\n", *shm); 8590792Sgshapiro break; 86147078Sgshapiro case 'S': 87147078Sgshapiro i = sm_shmsetowner(shmid, getuid(), getgid(), 0644); 88147078Sgshapiro printf("sm_shmsetowner=%d\n", i); 89147078Sgshapiro break; 9090792Sgshapiro } 9190792Sgshapiro } 9290792Sgshapiro return sm_shmstop((void *) shm, shmid, owner); 9390792Sgshapiro} 9490792Sgshapiro 9590792Sgshapiro 9690792Sgshapiro/* 9790792Sgshapiro** SHMBIG -- testing of shared memory 9890792Sgshapiro** 9990792Sgshapiro** Parameters: 10090792Sgshapiro** owner -- create segment. 10190792Sgshapiro** size -- size of segment. 10290792Sgshapiro** 10390792Sgshapiro** Returns: 10490792Sgshapiro** 0 on success 10590792Sgshapiro** < 0 on failure. 10690792Sgshapiro*/ 10790792Sgshapiro 10890792Sgshapiroint shmbig __P((bool, int)); 10990792Sgshapiro 11090792Sgshapiroint 11190792Sgshapiroshmbig(owner, size) 11290792Sgshapiro bool owner; 11390792Sgshapiro int size; 11490792Sgshapiro{ 11590792Sgshapiro int *shm, shmid; 11690792Sgshapiro int i; 11790792Sgshapiro 11890792Sgshapiro shm = (int *) sm_shmstart(T_SHMKEY, size, 0, &shmid, owner); 11990792Sgshapiro if (shm == (int *) 0) 12090792Sgshapiro { 12190792Sgshapiro perror("shminit failed"); 12290792Sgshapiro return -1; 12390792Sgshapiro } 12490792Sgshapiro 12590792Sgshapiro for (i = 0; i < size / sizeof(int); i++) 12690792Sgshapiro shm[i] = i; 12790792Sgshapiro for (i = 0; i < size / sizeof(int); i++) 12890792Sgshapiro { 12990792Sgshapiro if (shm[i] != i) 13090792Sgshapiro { 13190792Sgshapiro fprintf(stderr, "failed at %d: %d", i, shm[i]); 13290792Sgshapiro } 13390792Sgshapiro } 13490792Sgshapiro 13590792Sgshapiro return sm_shmstop((void *) shm, shmid, owner); 13690792Sgshapiro} 13790792Sgshapiro 13890792Sgshapiro 13990792Sgshapiro/* 14090792Sgshapiro** SHMTEST -- test of shared memory 14190792Sgshapiro** 14290792Sgshapiro** Parameters: 14390792Sgshapiro** owner -- create segment. 14490792Sgshapiro** 14590792Sgshapiro** Returns: 14690792Sgshapiro** 0 on success 14790792Sgshapiro** < 0 on failure. 14890792Sgshapiro*/ 14990792Sgshapiro 15090792Sgshapiro# define MAX_CNT 10 15190792Sgshapiro 152141858Sgshapiroint shmtest __P((int)); 153141858Sgshapiro 15490792Sgshapiroint 15590792Sgshapiroshmtest(owner) 15690792Sgshapiro int owner; 15790792Sgshapiro{ 15890792Sgshapiro int *shm, shmid; 15990792Sgshapiro int cnt = 0; 16090792Sgshapiro 16190792Sgshapiro shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 16290792Sgshapiro if (shm == (int *) 0) 16390792Sgshapiro { 16490792Sgshapiro perror("shminit failed"); 16590792Sgshapiro return -1; 16690792Sgshapiro } 16790792Sgshapiro 16890792Sgshapiro if (owner) 16990792Sgshapiro { 17090792Sgshapiro int r; 17190792Sgshapiro 172147078Sgshapiro r = sm_shmsetowner(shmid, getuid(), getgid(), 0660); 173147078Sgshapiro SM_TEST(r == 0); 17490792Sgshapiro *shm = 1; 17590792Sgshapiro while (*shm == 1 && cnt++ < MAX_CNT) 17690792Sgshapiro sleep(1); 17790792Sgshapiro SM_TEST(cnt <= MAX_CNT); 17890792Sgshapiro 17990792Sgshapiro /* release and re-acquire the segment */ 18090792Sgshapiro r = sm_shmstop((void *) shm, shmid, owner); 18190792Sgshapiro SM_TEST(r == 0); 18290792Sgshapiro shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 18390792Sgshapiro SM_TEST(shm != (int *) 0); 18490792Sgshapiro } 18590792Sgshapiro else 18690792Sgshapiro { 18790792Sgshapiro while (*shm != 1 && cnt++ < MAX_CNT) 18890792Sgshapiro sleep(1); 18990792Sgshapiro SM_TEST(cnt <= MAX_CNT); 19090792Sgshapiro *shm = 2; 19190792Sgshapiro 19290792Sgshapiro /* wait a momemt so the segment is still in use */ 19390792Sgshapiro sleep(2); 19490792Sgshapiro } 19590792Sgshapiro return sm_shmstop((void *) shm, shmid, owner); 19690792Sgshapiro} 19790792Sgshapiro 19890792Sgshapiroint 19990792Sgshapiromain(argc, argv) 20090792Sgshapiro int argc; 20190792Sgshapiro char *argv[]; 20290792Sgshapiro{ 20390792Sgshapiro bool interactive = false; 20490792Sgshapiro bool owner = false; 20590792Sgshapiro int big = -1; 20690792Sgshapiro int ch; 20790792Sgshapiro int r = 0; 20890792Sgshapiro int status; 20990792Sgshapiro extern char *optarg; 21090792Sgshapiro 21190792Sgshapiro# define OPTIONS "b:io" 21290792Sgshapiro while ((ch = getopt(argc, argv, OPTIONS)) != -1) 21390792Sgshapiro { 21490792Sgshapiro switch ((char) ch) 21590792Sgshapiro { 21690792Sgshapiro case 'b': 21790792Sgshapiro big = atoi(optarg); 21890792Sgshapiro break; 21990792Sgshapiro 22090792Sgshapiro case 'i': 22190792Sgshapiro interactive = true; 22290792Sgshapiro break; 22390792Sgshapiro 22490792Sgshapiro case 'o': 22590792Sgshapiro owner = true; 22690792Sgshapiro break; 22790792Sgshapiro 22890792Sgshapiro default: 22990792Sgshapiro break; 23090792Sgshapiro } 23190792Sgshapiro } 23290792Sgshapiro 23390792Sgshapiro if (interactive) 23490792Sgshapiro r = shminter(owner); 23590792Sgshapiro else if (big > 0) 23690792Sgshapiro r = shmbig(true, big); 23790792Sgshapiro else 23890792Sgshapiro { 23990792Sgshapiro pid_t pid; 24094334Sgshapiro extern int SmTestNumErrors; 24190792Sgshapiro 24290792Sgshapiro if ((pid = fork()) < 0) 24390792Sgshapiro { 24490792Sgshapiro perror("fork failed\n"); 24590792Sgshapiro return -1; 24690792Sgshapiro } 24790792Sgshapiro 24890792Sgshapiro sm_test_begin(argc, argv, "test shared memory"); 24990792Sgshapiro if (pid == 0) 25090792Sgshapiro { 25190792Sgshapiro /* give the parent the chance to setup data */ 25290792Sgshapiro sleep(1); 25390792Sgshapiro r = shmtest(false); 25490792Sgshapiro } 25590792Sgshapiro else 25690792Sgshapiro { 25790792Sgshapiro r = shmtest(true); 25890792Sgshapiro (void) wait(&status); 25990792Sgshapiro } 26090792Sgshapiro SM_TEST(r == 0); 26194334Sgshapiro if (SmTestNumErrors > 0) 26294334Sgshapiro printf("add -DSM_CONF_SHM=0 to confENVDEF in devtools/Site/site.config.m4\nand start over.\n"); 26390792Sgshapiro return sm_test_end(); 26490792Sgshapiro } 26590792Sgshapiro return r; 26690792Sgshapiro} 26790792Sgshapiro#else /* SM_CONF_SHM */ 26890792Sgshapiroint 26990792Sgshapiromain(argc, argv) 27090792Sgshapiro int argc; 27190792Sgshapiro char *argv[]; 27290792Sgshapiro{ 27390792Sgshapiro printf("No support for shared memory configured on this machine\n"); 27490792Sgshapiro return 0; 27590792Sgshapiro} 27690792Sgshapiro#endif /* SM_CONF_SHM */ 277