summaryrefslogtreecommitdiffstats
path: root/man3/shm_open.3
diff options
context:
space:
mode:
Diffstat (limited to 'man3/shm_open.3')
-rw-r--r--man3/shm_open.3509
1 files changed, 509 insertions, 0 deletions
diff --git a/man3/shm_open.3 b/man3/shm_open.3
new file mode 100644
index 0000000..c5756c4
--- /dev/null
+++ b/man3/shm_open.3
@@ -0,0 +1,509 @@
+'\" t
+.\" Copyright (C) 2002, 2020 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH shm_open 3 2023-07-20 "Linux man-pages 6.05.01"
+.SH NAME
+shm_open, shm_unlink \- create/open or unlink POSIX shared memory objects
+.SH LIBRARY
+Real-time library
+.RI ( librt ", " \-lrt )
+.SH SYNOPSIS
+.nf
+.B #include <sys/mman.h>
+.BR "#include <sys/stat.h>" " /* For mode constants */"
+.BR "#include <fcntl.h>" " /* For O_* constants */"
+.PP
+.BI "int shm_open(const char *" name ", int " oflag ", mode_t " mode );
+.BI "int shm_unlink(const char *" name );
+.fi
+.SH DESCRIPTION
+.BR shm_open ()
+creates and opens a new, or opens an existing, POSIX shared memory object.
+A POSIX shared memory object is in effect a handle which can
+be used by unrelated processes to
+.BR mmap (2)
+the same region of shared memory.
+The
+.BR shm_unlink ()
+function performs the converse operation,
+removing an object previously created by
+.BR shm_open ().
+.PP
+The operation of
+.BR shm_open ()
+is analogous to that of
+.BR open (2).
+.I name
+specifies the shared memory object to be created or opened.
+For portable use,
+a shared memory object should be identified by a name of the form
+.IR /somename ;
+that is, a null-terminated string of up to
+.B NAME_MAX
+(i.e., 255) characters consisting of an initial slash,
+.\" glibc allows the initial slash to be omitted, and makes
+.\" multiple initial slashes equivalent to a single slash.
+.\" This differs from the implementation of POSIX message queues.
+followed by one or more characters, none of which are slashes.
+.\" glibc allows subdirectory components in the name, in which
+.\" case the subdirectory must exist under /dev/shm, and allow the
+.\" required permissions if a user wants to create a shared memory
+.\" object in that subdirectory.
+.PP
+.I oflag
+is a bit mask created by ORing together exactly one of
+.B O_RDONLY
+or
+.B O_RDWR
+and any of the other flags listed here:
+.TP
+.B O_RDONLY
+Open the object for read access.
+A shared memory object opened in this way can be
+.BR mmap (2)ed
+only for read
+.RB ( PROT_READ )
+access.
+.TP
+.B O_RDWR
+Open the object for read-write access.
+.TP
+.B O_CREAT
+Create the shared memory object if it does not exist.
+The user and group ownership of the object are taken
+from the corresponding effective IDs of the calling process,
+.\" In truth it is actually the filesystem IDs on Linux, but these
+.\" are nearly always the same as the effective IDs. (MTK, Jul 05)
+and the object's
+permission bits are set according to the low-order 9 bits of
+.IR mode ,
+except that those bits set in the process file mode
+creation mask (see
+.BR umask (2))
+are cleared for the new object.
+A set of macro constants which can be used to define
+.I mode
+is listed in
+.BR open (2).
+(Symbolic definitions of these constants can be obtained by including
+.IR <sys/stat.h> .)
+.IP
+A new shared memory object initially has zero length\[em]the size of the
+object can be set using
+.BR ftruncate (2).
+The newly allocated bytes of a shared memory
+object are automatically initialized to 0.
+.TP
+.B O_EXCL
+If
+.B O_CREAT
+was also specified, and a shared memory object with the given
+.I name
+already exists, return an error.
+The check for the existence of the object, and its creation if it
+does not exist, are performed atomically.
+.TP
+.B O_TRUNC
+If the shared memory object already exists, truncate it to zero bytes.
+.PP
+Definitions of these flag values can be obtained by including
+.IR <fcntl.h> .
+.PP
+On successful completion
+.BR shm_open ()
+returns a new file descriptor referring to the shared memory object.
+This file descriptor is guaranteed to be the lowest-numbered file descriptor
+not previously opened within the process.
+The
+.B FD_CLOEXEC
+flag (see
+.BR fcntl (2))
+is set for the file descriptor.
+.PP
+The file descriptor is normally used in subsequent calls
+to
+.BR ftruncate (2)
+(for a newly created object) and
+.BR mmap (2).
+After a call to
+.BR mmap (2)
+the file descriptor may be closed without affecting the memory mapping.
+.PP
+The operation
+of
+.BR shm_unlink ()
+is analogous to
+.BR unlink (2):
+it removes a shared memory object name, and, once all processes
+have unmapped the object, deallocates and
+destroys the contents of the associated memory region.
+After a successful
+.BR shm_unlink (),
+attempts to
+.BR shm_open ()
+an object with the same
+.I name
+fail (unless
+.B O_CREAT
+was specified, in which case a new, distinct object is created).
+.SH RETURN VALUE
+On success,
+.BR shm_open ()
+returns a file descriptor (a nonnegative integer).
+On success,
+.BR shm_unlink ()
+returns 0.
+On failure, both functions return \-1 and set
+.I errno
+to indicate the error.
+.SH ERRORS
+.TP
+.B EACCES
+Permission to
+.BR shm_unlink ()
+the shared memory object was denied.
+.TP
+.B EACCES
+Permission was denied to
+.BR shm_open ()
+.I name
+in the specified
+.IR mode ,
+or
+.B O_TRUNC
+was specified and the caller does not have write permission on the object.
+.TP
+.B EEXIST
+Both
+.B O_CREAT
+and
+.B O_EXCL
+were specified to
+.BR shm_open ()
+and the shared memory object specified by
+.I name
+already exists.
+.TP
+.B EINVAL
+The
+.I name
+argument to
+.BR shm_open ()
+was invalid.
+.TP
+.B EMFILE
+The per-process limit on the number of open file descriptors has been reached.
+.TP
+.B ENAMETOOLONG
+The length of
+.I name
+exceeds
+.BR PATH_MAX .
+.TP
+.B ENFILE
+The system-wide limit on the total number of open files has been reached.
+.TP
+.B ENOENT
+An attempt was made to
+.BR shm_open ()
+a
+.I name
+that did not exist, and
+.B O_CREAT
+was not specified.
+.TP
+.B ENOENT
+An attempt was to made to
+.BR shm_unlink ()
+a
+.I name
+that does not exist.
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR shm_open (),
+.BR shm_unlink ()
+T} Thread safety MT-Safe locale
+.TE
+.sp 1
+.SH VERSIONS
+POSIX leaves the behavior of the combination of
+.B O_RDONLY
+and
+.B O_TRUNC
+unspecified.
+On Linux, this will successfully truncate an existing
+shared memory object\[em]this may not be so on other UNIX systems.
+.PP
+The POSIX shared memory object implementation on Linux makes use
+of a dedicated
+.BR tmpfs (5)
+filesystem that is normally mounted under
+.IR /dev/shm .
+.SH STANDARDS
+POSIX.1-2008.
+.SH HISTORY
+glibc 2.2.
+POSIX.1-2001.
+.PP
+POSIX.1-2001 says that the group ownership of a newly created shared
+memory object is set to either the calling process's effective group ID
+or "a system default group ID".
+POSIX.1-2008 says that the group ownership
+may be set to either the calling process's effective group ID
+or, if the object is visible in the filesystem,
+the group ID of the parent directory.
+.SH EXAMPLES
+The programs below employ POSIX shared memory and POSIX unnamed semaphores
+to exchange a piece of data.
+The "bounce" program (which must be run first) raises the case
+of a string that is placed into the shared memory by the "send" program.
+Once the data has been modified, the "send" program then prints
+the contents of the modified shared memory.
+An example execution of the two programs is the following:
+.PP
+.in +4n
+.EX
+$ \fB./pshm_ucase_bounce /myshm &\fP
+[1] 270171
+$ \fB./pshm_ucase_send /myshm hello\fP
+HELLO
+.EE
+.in
+.PP
+Further detail about these programs is provided below.
+.\"
+.SS Program source: pshm_ucase.h
+The following header file is included by both programs below.
+Its primary purpose is to define a structure that will be imposed
+on the memory object that is shared between the two programs.
+.PP
+.in +4n
+.\" SRC BEGIN (pshm_ucase.h)
+.EX
+#include <fcntl.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+\&
+#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e
+ } while (0)
+\&
+#define BUF_SIZE 1024 /* Maximum size for exchanged string */
+\&
+/* Define a structure that will be imposed on the shared
+ memory object */
+\&
+struct shmbuf {
+ sem_t sem1; /* POSIX unnamed semaphore */
+ sem_t sem2; /* POSIX unnamed semaphore */
+ size_t cnt; /* Number of bytes used in \[aq]buf\[aq] */
+ char buf[BUF_SIZE]; /* Data being transferred */
+};
+.EE
+.\" SRC END
+.in
+.\"
+.SS Program source: pshm_ucase_bounce.c
+The "bounce" program creates a new shared memory object with the name
+given in its command-line argument and sizes the object to
+match the size of the
+.I shmbuf
+structure defined in the header file.
+It then maps the object into the process's address space,
+and initializes two POSIX semaphores inside the object to 0.
+.PP
+After the "send" program has posted the first of the semaphores,
+the "bounce" program upper cases the data that has been placed
+in the memory by the "send" program and then posts the second semaphore
+to tell the "send" program that it may now access the shared memory.
+.PP
+.in +4n
+.\" SRC BEGIN (pshm_ucase_bounce.c)
+.EX
+/* pshm_ucase_bounce.c
+\&
+ Licensed under GNU General Public License v2 or later.
+*/
+#include <ctype.h>
+\&
+#include "pshm_ucase.h"
+\&
+int
+main(int argc, char *argv[])
+{
+ int fd;
+ char *shmpath;
+ struct shmbuf *shmp;
+\&
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s /shm\-path\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ shmpath = argv[1];
+\&
+ /* Create shared memory object and set its size to the size
+ of our structure. */
+\&
+ fd = shm_open(shmpath, O_CREAT | O_EXCL | O_RDWR, 0600);
+ if (fd == \-1)
+ errExit("shm_open");
+\&
+ if (ftruncate(fd, sizeof(struct shmbuf)) == \-1)
+ errExit("ftruncate");
+\&
+ /* Map the object into the caller\[aq]s address space. */
+\&
+ shmp = mmap(NULL, sizeof(*shmp), PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (shmp == MAP_FAILED)
+ errExit("mmap");
+\&
+ /* Initialize semaphores as process\-shared, with value 0. */
+\&
+ if (sem_init(&shmp\->sem1, 1, 0) == \-1)
+ errExit("sem_init\-sem1");
+ if (sem_init(&shmp\->sem2, 1, 0) == \-1)
+ errExit("sem_init\-sem2");
+\&
+ /* Wait for \[aq]sem1\[aq] to be posted by peer before touching
+ shared memory. */
+\&
+ if (sem_wait(&shmp\->sem1) == \-1)
+ errExit("sem_wait");
+\&
+ /* Convert data in shared memory into upper case. */
+\&
+ for (size_t j = 0; j < shmp\->cnt; j++)
+ shmp\->buf[j] = toupper((unsigned char) shmp\->buf[j]);
+\&
+ /* Post \[aq]sem2\[aq] to tell the peer that it can now
+ access the modified data in shared memory. */
+\&
+ if (sem_post(&shmp\->sem2) == \-1)
+ errExit("sem_post");
+\&
+ /* Unlink the shared memory object. Even if the peer process
+ is still using the object, this is okay. The object will
+ be removed only after all open references are closed. */
+\&
+ shm_unlink(shmpath);
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.in
+.\"
+.SS Program source: pshm_ucase_send.c
+The "send" program takes two command-line arguments:
+the pathname of a shared memory object previously created by the "bounce"
+program and a string that is to be copied into that object.
+.PP
+The program opens the shared memory object
+and maps the object into its address space.
+It then copies the data specified in its second argument
+into the shared memory,
+and posts the first semaphore,
+which tells the "bounce" program that it can now access that data.
+After the "bounce" program posts the second semaphore,
+the "send" program prints the contents of the shared memory
+on standard output.
+.PP
+.in +4n
+.\" SRC BEGIN (pshm_ucase_send.c)
+.EX
+/* pshm_ucase_send.c
+\&
+ Licensed under GNU General Public License v2 or later.
+*/
+#include <string.h>
+\&
+#include "pshm_ucase.h"
+\&
+int
+main(int argc, char *argv[])
+{
+ int fd;
+ char *shmpath, *string;
+ size_t len;
+ struct shmbuf *shmp;
+\&
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s /shm\-path string\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ shmpath = argv[1];
+ string = argv[2];
+ len = strlen(string);
+\&
+ if (len > BUF_SIZE) {
+ fprintf(stderr, "String is too long\en");
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Open the existing shared memory object and map it
+ into the caller\[aq]s address space. */
+\&
+ fd = shm_open(shmpath, O_RDWR, 0);
+ if (fd == \-1)
+ errExit("shm_open");
+\&
+ shmp = mmap(NULL, sizeof(*shmp), PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (shmp == MAP_FAILED)
+ errExit("mmap");
+\&
+ /* Copy data into the shared memory object. */
+\&
+ shmp\->cnt = len;
+ memcpy(&shmp\->buf, string, len);
+\&
+ /* Tell peer that it can now access shared memory. */
+\&
+ if (sem_post(&shmp\->sem1) == \-1)
+ errExit("sem_post");
+\&
+ /* Wait until peer says that it has finished accessing
+ the shared memory. */
+\&
+ if (sem_wait(&shmp\->sem2) == \-1)
+ errExit("sem_wait");
+\&
+ /* Write modified data in shared memory to standard output. */
+\&
+ write(STDOUT_FILENO, &shmp\->buf, len);
+ write(STDOUT_FILENO, "\en", 1);
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.in
+.SH SEE ALSO
+.BR close (2),
+.BR fchmod (2),
+.BR fchown (2),
+.BR fcntl (2),
+.BR fstat (2),
+.BR ftruncate (2),
+.BR memfd_create (2),
+.BR mmap (2),
+.BR open (2),
+.BR umask (2),
+.BR shm_overview (7)