shm_open_handle(), shm_open_handle_pid()

QNX SDP8.0C Library ReferenceAPIDeveloper

Open a shared memory object based on a handle

Synopsis:

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

int shm_open_handle( shm_handle_t const handle,
                     int const flags );

int shm_open_handle_pid( shm_handle_t const handle,
                         int const flags,
                         pid_t pid );

Arguments:

handle
A handle created for the calling process by shm_create_handle().
flags
A combination of the following bits (defined in <fcntl.h>):
  • O_RDONLY — open for read access only.
  • O_RDWR — open for read and write access.
  • O_WRONLY — open for write access only.
Note:
You can also specify O_CLOEXEC but this flag has no effect because it's always set (see below). Setting any other flags causes the function call to fail.
pid
(shm_open_handle_pid() only) The PID of the process that created the handle, or zero (0) for any process. For a nonzero value, the OS verifies that the given PID matches that of the handle creator; if it doesn't, the call fails. For a zero value, the OS doesn't perform the PID check.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The shm_open_handle() function returns a file descriptor that's associated with the shared memory object specified by handle. 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 automatically set for this file descriptor.

The handle argument must have been created with shm_create_handle() specifically for the calling process (i.e., the recipient). This is typically (but doesn't have to be) done in another process. For an example of how a client can request the creation of a handle from a server and then use that handle to access the shared memory, see below.

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.

The shm_open_handle_pid() function provides increased security because it allows a process to verify that a given handle came from a particular process (pid). This is helpful in situations when a process that wants to use a shared memory object (the consumer) might have received handles from multiple processes that created handles (producers) but doesn't trust at least one of them.

Suppose that you have two producers that have legitimately registered handles. Let's say the purpose of the consumer is to dump everything that it receives from producer A into a social media account. Producer A stores some harmless cat videos in its shared memory object, which is assigned handle 1234. Producer B writes some sensitive video content from a security camera in its shared memory object, which is assigned handle 5678. When producer A (the bad, untrustworthy producer) sends a message to the consumer, it tells the consumer to use producer B's handle, 5678. If the consumer uses shm_open_handle_pid() to verify the PID of producer A (the supposed handle creator), the call will fail and, thus, the consumer won't leak the sensitive content to the rest of the world.

Often, the consumer already knows the producer's PID. If not, the consumer can find the PID by calling ConnectServerInfo() if it is the client or ConnectClientInfo() if it is the server.

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 access the shared memory object is denied because the access modes specified by flags are denied.
EAGAIN
There are insufficient resources to complete the operation.
EINVAL
An illegal flag, meaning a flag other than one indicating the access mode, was given in flags (see the parameter description).
EMFILE
All file descriptors available to the process are currently open.
ENFILE
Too many shared memory objects are currently open in the system.
ENOMEM
There's insufficient memory to open a file descriptor.
ESRCH
One of the following occurred:
  • The specified handle does not exist.
  • (shm_open_handle_pid() only) The specified PID doesn't match the PID of the process that created the handle.

Example:

int fd, shm_fd;
// Your application will likely have its own data structure for representing messages
// to send to the server.
mymsg_t msg;
shm_handle_t handle;
void* ptr;

// Connect to the server.
fd = open("/path/to/server", O_RDWR);

// The code for handling a failed open attempt and for populating the message structure
// (assuming the open did not fail) goes here.

// Ask the server for a handle.
MsgSend(fd, &msg, sizeof(msg), &handle, sizeof(handle));

// Convert the handle to a file descriptor.
shm_fd = shm_open_handle(handle, O_RDWR);

// Map the shared memory object into the client's space.
// The memory region mapped in is equal in size to one memory page, can be read
// but not written by the calling process, and can be shared with other processes.
ptr = mmap(0, __PAGESIZE, PROT_READ, MAP_SHARED, shm_fd, 0);

Classification:

QNX OS

Safety:
Cancellation pointNo
Signal handlerYes
ThreadYes
Page updated: