Open and check the shared memory

Updated: May 06, 2022

The next step in processing is to open the shared memory region. If one already exists, we invalidate it and remove it, and then try to open it again (error messages in code not shown):

...

  sts = shm_open (opts, O_RDWR | O_CREAT | O_EXCL, 0644);
  if (sts == -1) {
    if (errno == EEXIST) {

      // in the case that it already exists, we'll wipe the
      // signature of the existing one and unlink it.
      sts = shm_open (opts, O_RDWR, 0);
      if (sts == -1) {
        exit (EXIT_FAILURE);
      }

      // map it in so we can wipe it
      shmem_ptr = mmap (0, 4096, PROT_READ | PROT_WRITE,
                        MAP_SHARED, sts, 0);
      if (shmem_ptr == MAP_FAILED) {
        exit (EXIT_FAILURE);
      }

      // wipe it
      memset (shmem_ptr, 0, 4096);
      close (sts);
      munmap (shmem_ptr, 4096);
      shm_unlink (opts);

      // now try again to open it!
      sts = shm_open (opts, O_RDWR | O_CREAT | O_EXCL, 0644);
      if (sts == -1) {
        exit (EXIT_FAILURE);
      }
    } else {
      // if the initial open failed for any reason
      // *other than* EEXIST, die.
      exit (EXIT_FAILURE);
    }
  }
  shmem_fd = sts;
...

The first call to shm_open() uses the O_CREAT and O_EXCL flags. These indicate that the shared memory region is being created, and must not already exist. Notice that the work involved in wiping the signature is the same work that we must do later to map the shared memory region into our address space.

At this point, we now have shmem_fd as the shared memory file descriptor.