Create a virtual mapping in the address space of another process
Synopsis:
#include <sys/mman_peer.h>
void *mmap_peer( pid_t pid,
void *addr,
size_t len,
int prot,
int flags,
int fd,
off_t off );
void *mmap64_peer( pid_t pid,
void *addr,
size_t len,
int prot,
int flags,
int fd,
off64_t off );
Arguments:
- pid
- The ID of the process in which you want to map memory.
- addr
- NULL, or a pointer to where you want the object to be mapped
in the specified process's address space.
- len
- The number of bytes to map into the specified process's address space.
Note that this value can't be 0.
- prot
- The access capabilities that you want to use for the memory region being mapped.
You can combine at least the following protection bits, as defined in
<sys/mman.h>:
- PROT_EXEC — the region can be executed.
Note: To successfully use this
flag:
- The calling process must have the PROCMGR_AID_PROT_EXEC
ability enabled. For more information, see procmgr_ability().
- PROT_NOCACHE — disable caching of the region
(e.g., so it can be used to access dual-ported memory).
Note:
On 32- and 64-bit ARM targets,
PROT_NOCACHE causes RAM to be mapped as normal noncached, but
non-RAM to be mapped as strongly ordered device memory.
For finer control, see
shm_ctl_special().
- PROT_NONE — the region can't be accessed.
- PROT_READ — the region can be read.
- PROT_WRITE — the region can be written.
Note:
In order to simultaneously set
PROT_EXEC and
PROT_WRITE,
the calling process must have the
PROCMGR_AID_PROT_WRITE_AND_EXEC ability enabled
(in addition to
PROCMGR_AID_PROT_EXEC).
For more information, see
procmgr_ability().
- flags
- Flags that specify further information about handling the mapped region.
For detailed information about the flags, see
mmap().
- fd
- The file descriptor for a shared memory object, or NOFD if you're mapping physical memory.
- off
- The offset into shared memory of the location that you want to start mapping.
Library:
libc
Use the -l c option to
qcc
to link against this library.
This library is usually included automatically.
Description:
The mmap_peer() function maps a region within the object of the specified process ID
beginning at off and
continuing for len into the address space, and returns the location.
The mmap64_peer() function is a large-file support version of mmap()
and is useful only on 32-bit architectures.
Note:
In QNX Neutrino 6.6 or later, the large-file support functions and data types
appear in the name space only if you define
_LARGEFILE64_SOURCE when you compile your code.
For more information, see
Classification
in What's in a Function Description?
The address returned by mmap_peer() is valid only in the context of the process
pid.
CAUTION:
We recommend that
mmap_peer() and
munmap_peer()
be called only
by a server on behalf of a client that's currently reply-blocked on the server and expects the message that
it sent to result in a change to its address space.
For example, the server can define a protocol that includes
ALLOC_BUFFER and
FREE_BUFFER
messages, making it explicit that the message will result in memory mapping and unmapping, respectively.
Otherwise the client's address space layout could unexpectedly change, leading to race conditions.
Consider using
shm_create_handle()
instead of mmap_peer().
The target process can:
- use
mprotect()
to increase permissions on whatever was mapped in, if the file descriptor allows those permissions
- unmap the memory
- use
fork()
to duplicate the mapping unbeknownst to the caller of mmap_peer()
Returns:
The address of the mapped-in object, or MAP_FAILED if an error occurred
(errno is set).
Errors:
In addition to the errno codes set by
mmap(),
the following can be set:
- ESRCH
- The process pid doesn't exist, is loading, or is terminating.
Example:
The following example forks into parent and child process, and the parent process waits for the child process
to terminate.
The child process does the following:
- performs mmap_peer() and stores the returned address
- checks to see if the mmap_peer() function failed
- performs munmap_peer() and verifies the return value
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <process.h>
#include <sys/mman.h>
int main(int argc, char *argv[])
{
pid_t pid;
pid_t parent_pid;
char buff[256];
const int mmap_len = 4096;
parent_pid = getpid();
pid = fork();
assert( pid != -1);
if( pid == 0 ) {
/* This is the child process */
void *ptr, *old_ptr;
int ret;
int failed;
failed = 0;
old_ptr = mmap_peer( parent_pid, 0, mmap_len, PROT_READ | PROT_WRITE,
MAP_SHARED, NOFD, 0);
if (old_ptr == MAP_FAILED) {
SPRNT( buff, sizeof(buff), "mmap_peer failed (errno %d)", errno);
failed++;
}
if (!failed) {
ret = munmap_peer(parent_pid, old_ptr, mmap_len);
if ( ret == -1 ) {
SPRNT( buff, sizeof(buff), "munmap_peer failed (errno %d)", errno);
failed++;
}
}
} else {
/* This is the parent process */
wait(NULL);
}
return EXIT_SUCCESS;
}
Classification:
mmap_peer() is
QNX Neutrino;
mmap64_peer() is
Large-file support
Safety: |
|
Cancellation point |
No |
Interrupt handler |
No |
Signal handler |
Yes |
Thread |
Yes |