xref: /freebsd/contrib/sendmail/libsm/t-shm.c (revision 13d882686343bf9a76ffdfa83854043d808703dd)
140266059SGregory Neil Shapiro /*
213d88268SGregory Neil Shapiro  * Copyright (c) 2000-2002, 2004, 2005 Sendmail, Inc. and its suppliers.
340266059SGregory Neil Shapiro  *      All rights reserved.
440266059SGregory Neil Shapiro  *
540266059SGregory Neil Shapiro  * By using this file, you agree to the terms and conditions set
640266059SGregory Neil Shapiro  * forth in the LICENSE file which can be found at the top level of
740266059SGregory Neil Shapiro  * the sendmail distribution.
840266059SGregory Neil Shapiro  */
940266059SGregory Neil Shapiro 
1040266059SGregory Neil Shapiro #include <sm/gen.h>
1113d88268SGregory Neil Shapiro SM_RCSID("@(#)$Id: t-shm.c,v 1.22 2005/01/14 02:14:10 ca Exp $")
1240266059SGregory Neil Shapiro 
1340266059SGregory Neil Shapiro #include <stdio.h>
1440266059SGregory Neil Shapiro 
1540266059SGregory Neil Shapiro #if SM_CONF_SHM
1640266059SGregory Neil Shapiro # include <stdlib.h>
1740266059SGregory Neil Shapiro # include <unistd.h>
1840266059SGregory Neil Shapiro # include <sys/wait.h>
1940266059SGregory Neil Shapiro 
2040266059SGregory Neil Shapiro # include <sm/heap.h>
2140266059SGregory Neil Shapiro # include <sm/string.h>
2240266059SGregory Neil Shapiro # include <sm/test.h>
2340266059SGregory Neil Shapiro # include <sm/shm.h>
2440266059SGregory Neil Shapiro 
2540266059SGregory Neil Shapiro # define SHMSIZE	1024
2640266059SGregory Neil Shapiro # define SHM_MAX	6400000
2740266059SGregory Neil Shapiro # define T_SHMKEY	21
2840266059SGregory Neil Shapiro 
2940266059SGregory Neil Shapiro 
3040266059SGregory Neil Shapiro /*
3140266059SGregory Neil Shapiro **  SHMINTER -- interactive testing of shared memory
3240266059SGregory Neil Shapiro **
3340266059SGregory Neil Shapiro **	Parameters:
3440266059SGregory Neil Shapiro **		owner -- create segment.
3540266059SGregory Neil Shapiro **
3640266059SGregory Neil Shapiro **	Returns:
3740266059SGregory Neil Shapiro **		0 on success
3840266059SGregory Neil Shapiro **		< 0 on failure.
3940266059SGregory Neil Shapiro */
4040266059SGregory Neil Shapiro 
4140266059SGregory Neil Shapiro int shminter __P((bool));
4240266059SGregory Neil Shapiro 
4340266059SGregory Neil Shapiro int
4440266059SGregory Neil Shapiro shminter(owner)
4540266059SGregory Neil Shapiro 	bool owner;
4640266059SGregory Neil Shapiro {
4740266059SGregory Neil Shapiro 	int *shm, shmid;
48e92d3f3fSGregory Neil Shapiro 	int i, t;
4940266059SGregory Neil Shapiro 
5040266059SGregory Neil Shapiro 	shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
5140266059SGregory Neil Shapiro 	if (shm == (int *) 0)
5240266059SGregory Neil Shapiro 	{
5340266059SGregory Neil Shapiro 		perror("shminit failed");
5440266059SGregory Neil Shapiro 		return -1;
5540266059SGregory Neil Shapiro 	}
5640266059SGregory Neil Shapiro 
5740266059SGregory Neil Shapiro 	while ((t = getchar()) != EOF)
5840266059SGregory Neil Shapiro 	{
5940266059SGregory Neil Shapiro 		switch (t)
6040266059SGregory Neil Shapiro 		{
6140266059SGregory Neil Shapiro 		  case 'c':
6240266059SGregory Neil Shapiro 			*shm = 0;
6340266059SGregory Neil Shapiro 			break;
6440266059SGregory Neil Shapiro 		  case 'i':
6540266059SGregory Neil Shapiro 			++*shm;
6640266059SGregory Neil Shapiro 			break;
6740266059SGregory Neil Shapiro 		  case 'd':
6840266059SGregory Neil Shapiro 			--*shm;
6940266059SGregory Neil Shapiro 			break;
7040266059SGregory Neil Shapiro 		  case 's':
7140266059SGregory Neil Shapiro 			sleep(1);
7240266059SGregory Neil Shapiro 			break;
7340266059SGregory Neil Shapiro 		  case 'l':
7440266059SGregory Neil Shapiro 			t = *shm;
7540266059SGregory Neil Shapiro 			for (i = 0; i < SHM_MAX; i++)
7640266059SGregory Neil Shapiro 			{
7740266059SGregory Neil Shapiro 				++*shm;
7840266059SGregory Neil Shapiro 			}
7940266059SGregory Neil Shapiro 			if (*shm != SHM_MAX + t)
8040266059SGregory Neil Shapiro 				fprintf(stderr, "error: %d != %d\n",
8140266059SGregory Neil Shapiro 					*shm, SHM_MAX + t);
8240266059SGregory Neil Shapiro 			break;
8340266059SGregory Neil Shapiro 		  case 'v':
8440266059SGregory Neil Shapiro 			printf("shmval: %d\n", *shm);
8540266059SGregory Neil Shapiro 			break;
8613d88268SGregory Neil Shapiro 		  case 'S':
8713d88268SGregory Neil Shapiro 			i = sm_shmsetowner(shmid, getuid(), getgid(), 0644);
8813d88268SGregory Neil Shapiro 			printf("sm_shmsetowner=%d\n", i);
8913d88268SGregory Neil Shapiro 			break;
9040266059SGregory Neil Shapiro 		}
9140266059SGregory Neil Shapiro 	}
9240266059SGregory Neil Shapiro 	return sm_shmstop((void *) shm, shmid, owner);
9340266059SGregory Neil Shapiro }
9440266059SGregory Neil Shapiro 
9540266059SGregory Neil Shapiro 
9640266059SGregory Neil Shapiro /*
9740266059SGregory Neil Shapiro **  SHMBIG -- testing of shared memory
9840266059SGregory Neil Shapiro **
9940266059SGregory Neil Shapiro **	Parameters:
10040266059SGregory Neil Shapiro **		owner -- create segment.
10140266059SGregory Neil Shapiro **		size -- size of segment.
10240266059SGregory Neil Shapiro **
10340266059SGregory Neil Shapiro **	Returns:
10440266059SGregory Neil Shapiro **		0 on success
10540266059SGregory Neil Shapiro **		< 0 on failure.
10640266059SGregory Neil Shapiro */
10740266059SGregory Neil Shapiro 
10840266059SGregory Neil Shapiro int shmbig __P((bool, int));
10940266059SGregory Neil Shapiro 
11040266059SGregory Neil Shapiro int
11140266059SGregory Neil Shapiro shmbig(owner, size)
11240266059SGregory Neil Shapiro 	bool owner;
11340266059SGregory Neil Shapiro 	int size;
11440266059SGregory Neil Shapiro {
11540266059SGregory Neil Shapiro 	int *shm, shmid;
11640266059SGregory Neil Shapiro 	int i;
11740266059SGregory Neil Shapiro 
11840266059SGregory Neil Shapiro 	shm = (int *) sm_shmstart(T_SHMKEY, size, 0, &shmid, owner);
11940266059SGregory Neil Shapiro 	if (shm == (int *) 0)
12040266059SGregory Neil Shapiro 	{
12140266059SGregory Neil Shapiro 		perror("shminit failed");
12240266059SGregory Neil Shapiro 		return -1;
12340266059SGregory Neil Shapiro 	}
12440266059SGregory Neil Shapiro 
12540266059SGregory Neil Shapiro 	for (i = 0; i < size / sizeof(int); i++)
12640266059SGregory Neil Shapiro 		shm[i] = i;
12740266059SGregory Neil Shapiro 	for (i = 0; i < size / sizeof(int); i++)
12840266059SGregory Neil Shapiro 	{
12940266059SGregory Neil Shapiro 		if (shm[i] != i)
13040266059SGregory Neil Shapiro 		{
13140266059SGregory Neil Shapiro 			fprintf(stderr, "failed at %d: %d", i, shm[i]);
13240266059SGregory Neil Shapiro 		}
13340266059SGregory Neil Shapiro 	}
13440266059SGregory Neil Shapiro 
13540266059SGregory Neil Shapiro 	return sm_shmstop((void *) shm, shmid, owner);
13640266059SGregory Neil Shapiro }
13740266059SGregory Neil Shapiro 
13840266059SGregory Neil Shapiro 
13940266059SGregory Neil Shapiro /*
14040266059SGregory Neil Shapiro **  SHMTEST -- test of shared memory
14140266059SGregory Neil Shapiro **
14240266059SGregory Neil Shapiro **	Parameters:
14340266059SGregory Neil Shapiro **		owner -- create segment.
14440266059SGregory Neil Shapiro **
14540266059SGregory Neil Shapiro **	Returns:
14640266059SGregory Neil Shapiro **		0 on success
14740266059SGregory Neil Shapiro **		< 0 on failure.
14840266059SGregory Neil Shapiro */
14940266059SGregory Neil Shapiro 
15040266059SGregory Neil Shapiro # define MAX_CNT	10
15140266059SGregory Neil Shapiro 
152b6bacd31SGregory Neil Shapiro int shmtest __P((int));
153b6bacd31SGregory Neil Shapiro 
15440266059SGregory Neil Shapiro int
15540266059SGregory Neil Shapiro shmtest(owner)
15640266059SGregory Neil Shapiro 	int owner;
15740266059SGregory Neil Shapiro {
15840266059SGregory Neil Shapiro 	int *shm, shmid;
15940266059SGregory Neil Shapiro 	int cnt = 0;
16040266059SGregory Neil Shapiro 
16140266059SGregory Neil Shapiro 	shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
16240266059SGregory Neil Shapiro 	if (shm == (int *) 0)
16340266059SGregory Neil Shapiro 	{
16440266059SGregory Neil Shapiro 		perror("shminit failed");
16540266059SGregory Neil Shapiro 		return -1;
16640266059SGregory Neil Shapiro 	}
16740266059SGregory Neil Shapiro 
16840266059SGregory Neil Shapiro 	if (owner)
16940266059SGregory Neil Shapiro 	{
17040266059SGregory Neil Shapiro 		int r;
17140266059SGregory Neil Shapiro 
17213d88268SGregory Neil Shapiro 		r = sm_shmsetowner(shmid, getuid(), getgid(), 0660);
17313d88268SGregory Neil Shapiro 		SM_TEST(r == 0);
17440266059SGregory Neil Shapiro 		*shm = 1;
17540266059SGregory Neil Shapiro 		while (*shm == 1 && cnt++ < MAX_CNT)
17640266059SGregory Neil Shapiro 			sleep(1);
17740266059SGregory Neil Shapiro 		SM_TEST(cnt <= MAX_CNT);
17840266059SGregory Neil Shapiro 
17940266059SGregory Neil Shapiro 		/* release and re-acquire the segment */
18040266059SGregory Neil Shapiro 		r = sm_shmstop((void *) shm, shmid, owner);
18140266059SGregory Neil Shapiro 		SM_TEST(r == 0);
18240266059SGregory Neil Shapiro 		shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
18340266059SGregory Neil Shapiro 		SM_TEST(shm != (int *) 0);
18440266059SGregory Neil Shapiro 	}
18540266059SGregory Neil Shapiro 	else
18640266059SGregory Neil Shapiro 	{
18740266059SGregory Neil Shapiro 		while (*shm != 1 && cnt++ < MAX_CNT)
18840266059SGregory Neil Shapiro 			sleep(1);
18940266059SGregory Neil Shapiro 		SM_TEST(cnt <= MAX_CNT);
19040266059SGregory Neil Shapiro 		*shm = 2;
19140266059SGregory Neil Shapiro 
19240266059SGregory Neil Shapiro 		/* wait a momemt so the segment is still in use */
19340266059SGregory Neil Shapiro 		sleep(2);
19440266059SGregory Neil Shapiro 	}
19540266059SGregory Neil Shapiro 	return sm_shmstop((void *) shm, shmid, owner);
19640266059SGregory Neil Shapiro }
19740266059SGregory Neil Shapiro 
19840266059SGregory Neil Shapiro int
19940266059SGregory Neil Shapiro main(argc, argv)
20040266059SGregory Neil Shapiro 	int argc;
20140266059SGregory Neil Shapiro 	char *argv[];
20240266059SGregory Neil Shapiro {
20340266059SGregory Neil Shapiro 	bool interactive = false;
20440266059SGregory Neil Shapiro 	bool owner = false;
20540266059SGregory Neil Shapiro 	int big = -1;
20640266059SGregory Neil Shapiro 	int ch;
20740266059SGregory Neil Shapiro 	int r = 0;
20840266059SGregory Neil Shapiro 	int status;
20940266059SGregory Neil Shapiro 	extern char *optarg;
21040266059SGregory Neil Shapiro 
21140266059SGregory Neil Shapiro # define OPTIONS	"b:io"
21240266059SGregory Neil Shapiro 	while ((ch = getopt(argc, argv, OPTIONS)) != -1)
21340266059SGregory Neil Shapiro 	{
21440266059SGregory Neil Shapiro 		switch ((char) ch)
21540266059SGregory Neil Shapiro 		{
21640266059SGregory Neil Shapiro 		  case 'b':
21740266059SGregory Neil Shapiro 			big = atoi(optarg);
21840266059SGregory Neil Shapiro 			break;
21940266059SGregory Neil Shapiro 
22040266059SGregory Neil Shapiro 		  case 'i':
22140266059SGregory Neil Shapiro 			interactive = true;
22240266059SGregory Neil Shapiro 			break;
22340266059SGregory Neil Shapiro 
22440266059SGregory Neil Shapiro 		  case 'o':
22540266059SGregory Neil Shapiro 			owner = true;
22640266059SGregory Neil Shapiro 			break;
22740266059SGregory Neil Shapiro 
22840266059SGregory Neil Shapiro 		  default:
22940266059SGregory Neil Shapiro 			break;
23040266059SGregory Neil Shapiro 		}
23140266059SGregory Neil Shapiro 	}
23240266059SGregory Neil Shapiro 
23340266059SGregory Neil Shapiro 	if (interactive)
23440266059SGregory Neil Shapiro 		r = shminter(owner);
23540266059SGregory Neil Shapiro 	else if (big > 0)
23640266059SGregory Neil Shapiro 		r = shmbig(true, big);
23740266059SGregory Neil Shapiro 	else
23840266059SGregory Neil Shapiro 	{
23940266059SGregory Neil Shapiro 		pid_t pid;
240605302a5SGregory Neil Shapiro 		extern int SmTestNumErrors;
24140266059SGregory Neil Shapiro 
24240266059SGregory Neil Shapiro 		if ((pid = fork()) < 0)
24340266059SGregory Neil Shapiro 		{
24440266059SGregory Neil Shapiro 			perror("fork failed\n");
24540266059SGregory Neil Shapiro 			return -1;
24640266059SGregory Neil Shapiro 		}
24740266059SGregory Neil Shapiro 
24840266059SGregory Neil Shapiro 		sm_test_begin(argc, argv, "test shared memory");
24940266059SGregory Neil Shapiro 		if (pid == 0)
25040266059SGregory Neil Shapiro 		{
25140266059SGregory Neil Shapiro 			/* give the parent the chance to setup data */
25240266059SGregory Neil Shapiro 			sleep(1);
25340266059SGregory Neil Shapiro 			r = shmtest(false);
25440266059SGregory Neil Shapiro 		}
25540266059SGregory Neil Shapiro 		else
25640266059SGregory Neil Shapiro 		{
25740266059SGregory Neil Shapiro 			r = shmtest(true);
25840266059SGregory Neil Shapiro 			(void) wait(&status);
25940266059SGregory Neil Shapiro 		}
26040266059SGregory Neil Shapiro 		SM_TEST(r == 0);
261605302a5SGregory Neil Shapiro 		if (SmTestNumErrors > 0)
262605302a5SGregory Neil Shapiro 			printf("add -DSM_CONF_SHM=0 to confENVDEF in devtools/Site/site.config.m4\nand start over.\n");
26340266059SGregory Neil Shapiro 		return sm_test_end();
26440266059SGregory Neil Shapiro 	}
26540266059SGregory Neil Shapiro 	return r;
26640266059SGregory Neil Shapiro }
26740266059SGregory Neil Shapiro #else /* SM_CONF_SHM */
26840266059SGregory Neil Shapiro int
26940266059SGregory Neil Shapiro main(argc, argv)
27040266059SGregory Neil Shapiro 	int argc;
27140266059SGregory Neil Shapiro 	char *argv[];
27240266059SGregory Neil Shapiro {
27340266059SGregory Neil Shapiro 	printf("No support for shared memory configured on this machine\n");
27440266059SGregory Neil Shapiro 	return 0;
27540266059SGregory Neil Shapiro }
27640266059SGregory Neil Shapiro #endif /* SM_CONF_SHM */
277