q0987
q0987

Reputation: 35982

Why call shm_unlink first before calling shm_open?

I have seen the following code pattern in a legacy project:

  1. 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;
    }
    
  2. Remove an object previously created by shm_open():

    shm_unlink("/abc");
    
  3. create a shared memory object:

    fd = shm_open("/abc", (O_CREAT | O_RDWR), S_IWUSR);
    

Is Step 2 redundant?

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?

Can we shorten the three steps to just one?

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

Answers (1)

P.P
P.P

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

Related Questions