Reputation: 35982
I have seen the following code pattern in a legacy project:
Check whether the shared-memory has been created with name "/abc":
int fd = shm_open("/abc", O_RDWR, 0777);
if(fd != -1)
{
close(fd);
return -1;
}
Remove an object previously created by shm_open()
:
shm_unlink("/abc");
create a shared memory object:
fd = shm_open("/abc", (O_CREAT | O_RDWR), S_IWUSR);
The code can run into Step 2 because the shared-memory object doesn't exist for "/abc". In other words, the code returns if the object does exist. Why should we explicitly call shm_unlink to remove the non-existing object?
I think we can proceed as follows, where we use the flag O_EXCL
to check whether there exists an old memory object and create it if it doesn't exist at all. The shm_open()
man page says:
O_EXCL
If O
_CREAT
was also specified, and a shared memory object with the given name already exists, return an error. The check for the existence of the object, and its creation if it does not exist, are performed atomically.
So it should be okay to replace all the code above with a single line:
int fd = shm_open("/abc", O_RDWR | O_EXCL, 0777);
Is that correct?
Upvotes: 3
Views: 1119
Reputation: 121377
Is the Step 2 redundant?
It is. It serves no purpose.
Besides this "check-for-existence" is prone to TOCTOU vulnerability.
Can we shorten the 3-step above as a single step
Yes. That's the right way to go about it. But you'll also need O_CREAT
flag (which is missing in your code).
Upvotes: 4