为什么在调用shm_open之前先调用shm_unlink?

我在遗留项目中看到了以下代码模式:

  1. 检查是否使用名称“/ abc”创build了共享内存

    int fd = shm_open("/abc", O_RDWR, 0777); if(fd != -1) { close(fd); return -1; } 
  2. 删除以前由shm_open()创build的对象:

     shm_unlink("/abc"); 
  3. 创build一个共享内存对象:

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

第2步是多余的吗?

代码可以运行到步骤2,因为共享内存对象不存在“/ abc”。 换句话说,如果对象确实存在,代码就会返回。 为什么我们应该明确地调用shm_unlink去除不存在的对象?

我们能把三步缩短到一步吗?

我认为我们可以按照以下步骤进行操作,我们使用标志O_EXCL来检查是否存在一个旧的内存对象,如果它不存在,就创build它。 shm_open()手册页说:

O_EXCL

如果还指定了O _CREAT ,并且具有给定名称的共享内存对象已经存在,则返回错误。 对象的存在检查,如果它不存在,它的创build是自动执行的。

所以应该可以用一行代替上面所有的代码:

 int fd = shm_open("/abc", O_RDWR | O_EXCL, 0777); 

那是对的吗?

第2步是多余的吗?

它是。 它没有任何用处。

除此之外,“检查存在”也容易出现TOCTOU漏洞。

我们能否一步缩短上述三步

是。 这是正确的方式去做。 但是你也需要O_CREAT标志(在你的代码中缺少)。