[net.unix-wizards] Shared Memory Problem

holloway@drivax.UUCP (Bruce Holloway) (04/01/86)

I'm having a problem with the shared memory routines under System V, and
I wonder if any gurus out there could help me....

I'm trying to create a shared memory segment, and put its base address into
a structure pointer. Everything seems fine until I actually try to use
the memory, when I get a core dump.

What am I doing wrong? (My code included).

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

#define	FALSE	0
#define	TRUE	1

#define	WAITING	1
#define	GOING	2

#define	MES	struct _mes
MES{
    int mes_flags;
    char mes_mes[80];
} *mes;

extern int errno;

extern char *shmat();

main(acnt,avar)
int acnt;
char *avar[];
{
    extern key_t ftok();
    key_t key;
    int shmid, fatal;
    char *mm;

    printf("Calling path is: %s\n",avar[0]);
    key = ftok(avar[0],'B');
    if(key == (key_t)-1){ printf("Couldn't make key\n"); return; }
    else printf("Key is %ld\n",(long)key);

    shmid = shmget(key, sizeof(MES), IPC_CREAT | IPC_EXCL);

    if(shmid<0){
	fatal = FALSE;
	switch(errno){
	    case EINVAL:
		mm = "Size is out of legal bounds";
		fatal = TRUE;
		break;
	    case EACCES:
		mm = "Access not granted";
		fatal = TRUE;
		break;
	    case ENOENT:
		mm = "Not creating a shmid, and one does not exist";
		fatal = TRUE;
		break;
	    case ENOSPC:
		mm = "Too many shmids already.";
		fatal = TRUE;
		break;
	    case ENOMEM:
		mm = "Not enough memory to fill request.";
		fatal = TRUE;
		break;
	    case EEXIST:
		mm = "A shmid already exists. We are not first.";
		break;
	    default:
		mm = "Undefined error code.";
		fatal = TRUE;
		break;
	    }
	printf("ERROR(%d): %s\n",errno,mm);
	if(fatal) return;
	shmid = shmget(key, sizeof(MES), IPC_CREAT);
	receive(shmid);
	return;
	}
    send(shmid);
}

send(shmid)
int shmid;
{
    int mesnum = 1;

    printf("We are first. Sending first message.\n\n");

    mes = (MES *)shmat(shmid, (char *)0, 0);
    if(!mes){ printf("SHMAT failed!\n"); return; }

/* Core is dumped on next statement */

    mes->mes_flags = 0;

    putchar('!');

    while(1){
	sprintf(mes->mes_mes, "Message #%d!\n", mesnum++);
	mes->mes_flags |= WAITING;
	while(mes->mes_flags & WAITING);
	}
}

receive(shmid)
int shmid;
{
    printf("We are second. Waiting for messages.\n\n");

    mes = (MES *)shmat(shmid, (char *)0, 0);
    if(!mes){ printf("SHMAT failed!\n"); return; }

    while(1){

/* Core is dumped on this statement. */

	while(!(mes->mes_flags & WAITING));

	printf(mes->mes_mes);
	mes->mes_flags &= ~WAITING;
	}
}

-- 

+----------------------------------------------------------------------------+
|Whatever I write are not the opinions or policies of Digital Research, Inc.,|
|and probably won't be in the foreseeable future.                            |
+----------------------------------------------------------------------------+

Bruce Holloway

....!ucbvax!hplabs!amdahl!drivax!holloway
(I'm not THAT Bruce Holloway, I'm the other one.)

keith@enmasse.UUCP (Keith Crews) (04/02/86)

In article <367@drivax.UUCP> holloway@drivax.UUCP (Bruce Holloway) writes:
>I'm having a problem with the shared memory routines under System V, and
>I wonder if any gurus out there could help me....
>
>I'm trying to create a shared memory segment, and put its base address into
>a structure pointer. Everything seems fine until I actually try to use
>the memory, when I get a core dump.
>
>What am I doing wrong? (My code included).
>
>    shmid = shmget(key, sizeof(MES), IPC_CREAT | IPC_EXCL);
>

You need to give access attributes on this shmget.  Eg

	IPC_CREAT | IPC_EXCL | 0666

	Keith Crews

Liz_Watson%anvil.UUCP@harvard.harvard.edu (04/03/86)

Bruce Holloway writes:
>I'm having a problem with the shared memory routines under System V, and
>I wonder if any gurus out there could help me....
>
>    mes = (MES *)shmat(shmid, (char *)0, 0);
>    if(!mes){ printf("SHMAT failed!\n"); return; }
>
>/* Core is dumped on next statement */
>
>    mes->mes_flags = 0;
>

First, fix up your error check on the shmat.  When shmat
fails, it returns a -1.  This causes your core dump.

The shmat call fails because the shmget call did not give
adequate (any) permissions.  The shmat requires at least
read permission.  The permissions are set by shmget,
using the low-order 9 bits of shmflag.


Liz Watson
Stratus Comp