summaryrefslogtreecommitdiffstats
path: root/man2/shmop.2
diff options
context:
space:
mode:
Diffstat (limited to 'man2/shmop.2')
-rw-r--r--man2/shmop.2507
1 files changed, 507 insertions, 0 deletions
diff --git a/man2/shmop.2 b/man2/shmop.2
new file mode 100644
index 0000000..09168ec
--- /dev/null
+++ b/man2/shmop.2
@@ -0,0 +1,507 @@
+.\" Copyright 1993 Giorgio Ciucci (giorgio@crcc.it)
+.\" and Copyright 2020 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.\" Modified Sun Nov 28 17:06:19 1993, Rik Faith (faith@cs.unc.edu)
+.\" with material from Luigi P. Bai (lpb@softint.com)
+.\" Portions Copyright 1993 Luigi P. Bai
+.\" Modified Tue Oct 22 22:04:23 1996 by Eric S. Raymond <esr@thyrsus.com>
+.\" Modified, 5 Jan 2002, Michael Kerrisk <mtk.manpages@gmail.com>
+.\" Modified, 19 Sep 2002, Michael Kerrisk <mtk.manpages@gmail.com>
+.\" Added SHM_REMAP flag description
+.\" Modified, 27 May 2004, Michael Kerrisk <mtk.manpages@gmail.com>
+.\" Added notes on capability requirements
+.\" Modified, 11 Nov 2004, Michael Kerrisk <mtk.manpages@gmail.com>
+.\" Language and formatting clean-ups
+.\" Changed wording and placement of sentence regarding attachment
+.\" of segments marked for destruction
+.\"
+.TH SHMOP 2 2023-05-03 "Linux man-pages 6.05.01"
+.SH NAME
+shmat, shmdt \- System V shared memory operations
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.B #include <sys/shm.h>
+.PP
+.BI "void *shmat(int " shmid ", const void *_Nullable " shmaddr ", \
+int " shmflg );
+.BI "int shmdt(const void *" shmaddr );
+.fi
+.SH DESCRIPTION
+.SS shmat()
+.BR shmat ()
+attaches the System\ V shared memory segment identified by
+.I shmid
+to the address space of the calling process.
+The attaching address is specified by
+.I shmaddr
+with one of the following criteria:
+.IP \[bu] 3
+If
+.I shmaddr
+is NULL,
+the system chooses a suitable (unused) page-aligned address to attach
+the segment.
+.IP \[bu]
+If
+.I shmaddr
+isn't NULL
+and
+.B SHM_RND
+is specified in
+.IR shmflg ,
+the attach occurs at the address equal to
+.I shmaddr
+rounded down to the nearest multiple of
+.BR SHMLBA .
+.IP \[bu]
+Otherwise,
+.I shmaddr
+must be a page-aligned address at which the attach occurs.
+.PP
+In addition to
+.BR SHM_RND ,
+the following flags may be specified in the
+.I shmflg
+bit-mask argument:
+.TP
+.BR SHM_EXEC " (Linux-specific; since Linux 2.6.9)"
+Allow the contents of the segment to be executed.
+The caller must have execute permission on the segment.
+.TP
+.B SHM_RDONLY
+Attach the segment for read-only access.
+The process must have read permission for the segment.
+If this flag is not specified,
+the segment is attached for read and write access,
+and the process must have read and write permission for the segment.
+There is no notion of a write-only shared memory segment.
+.TP
+.BR SHM_REMAP " (Linux-specific)"
+This flag specifies
+that the mapping of the segment should replace
+any existing mapping in the range starting at
+.I shmaddr
+and continuing for the size of the segment.
+(Normally, an
+.B EINVAL
+error would result if a mapping already exists in this address range.)
+In this case,
+.I shmaddr
+must not be NULL.
+.PP
+The
+.BR brk (2)
+value of the calling process is not altered by the attach.
+The segment will automatically be detached at process exit.
+The same segment may be attached as a read and as a read-write
+one, and more than once, in the process's address space.
+.PP
+A successful
+.BR shmat ()
+call updates the members of the
+.I shmid_ds
+structure (see
+.BR shmctl (2))
+associated with the shared memory segment as follows:
+.IP \[bu] 3
+.I shm_atime
+is set to the current time.
+.IP \[bu]
+.I shm_lpid
+is set to the process-ID of the calling process.
+.IP \[bu]
+.I shm_nattch
+is incremented by one.
+.\"
+.SS shmdt()
+.BR shmdt ()
+detaches the shared memory segment located at the address specified by
+.I shmaddr
+from the address space of the calling process.
+The to-be-detached segment must be currently
+attached with
+.I shmaddr
+equal to the value returned by the attaching
+.BR shmat ()
+call.
+.PP
+On a successful
+.BR shmdt ()
+call, the system updates the members of the
+.I shmid_ds
+structure associated with the shared memory segment as follows:
+.IP \[bu] 3
+.I shm_dtime
+is set to the current time.
+.IP \[bu]
+.I shm_lpid
+is set to the process-ID of the calling process.
+.IP \[bu]
+.I shm_nattch
+is decremented by one.
+If it becomes 0 and the segment is marked for deletion,
+the segment is deleted.
+.SH RETURN VALUE
+On success,
+.BR shmat ()
+returns the address of the attached shared memory segment; on error,
+.I (void\ *)\ \-1
+is returned, and
+.I errno
+is set to indicate the error.
+.PP
+On success,
+.BR shmdt ()
+returns 0; on error \-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.BR shmat ()
+can fail with one of the following errors:
+.TP
+.B EACCES
+The calling process does not have the required permissions for
+the requested attach type, and does not have the
+.B CAP_IPC_OWNER
+capability in the user namespace that governs its IPC namespace.
+.TP
+.B EIDRM
+\fIshmid\fP points to a removed identifier.
+.TP
+.B EINVAL
+Invalid
+.I shmid
+value, unaligned (i.e., not page-aligned and \fBSHM_RND\fP was not
+specified) or invalid
+.I shmaddr
+value, or can't attach segment at
+.IR shmaddr ,
+or
+.B SHM_REMAP
+was specified and
+.I shmaddr
+was NULL.
+.TP
+.B ENOMEM
+Could not allocate memory for the descriptor or for the page tables.
+.PP
+.BR shmdt ()
+can fail with one of the following errors:
+.TP
+.B EINVAL
+There is no shared memory segment attached at
+.IR shmaddr ;
+or,
+.\" The following since Linux 2.6.17-rc1:
+.I shmaddr
+is not aligned on a page boundary.
+.SH STANDARDS
+POSIX.1-2008.
+.SH HISTORY
+POSIX.1-2001, SVr4.
+.\" SVr4 documents an additional error condition EMFILE.
+.PP
+In SVID 3 (or perhaps earlier),
+the type of the \fIshmaddr\fP argument was changed from
+.I "char\ *"
+into
+.IR "const void\ *" ,
+and the returned type of
+.BR shmat ()
+from
+.I "char\ *"
+into
+.IR "void\ *" .
+.SH NOTES
+After a
+.BR fork (2),
+the child inherits the attached shared memory segments.
+.PP
+After an
+.BR execve (2),
+all attached shared memory segments are detached from the process.
+.PP
+Upon
+.BR _exit (2),
+all attached shared memory segments are detached from the process.
+.PP
+Using
+.BR shmat ()
+with
+.I shmaddr
+equal to NULL
+is the preferred, portable way of attaching a shared memory segment.
+Be aware that the shared memory segment attached in this way
+may be attached at different addresses in different processes.
+Therefore, any pointers maintained within the shared memory must be
+made relative (typically to the starting address of the segment),
+rather than absolute.
+.PP
+On Linux, it is possible to attach a shared memory segment even if it
+is already marked to be deleted.
+However, POSIX.1 does not specify this behavior and
+many other implementations do not support it.
+.PP
+The following system parameter affects
+.BR shmat ():
+.TP
+.B SHMLBA
+Segment low boundary address multiple.
+When explicitly specifying an attach address in a call to
+.BR shmat (),
+the caller should ensure that the address is a multiple of this value.
+This is necessary on some architectures,
+in order either to ensure good CPU cache performance or to ensure that
+different attaches of the same segment have consistent views
+within the CPU cache.
+.B SHMLBA
+is normally some multiple of the system page size.
+(On many Linux architectures,
+.B SHMLBA
+is the same as the system page size.)
+.PP
+The implementation places no intrinsic per-process limit on the
+number of shared memory segments
+.RB ( SHMSEG ).
+.SH EXAMPLES
+The two programs shown below exchange a string using a shared memory segment.
+Further details about the programs are given below.
+First, we show a shell session demonstrating their use.
+.PP
+In one terminal window, we run the "reader" program,
+which creates a System V shared memory segment and a System V semaphore set.
+The program prints out the IDs of the created objects,
+and then waits for the semaphore to change value.
+.PP
+.in +4n
+.EX
+$ \fB./svshm_string_read\fP
+shmid = 1114194; semid = 15
+.EE
+.in
+.PP
+In another terminal window, we run the "writer" program.
+The "writer" program takes three command-line arguments:
+the IDs of the shared memory segment and semaphore set created
+by the "reader", and a string.
+It attaches the existing shared memory segment,
+copies the string to the shared memory, and modifies the semaphore value.
+.PP
+.in +4n
+.EX
+$ \fB./svshm_string_write 1114194 15 \[aq]Hello, world\[aq]\fP
+.EE
+.in
+.PP
+Returning to the terminal where the "reader" is running,
+we see that the program has ceased waiting on the semaphore
+and has printed the string that was copied into the
+shared memory segment by the writer:
+.PP
+.in +4n
+.EX
+Hello, world
+.EE
+.in
+.\"
+.SS Program source: svshm_string.h
+The following header file is included by the "reader" and "writer" programs:
+.PP
+.in +4n
+.\" SRC BEGIN (svshm_string.h)
+.EX
+/* svshm_string.h
+\&
+ Licensed under GNU General Public License v2 or later.
+*/
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+\&
+#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e
+ } while (0)
+\&
+union semun { /* Used in calls to semctl() */
+ int val;
+ struct semid_ds * buf;
+ unsigned short * array;
+#if defined(__linux__)
+ struct seminfo * __buf;
+#endif
+};
+\&
+#define MEM_SIZE 4096
+.EE
+.\" SRC END
+.in
+.\"
+.SS Program source: svshm_string_read.c
+The "reader" program creates a shared memory segment and a semaphore set
+containing one semaphore.
+It then attaches the shared memory object into its address space
+and initializes the semaphore value to 1.
+Finally, the program waits for the semaphore value to become 0,
+and afterwards prints the string that has been copied into the
+shared memory segment by the "writer".
+.PP
+.in +4n
+.\" SRC BEGIN (svshm_string_read.c)
+.EX
+/* svshm_string_read.c
+\&
+ Licensed under GNU General Public License v2 or later.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+\&
+#include "svshm_string.h"
+\&
+int
+main(void)
+{
+ int semid, shmid;
+ char *addr;
+ union semun arg, dummy;
+ struct sembuf sop;
+\&
+ /* Create shared memory and semaphore set containing one
+ semaphore. */
+\&
+ shmid = shmget(IPC_PRIVATE, MEM_SIZE, IPC_CREAT | 0600);
+ if (shmid == \-1)
+ errExit("shmget");
+\&
+ semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
+ if (semid == \-1)
+ errExit("semget");
+\&
+ /* Attach shared memory into our address space. */
+\&
+ addr = shmat(shmid, NULL, SHM_RDONLY);
+ if (addr == (void *) \-1)
+ errExit("shmat");
+\&
+ /* Initialize semaphore 0 in set with value 1. */
+\&
+ arg.val = 1;
+ if (semctl(semid, 0, SETVAL, arg) == \-1)
+ errExit("semctl");
+\&
+ printf("shmid = %d; semid = %d\en", shmid, semid);
+\&
+ /* Wait for semaphore value to become 0. */
+\&
+ sop.sem_num = 0;
+ sop.sem_op = 0;
+ sop.sem_flg = 0;
+\&
+ if (semop(semid, &sop, 1) == \-1)
+ errExit("semop");
+\&
+ /* Print the string from shared memory. */
+\&
+ printf("%s\en", addr);
+\&
+ /* Remove shared memory and semaphore set. */
+\&
+ if (shmctl(shmid, IPC_RMID, NULL) == \-1)
+ errExit("shmctl");
+ if (semctl(semid, 0, IPC_RMID, dummy) == \-1)
+ errExit("semctl");
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.in
+.\"
+.SS Program source: svshm_string_write.c
+The writer program takes three command-line arguments:
+the IDs of the shared memory segment and semaphore set
+that have already been created by the "reader", and a string.
+It attaches the shared memory segment into its address space,
+and then decrements the semaphore value to 0 in order to inform the
+"reader" that it can now examine the contents of the shared memory.
+.PP
+.in +4n
+.\" SRC BEGIN (svshm_string_write.c)
+.EX
+/* svshm_string_write.c
+\&
+ Licensed under GNU General Public License v2 or later.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+\&
+#include "svshm_string.h"
+\&
+int
+main(int argc, char *argv[])
+{
+ int semid, shmid;
+ char *addr;
+ size_t len;
+ struct sembuf sop;
+\&
+ if (argc != 4) {
+ fprintf(stderr, "Usage: %s shmid semid string\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ len = strlen(argv[3]) + 1; /* +1 to include trailing \[aq]\e0\[aq] */
+ if (len > MEM_SIZE) {
+ fprintf(stderr, "String is too big!\en");
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Get object IDs from command\-line. */
+\&
+ shmid = atoi(argv[1]);
+ semid = atoi(argv[2]);
+\&
+ /* Attach shared memory into our address space and copy string
+ (including trailing null byte) into memory. */
+\&
+ addr = shmat(shmid, NULL, 0);
+ if (addr == (void *) \-1)
+ errExit("shmat");
+\&
+ memcpy(addr, argv[3], len);
+\&
+ /* Decrement semaphore to 0. */
+\&
+ sop.sem_num = 0;
+ sop.sem_op = \-1;
+ sop.sem_flg = 0;
+\&
+ if (semop(semid, &sop, 1) == \-1)
+ errExit("semop");
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.in
+.SH SEE ALSO
+.BR brk (2),
+.BR mmap (2),
+.BR shmctl (2),
+.BR shmget (2),
+.BR capabilities (7),
+.BR shm_overview (7),
+.BR sysvipc (7)