Shared Memory Code Snippet in C - c

I came across the following code snippet
int seg1 = shmget( number, 1, 0660 );
if( -1 != seg1 )
{
struct shmid_ds buf;
shmctl( seg1, IPC_RMID, &buf );
fprintf( stderr, "Removed existing shared memory segment" );
}
int seg = shmget( number, 2 * size, IPC_CREAT | 0660 );
Buffer = (char*) shmat( seg, NULL, 0 );
Questions:
1) shmget( number, 1, 0660 )
f IPC_CREAT or IPC_EXCL is not specified and only 0660 is specified, what's the default IPC_ ? The does not explain this/
2) Why would one want to do a shmget for a key number with a size of 1 byte, then do a IPC_RMID and then again do a shmget of the same key with the bigger space ?

1) shmget( number, 1, 0660 ) f IPC_CREAT or IPC_EXCL is not specified and only 0660 is specified, what's the default IPC_ ? The does not explain this/
By default, neither option applies. The segment is only opened if it already exists.
2) Why would one want to do a shmget for a key number with a size of 1 byte, then do a IPC_RMID and then again do a shmget of the same key with the bigger space ?
The purpose is just to remove an existing shared memory segment regardless of its size. The shmget function will fail if size is bigger than the size of the existing segment, so using one ensures it doesn't fail.

Related

How to check if shared memory exists using shmget or ftok?

I am writting project in c using shared memory via shm functions. I want to try to "connect" to shared memory and check if it exists using shmget() function.
I tried a few flags with this function but failed to achieve expected result. I wonder if there is a way to see whether a shared memory already exists.
The manual page spells this out rather explicitly.
int shmget(key_t key, size_t size, int shmflg);
If shmflg specifies both IPC_CREAT and IPC_EXCL and a shared memory segment already exists for key, then shmget() fails with errno set to EEXIST.
And again, the flags:
IPC_CREAT
Create a new segment. If this flag is not used, then shmget() will find the segment associated with key and check to see if the user has permission to access the segment.
IPC_EXCL
This flag is used with IPC_CREAT to ensure that this call creates the segment. If the segment already exists, the call fails.
Alternatively, if the flag IPC_CREAT is not specified, and no memory segment exists for the given key, then shmget fails and sets errno to ENOENT.
ENOENT
No segment exists for the given key, and IPC_CREAT was not specified.
So you may want to try something along the lines of
errno = 0;
if (-1 == shmget(key, size, IPC_CREAT | IPC_EXCL)) {
if (EEXIST == errno) {
/* shared memory already exists */
}
}
or
errno = 0;
if (-1 == shmget(key, size, 0)) {
if (ENOENT == errno) {
/* shared memory does not exist */
}
}
On the other hand, ftok(3) fails for the same reasons as stat(2).

C linux shmget Invalid argument

int shmCreate(int id, int size)
{
int shmid
key_t key;
if ((key = ftok(".", id)) == -1) {
perror("ftok");
exit(1);
}
if ((shmid = shmget(key, size, IPC_CREAT | 0666)) == -1) {
perror("shmget");
exit(1);
}
return shmid;
}
I'm trying to write function which use shmget, where function gets size as parameter. I'm getting Invalid argument error all the time, except for size = 1. When I pass size other than 1 i got error, but the memory segment is created when i check ipcs -m, and it has size of 1. How do I get rid of this error?
According to the man page for shmget(2):
EINVAL A segment for the given key exists, but size is greater than
the size of that segment.
You cannot attach a segment that already exists with a larger size. So you need to remove it first or use a different key.

Shared Memory in C: Shmget Issues

int shmid;
int* locat;
//create shared memory segment
shmid = shmget(6666, size, 0666);
if (shmid < 0) {
perror("shmget");
exit(1);
}
locat = (int *) shmat(shmid, NULL, 0);
if (locat == (int *) -1) {
perror("shmat");
exit(1);
}
I am setting up shared memory as such, yet I keep getting this error: shmget: No such file or directory
This code was working fine, not sure why this occurs now.
As the man says
IPC_CREAT
Create a new segment. If this flag is not used, then shmget() will find the segment associated with key and check to see if the user has permission to access the segment.
You have to add IPC_CREAT to your shmget call
shmid = shmget(6666, size, IPC_CREAT | 0666);
You could also use the IPC_EXCL to ensure that the segment is newly created
IPC_EXCL
This flag is used with IPC_CREAT to ensure that this call
creates the segment. If the segment already exists, the
call fails.
There are two things :
When you want to initialize a shared memory ( corresponding to a particular key value ) , you have to BITWISE OR the permission number with IPC_CREAT.
Just like
shmget(6666 , size , 0666|IPC_CREAT);
When you want to attach the same segment ( identified by the key value ) to another process , IPC_CREAT is not mandatory as the shared memory has already been created the the logical address space.

Shmget: Invalid argument. Why i get this error?

I get a "shmget: Invalid argument error" while i try to execute this part of code
int *nFS, *spb, *cell1, shmid;
key_t key = 5768;
//i need a shared memory segment in which i can put 3 ints
if ((shmid = shmget(key, (sizeof(int) * 3), IPC_CREAT | 0666)) < 0 ) {
perror("shmget");
exit(1);
}
if ((spb = (int)shmat(shmid, NULL, 0))== -1 ){
perror("shmat");
exit(1);
}
cell1= spb + 1 ;
nFS= cell1 + 1;
//i try to assign here 7 to nFS
*nFS=7;
there is something wrong here but i can't figure out what. Can you help me?
Thanks, Alex.
From the shmget(1) man page:
EINVAL A new segment was to be created and size < SHMMIN or size >
SHMMAX, or no new segment was to be
created, a segment with given key existed, but size is greater than the size of that segment.
You should check whether you still have an segment for this key using ipcs and remove it with ipcrm.
In my case, the value of the size_t __size parameter was less than 0.
For reference, shmget() is prototyped as:
int shmget(key_t __key, size_t __size, int __shmflg)

Segment violation on attempt to initialize a memory mapped file

The following is code I've used to create a memory mapped file:
fid = open(filename, O_CREAT | O_RDWR, 0660);
if ( 0 > fid )
{
throw error;
}
/* mapped offset pointer to data file */
offset_table_p = (ubyte_2 *) shmat(fid, 0, SHM_MAP);
/* Initialize table */
memset(offset_table_p, 0x00, (table_size + 1) * 2);
say table_size is around 2XXXXXXXX bytes.
During debug, I've noticed it fails while attempt to initializing the 'offset table pointer',
Can anyone provide me some inputs on why it's failing during intilalization?
is there any possibilities that my memory map file was not created with required table size?
As far as I can tell from reading documentation, you are doing it completely wrong.
Either use open() and mmap() or use shmget() and shmat().
If you use open() you will need to make the file long enough first. Use ftruncate() for that.
First things first:
Examine the file both before and after the open() call. If on Linux, you can use the code:
char paxbuff[1000]; // at start of function
sprintf (paxbuff,"ls -al %s",filename);
system (paxbuff);
fid = open(filename, O_CREAT | O_RDWR, 0660); // this line already exists.
system (paxbuff);
Then, after you call shmat(), check the return values and size thus:
offset_table_p = (ubyte_2 *) shmat(fid, 0, SHM_MAP); // already exists.
printf ("ret = %p, errno = %d\n",offset_table_p,errno);
printf ("sz = %d\n",table_size);
That should be enough to work out the problem.

Resources