Reputation: 687
Receiving the message "Invalid argument" when using shmget with the second parameter not being NULL.
It compiles ok, but when executing, I get this error message.
I've been stuck on this all day long. Hope you can help me! :)
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
int idSharedMem;
int *varSharedMem1;
int *varSharedMem2;
/* Create the shared memory */
idSharedMem = shmget((key_t) 0001, sizeof(int), IPC_CREAT | 0666);
if (idSharedMem == -1)
{
perror("shmget");
}
/* Allocate a memory address and attached it to a variable */
varSharedMem1 = shmat(idSharedMem, NULL, 0);
if (varSharedMem1 == (int *) -1)
{
perror("shmat1");
}
/* Sign a value to the variable */
*varSharedMem1 = 5;
/* Attach an existing allocated memory to another variable */
varSharedMem2 = shmat(idSharedMem, varSharedMem1, 0);
if (varSharedMem2 == (int *) -1)
{
/* PRINTS "shmat2: Invalid argument" */
perror("shmat2");
}
/* Wanted it to print 5 */
printf("Recovered value %d\n", *varSharedMem2);
return(0);
}
Upvotes: 3
Views: 3615
Reputation: 229058
With shmat(idSharedMem, varSharedMem1, 0);
you're trying to attach the segment at the location of varSharedMem1
. However you have previously attached a segment at that location which will result in EINVAL. Linux provides a SHM_REMAP flag you can use to replace previously mapped segments.
shmat manpage:
The (Linux-specific) SHM_REMAP flag may be specified in shmflg to indicate that the mapping of the segment should replace any existing mapping in the range starting at shmaddr and continuing for the size of the segment. (Normally an EINVAL error would result if a mapping already exists in this address range.) In this case, shmaddr must not be NULL.
Upvotes: 4
Reputation: 3089
From shmat man page:
If shmaddr isn't NULL and SHM_RND is specified in shmflg, the attach occurs at the
address equal to shmaddr rounded down to the nearest multiple of SHMLBA.
Otherwise shmaddr must be a page-aligned address at which the attach occurs.
more from shmat man page:
Using shmat() with shmaddr equal to NULL is the preferred, portable way of
attaching a shared memory segment.
To make a second attach, just:
varSharedMem2 = shmat(idSharedMem, NULL, 0);
Upvotes: 1