[Previous] [Contents] [Next]

shm_open()

Open a shared memory object

Synopsis:

#include <fcntl.h>
#include <sys/mman.h>

int shm_open( const char * name,
              int oflag,
              mode_t mode );

Library:

libc

Description:

The shm_open() function returns a file descriptor that's associated with the shared "memory object" specified by name. This file descriptor is used by other functions to refer to the shared memory object (for example, mmap(), mprotect()). The FD_CLOEXEC file descriptor flag in fcntl() is set for this file descriptor.


Note: To conform to POSIX, the name of a shared memory object must begin with a slash (/) character and contain only one slash.

The state of the shared memory object, including all data associated with it, persists until the shared memory object is unlinked and all other references are gone.

The value of oflag is constructed by the bitwise ORing of the following flags. At least the following flag bits are defined in <fcntl.h>:

O_RDONLY
Open for read access only.
O_RDWR
Open for read and write access.
O_CREAT
If the shared memory object exists, this flag has no effect, except as noted under O_EXCL below. Otherwise, the shared memory object is created, and its permissions are set in accordance with the value of mode and the file mode creation mask of the process.
O_EXCL
If O_EXCL and O_CREAT are set, then shm_open() fails if the shared memory segment exists.

The check for the existence of the shared memory object, and the creation of the object if it doesn't exist, are atomic with respect to other processes executing shm_open(), naming the same shared memory object with O_EXCL and O_CREAT set.

O_TRUNC
If the shared memory object exists, and it's successfully opened O_RDWR, the object is truncated to zero length and the mode and owner are unchanged.

The permission bits for the memory object are set to the value of mode, except those bits set in the process's file creation mask (see the umask() function and <sys/stat.h>).

Returns:

A nonnegative integer, which is the lowest numbered unused file descriptor. Otherwise, -1 (errno is set).

Errors:

EACCES
Permission to create the shared memory object is denied.

The shared memory object exists and the permissions specified by oflag are denied, or O_TRUNC is specified and write permission is denied.

EEXIST
O_CREAT and O_EXCL are set, and the named shared memory object already exists.
EINTR
The shm_open() call was interrupted by a signal.
ELOOP
Too many levels of symbolic links or prefixes.
EMFILE
Too many file descriptors are currently in use by this process.
ENAMETOOLONG
The length of the name argument exceeds NAME_MAX.
ENFILE
Too many shared memory objects are currently open in the system.
ENOENT
O_CREAT isn't set, and the named shared memory object doesn't exist, or O_CREAT is set and either the name prefix doesn't exist or the name argument points to an empty string.
ENOSPC
There isn't enough space to create the new shared memory object.
ENOSYS
The shm_open() function isn't supported by this implementation.

Examples:

This example sets up a shared memory object, but doesn't really do anything with it:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <sys/mman.h>

int main( int argc, char** argv )
{
    int fd;
    unsigned* addr;

    /*
     * In case the unlink code isn't executed at the end
     */
    if( argc != 1 ) {
        shm_unlink( "/bolts" );
        return EXIT_SUCCESS;
    }

    /* Create a new memory object */
    fd = shm_open( "/bolts", O_RDWR | O_CREAT, 0777 );
    if( fd == -1 ) {
        fprintf( stderr, "Open failed:%s\n",
            strerror( errno ) );
        return EXIT_FAILURE;
    }
    
    /* Set the memory object's size */
    if( ftruncate( fd, sizeof( *addr ) ) == -1 ) {
        fprintf( stderr, "ftruncate: %s\n",
            strerror( errno ) );
        return EXIT_FAILURE;
    }

    /* Map the memory object */
    addr = mmap( 0, sizeof( *addr ),
            PROT_READ | PROT_WRITE,
            MAP_SHARED, fd, 0 );
    if( addr == MAP_FAILED ) {
        fprintf( stderr, "mmap failed: %s\n",
            strerror( errno ) );
        return EXIT_FAILURE;
    }

    printf( "Map addr is 0x%08x\n", addr );

    /* Write to shared memory */
    *addr = 1;

    /*
     * The memory object remains in
     * the system after the close
     */
    close( fd );

    /*
     * To remove a memory object
     * you must unlink it like a file.
     *
     * This may be done by another process.
     */
    shm_unlink( "/bolts" );

    return EXIT_SUCCESS;
}

This example uses a shared memory object to share data with a forked process:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>

main(int argc, char * argv[])
{
int        fd;
unsigned  *addr;

  /*
   * In case the unlink code isn't executed at the end
   */
  if (argc != 1) {
     shm_unlink("/bolts");
     return EXIT_SUCCESS;
  }

  /* Create a new memory object */
  fd = shm_open("/bolts", O_RDWR | O_CREAT, 0777);
  if (fd == -1) {
     fprintf(stderr, "Open failed : %s\n",
       strerror(errno));
     return EXIT_FAILURE;
  }

  /* Set the memory object's size */
  if (ftruncate(fd, sizeof(*addr)) == -1) {
     fprintf(stderr, "ftruncate : %s\n", strerror(errno));
     return EXIT_FAILURE;
  }

  /* Map the memory object */
  addr = mmap(0, sizeof(*addr), PROT_READ | PROT_WRITE,
               MAP_SHARED, fd, 0);
  if (addr == MAP_FAILED) {
     fprintf(stderr, "mmap failed:%s\n", strerror(errno));
     return EXIT_FAILURE;
  }

  printf("Map addr is %6.6X\n", addr);
  printf("Press break to stop.\n");
  sleep(3);    /* So you can read above message */

  /*
   * We unlink so object goes away on last close.
   */
  shm_unlink("/bolts");

  *addr = '0';
  if (fork())
     for (;;)
       if (*addr == '0')
         putc(*addr = '1', stderr);
       else
         sched_yield();
  else
    for (;;)
       if (*addr == '1')
         putc(*addr = '0', stderr);
       else
         sched_yield();
  return EXIT_SUCCESS;
}

Classification:

POSIX 1003.1 (Realtime Extensions)

Safety:
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes

See also:

errno, fcntl(), ftruncate(), mmap(), munmap(), mprotect(), open(), shm_ctl(), shm_unlink(), sysconf()


[Previous] [Contents] [Next]