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

时间:2017-09-21 14:44:37

标签: c linux shared-memory

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

  1. 检查是否已使用名称“/ abc”创建共享内存:

    save_btn = new AjaxSubmitLink("submit_btn", this) {                
      protected void onSubmit(AjaxRequestTarget art){
        art.appendJavaScript("e.preventDefault();");
      }
    };
    
  2. 删除以前由getRequestCycleSettings().setRenderStrategy(RequestCycleSettings.RenderStrategy.ONE_PASS_RENDER); 创建的对象:

    int fd = shm_open("/abc", O_RDWR, 0777);
    if(fd != -1)
    {
      close(fd);
      return -1;
    }
    
  3. 创建共享内存对象:

    shm_open()
  4. 第2步是多余的吗?

    代码可以进入第2步,因为“/ abc”不存在共享内存对象。换句话说,如果对象确实存在,则代码返回。我们为什么要显式调用shm_unlink来删除不存在的对象?

    我们可以将这三个步骤缩短为一个吗?

    我认为我们可以按照以下步骤进行操作,我们使用标志shm_unlink("/abc"); 来检查是否存在旧的内存对象,如果它根本不存在则创建它。 shm_open()手册页说:

      

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

         

    如果还指定了O O_EXCL,则还有共享内存对象                         如果给定名称已存在,则返回错误。该                         检查对象的存在,以及它的创建                         它不存在,是以原子方式进行的。

    所以用一行代替上面的所有代码应该没问题:

    O_EXCL

    这是对的吗?

1 个答案:

答案 0 :(得分:4)

  

第2步是多余的吗?

是的。它没有用处。

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

  

我们可以将上述3步缩短为一步

是。这是正确的方法。但是你还需要O_CREAT标志(代码中缺少)。