[comp.unix.questions] Shared memory/Semaphore problem on Sun4/260

armor@saturn.cs.swin.OZ.AU (Eric Voxvold) (03/01/91)

Running a simple semaphore test program and a shared memory
program, correct execution will occur on the sun3 but on the
sun4/260 an invalid argument error occurs on the shmget and semget
system calls.  The operating system is sunOS 4.0.3.

Below are the offending programs:

/* semaphore.c */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>

#define SEMKEY	7
#define	IFLAGS	(IPC_CREAT)



static int semid;
struct sembuf p1 = {0,1,0}, p2 = {0,-1,0};

getsem_()
{
	if((semid = semget(SEMKEY,1,0600)) < 0)
	{
		if((semid = semget(SEMKEY,1,0600|IFLAGS)) < 0)
			fatal("semget");
		if(semctl(semid,0,SETVAL,1)<0)
			fatal("semctl");
	}
}
removesem_()
{
	int val1,val2;
	val1 = semctl(semid,0,GETNCNT,val1);
	val2 = semctl(semid,0,GETZCNT,val2);
	if((val1 < 1) && (val2 <1))
		semctl(semid,0,IPC_RMID,val1);
}

		
sem4wt_()
{
	semop(semid,&p2,1);
}
sem4nf_()
{
	semop(semid,&p1,1);
}
sem4dr_()
{
	if(semctl(semid,0,SETVAL,1)<0)
		fatal("semctl");
}
	

fatal(s)
char *s;
{
	perror(s);
	exit(1);
}

/* semtest.c */


main()
{
	int pid;

	switch((pid = fork())){
		case 0:
			test();
			break;

		default: 
			test();
			break;
	}
}

test()
{
	char c;
	getsem_();
	sem4wt_();
	printf("hi there, enter 'y' to exit: ");
	while((c = getchar()) != 'y')
		;
	sem4nf_();
	removesem_();
}

/* shmemtest.c */

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>

#define SHMKEY	1
#define	IFLAGS	(IPC_CREAT)
#define ERR	((int *) -1)




static int shmid;
static int length[5];
static char *shmptr;


getseg_(p)
int **p;

{
	char *shmat();

	if((shmid = shmget(SHMKEY,sizeof(int) ,0666|IFLAGS)) < 0)
		fatal("shmget");

	if((*p = (int *)shmat(shmid,0,0)) == ERR)
		fatal("shmat");
}

/*	If there are other processes attached to the shared memory */
/*	segment removeshm_ just detaches the process' shmptr from  */
/*      the shared memory segment.  Otherewise removeshm_ removes  */
/*	the shared memory segment from the system.                 */
removeshm_()
{
	struct shmid_ds buf;

	shmctl(shmid,IPC_STAT,&buf);
	if(buf.shm_nattch == 1)
		if(shmctl(shmid,IPC_RMID,(struct shmid_ds *)0)<0)
			fatal("shmctl");
	else
		shmdt(shmid);
}
fatal(s)
char *s;
{
	perror(s);
	exit(1);
}

main()
{
	int *p, pid,*s, x;

	x = 0;
	s = &x;
	getseg_(&p);
	(*p) = 0;

	printf("shared int = %d\n",*p);
	printf("unshared int = %d\n\n",*s);
	switch((pid = fork())){
		case 0:
			test1(p,s);
			break;
	        default:
			test2(p,s);
			break;
		}
	printf("shared int = %d\n",*p);
	printf("unshared int = %d\n\n",*s);
	removeshm_();
}
test1(p,q)
int *p, *q;
{
	char c;
	while ((c = getchar()) != '1')
		;
	(*p)++;
	(*q)++;
}
test2(p,q)
int *p, *q;
{
	char c;
	while ((c = getchar()) != '2')
		;
	(*p)++;
	(*q)++;
}