shm_open()
Open a shared memory object based on a pathname
Synopsis:
#include <fcntl.h>
#include <sys/mman.h>
int shm_open( const char * name,
int oflag,
mode_t mode );
Arguments:
- name
- The name of the shared memory object that you want to create or access. If you pass SHM_ANON for name, then O_ANON and O_CREAT are set. For more information, see below.
- oflag
- The file status flags and the file access modes of the open file description are set according to the value of oflag. Construct the value of oflag by bitwise ORing values from the following list, defined in the <fcntl.h> header file.
- mode
- 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. For more information, see the entries for umask(), and struct stat.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The shm_open() function returns a file descriptor that's associated with the shared memory object specified by name. This file descriptor can be used by other functions to refer to the shared memory object (e.g., mmap()). The FD_CLOEXEC flag in fcntl() is set for this file descriptor.
If you use the file descriptor to create a handle to the object (with shm_create_handle()) for sharing with a recipient process, the handle can support an access mode that's as privileged as or less privileged than what's indicated in oflag for shm_open(). For example, if oflag is set to O_RDWR, a process can create a handle to allow O_RDWR, O_RDONLY, or O_WRONLY access to the object. But if oflag is set to O_RDONLY, the handle can support O_RDONLY access but not O_RDWR or O_WRONLY access.
name | Pathname space entry |
---|---|
SHM_ANON | — |
entry | /dev/shmem/CWD/entry |
/entry | /dev/shmem/entry |
where CWD is the current working directory for the program at the point that it calls shm_open().
The state of the shared memory object, including all data associated with it, persists until the object is unlinked and all other references are gone.
Returns:
A nonnegative integer, which is the lowest numbered unused file descriptor, or -1 if an error occurred (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
- All file descriptors available to the process are currently open.
- ENAMETOOLONG
- The length of the name argument exceeds PATH_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.
- ENOMEM
- There's insufficient memory to open a file descriptor.
- EOVERFLOW
- The size of the shared memory object can't be represented correctly as a 32-bit offset, and O_LARGEFILE wasn't specified.
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:
Safety: | |
---|---|
Cancellation point | No |
Signal handler | Yes |
Thread | Yes |