]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/shmop.2
dist.mk, All pages: .TH: Generate date at 'make dist'
[thirdparty/man-pages.git] / man2 / shmop.2
1 .\" Copyright 1993 Giorgio Ciucci (giorgio@crcc.it)
2 .\" and Copyright 2020 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .\" Modified Sun Nov 28 17:06:19 1993, Rik Faith (faith@cs.unc.edu)
7 .\" with material from Luigi P. Bai (lpb@softint.com)
8 .\" Portions Copyright 1993 Luigi P. Bai
9 .\" Modified Tue Oct 22 22:04:23 1996 by Eric S. Raymond <esr@thyrsus.com>
10 .\" Modified, 5 Jan 2002, Michael Kerrisk <mtk.manpages@gmail.com>
11 .\" Modified, 19 Sep 2002, Michael Kerrisk <mtk.manpages@gmail.com>
12 .\" Added SHM_REMAP flag description
13 .\" Modified, 27 May 2004, Michael Kerrisk <mtk.manpages@gmail.com>
14 .\" Added notes on capability requirements
15 .\" Modified, 11 Nov 2004, Michael Kerrisk <mtk.manpages@gmail.com>
16 .\" Language and formatting clean-ups
17 .\" Changed wording and placement of sentence regarding attachment
18 .\" of segments marked for destruction
19 .\"
20 .TH SHMOP 2 (date) "Linux man-pages (unreleased)"
21 .SH NAME
22 shmat, shmdt \- System V shared memory operations
23 .SH LIBRARY
24 Standard C library
25 .RI ( libc ", " \-lc )
26 .SH SYNOPSIS
27 .nf
28 .B #include <sys/shm.h>
29 .PP
30 .BI "void *shmat(int " shmid ", const void *" shmaddr ", int " shmflg );
31 .BI "int shmdt(const void *" shmaddr );
32 .fi
33 .SH DESCRIPTION
34 .SS shmat()
35 .BR shmat ()
36 attaches the System\ V shared memory segment identified by
37 .I shmid
38 to the address space of the calling process.
39 The attaching address is specified by
40 .I shmaddr
41 with one of the following criteria:
42 .IP \(bu 2
43 If
44 .I shmaddr
45 is NULL,
46 the system chooses a suitable (unused) page-aligned address to attach
47 the segment.
48 .IP \(bu
49 If
50 .I shmaddr
51 isn't NULL
52 and
53 .B SHM_RND
54 is specified in
55 .IR shmflg ,
56 the attach occurs at the address equal to
57 .I shmaddr
58 rounded down to the nearest multiple of
59 .BR SHMLBA .
60 .IP \(bu
61 Otherwise,
62 .I shmaddr
63 must be a page-aligned address at which the attach occurs.
64 .PP
65 In addition to
66 .BR SHM_RND ,
67 the following flags may be specified in the
68 .I shmflg
69 bit-mask argument:
70 .TP
71 .BR SHM_EXEC " (Linux-specific; since Linux 2.6.9)"
72 Allow the contents of the segment to be executed.
73 The caller must have execute permission on the segment.
74 .TP
75 .B SHM_RDONLY
76 Attach the segment for read-only access.
77 The process must have read permission for the segment.
78 If this flag is not specified,
79 the segment is attached for read and write access,
80 and the process must have read and write permission for the segment.
81 There is no notion of a write-only shared memory segment.
82 .TP
83 .BR SHM_REMAP " (Linux-specific)"
84 This flag specifies
85 that the mapping of the segment should replace
86 any existing mapping in the range starting at
87 .I shmaddr
88 and continuing for the size of the segment.
89 (Normally, an
90 .B EINVAL
91 error would result if a mapping already exists in this address range.)
92 In this case,
93 .I shmaddr
94 must not be NULL.
95 .PP
96 The
97 .BR brk (2)
98 value of the calling process is not altered by the attach.
99 The segment will automatically be detached at process exit.
100 The same segment may be attached as a read and as a read-write
101 one, and more than once, in the process's address space.
102 .PP
103 A successful
104 .BR shmat ()
105 call updates the members of the
106 .I shmid_ds
107 structure (see
108 .BR shmctl (2))
109 associated with the shared memory segment as follows:
110 .IP \(bu 2
111 .I shm_atime
112 is set to the current time.
113 .IP \(bu
114 .I shm_lpid
115 is set to the process-ID of the calling process.
116 .IP \(bu
117 .I shm_nattch
118 is incremented by one.
119 .\"
120 .SS shmdt()
121 .BR shmdt ()
122 detaches the shared memory segment located at the address specified by
123 .I shmaddr
124 from the address space of the calling process.
125 The to-be-detached segment must be currently
126 attached with
127 .I shmaddr
128 equal to the value returned by the attaching
129 .BR shmat ()
130 call.
131 .PP
132 On a successful
133 .BR shmdt ()
134 call, the system updates the members of the
135 .I shmid_ds
136 structure associated with the shared memory segment as follows:
137 .IP \(bu 2
138 .I shm_dtime
139 is set to the current time.
140 .IP \(bu
141 .I shm_lpid
142 is set to the process-ID of the calling process.
143 .IP \(bu
144 .I shm_nattch
145 is decremented by one.
146 If it becomes 0 and the segment is marked for deletion,
147 the segment is deleted.
148 .SH RETURN VALUE
149 On success,
150 .BR shmat ()
151 returns the address of the attached shared memory segment; on error,
152 .I (void\ *)\ \-1
153 is returned, and
154 .I errno
155 is set to indicate the error.
156 .PP
157 On success,
158 .BR shmdt ()
159 returns 0; on error \-1 is returned, and
160 .I errno
161 is set to indicate the error.
162 .SH ERRORS
163 .BR shmat ()
164 can fail with one of the following errors:
165 .TP
166 .B EACCES
167 The calling process does not have the required permissions for
168 the requested attach type, and does not have the
169 .B CAP_IPC_OWNER
170 capability in the user namespace that governs its IPC namespace.
171 .TP
172 .B EIDRM
173 \fIshmid\fP points to a removed identifier.
174 .TP
175 .B EINVAL
176 Invalid
177 .I shmid
178 value, unaligned (i.e., not page-aligned and \fBSHM_RND\fP was not
179 specified) or invalid
180 .I shmaddr
181 value, or can't attach segment at
182 .IR shmaddr ,
183 or
184 .B SHM_REMAP
185 was specified and
186 .I shmaddr
187 was NULL.
188 .TP
189 .B ENOMEM
190 Could not allocate memory for the descriptor or for the page tables.
191 .PP
192 .BR shmdt ()
193 can fail with one of the following errors:
194 .TP
195 .B EINVAL
196 There is no shared memory segment attached at
197 .IR shmaddr ;
198 or,
199 .\" The following since 2.6.17-rc1:
200 .I shmaddr
201 is not aligned on a page boundary.
202 .SH STANDARDS
203 POSIX.1-2001, POSIX.1-2008, SVr4.
204 .\" SVr4 documents an additional error condition EMFILE.
205 .PP
206 In SVID 3 (or perhaps earlier),
207 the type of the \fIshmaddr\fP argument was changed from
208 .I "char\ *"
209 into
210 .IR "const void\ *" ,
211 and the returned type of
212 .BR shmat ()
213 from
214 .I "char\ *"
215 into
216 .IR "void\ *" .
217 .SH NOTES
218 After a
219 .BR fork (2),
220 the child inherits the attached shared memory segments.
221 .PP
222 After an
223 .BR execve (2),
224 all attached shared memory segments are detached from the process.
225 .PP
226 Upon
227 .BR _exit (2),
228 all attached shared memory segments are detached from the process.
229 .PP
230 Using
231 .BR shmat ()
232 with
233 .I shmaddr
234 equal to NULL
235 is the preferred, portable way of attaching a shared memory segment.
236 Be aware that the shared memory segment attached in this way
237 may be attached at different addresses in different processes.
238 Therefore, any pointers maintained within the shared memory must be
239 made relative (typically to the starting address of the segment),
240 rather than absolute.
241 .PP
242 On Linux, it is possible to attach a shared memory segment even if it
243 is already marked to be deleted.
244 However, POSIX.1 does not specify this behavior and
245 many other implementations do not support it.
246 .PP
247 The following system parameter affects
248 .BR shmat ():
249 .TP
250 .B SHMLBA
251 Segment low boundary address multiple.
252 When explicitly specifying an attach address in a call to
253 .BR shmat (),
254 the caller should ensure that the address is a multiple of this value.
255 This is necessary on some architectures,
256 in order either to ensure good CPU cache performance or to ensure that
257 different attaches of the same segment have consistent views
258 within the CPU cache.
259 .B SHMLBA
260 is normally some multiple of the system page size.
261 (On many Linux architectures,
262 .B SHMLBA
263 is the same as the system page size.)
264 .PP
265 The implementation places no intrinsic per-process limit on the
266 number of shared memory segments
267 .RB ( SHMSEG ).
268 .SH EXAMPLES
269 The two programs shown below exchange a string using a shared memory segment.
270 Further details about the programs are given below.
271 First, we show a shell session demonstrating their use.
272 .PP
273 In one terminal window, we run the "reader" program,
274 which creates a System V shared memory segment and a System V semaphore set.
275 The program prints out the IDs of the created objects,
276 and then waits for the semaphore to change value.
277 .PP
278 .in +4n
279 .EX
280 $ \fB./svshm_string_read\fP
281 shmid = 1114194; semid = 15
282 .EE
283 .in
284 .PP
285 In another terminal window, we run the "writer" program.
286 The "writer" program takes three command-line arguments:
287 the IDs of the shared memory segment and semaphore set created
288 by the "reader", and a string.
289 It attaches the existing shared memory segment,
290 copies the string to the shared memory, and modifies the semaphore value.
291 .PP
292 .in +4n
293 .EX
294 $ \fB./svshm_string_write 1114194 15 \(aqHello, world\(aq\fP
295 .EE
296 .in
297 .PP
298 Returning to the terminal where the "reader" is running,
299 we see that the program has ceased waiting on the semaphore
300 and has printed the string that was copied into the
301 shared memory segment by the writer:
302 .PP
303 .in +4n
304 .EX
305 Hello, world
306 .EE
307 .in
308 .\"
309 .SS Program source: svshm_string.h
310 The following header file is included by the "reader" and "writer" programs:
311 .PP
312 .in +4n
313 .\" SRC BEGIN (svshm_string.h)
314 .EX
315 /* svshm_string.h
316
317 Licensed under GNU General Public License v2 or later.
318 */
319 #include <sys/types.h>
320 #include <sys/ipc.h>
321 #include <sys/shm.h>
322 #include <sys/sem.h>
323 #include <stdio.h>
324 #include <stdlib.h>
325 #include <string.h>
326
327 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e
328 } while (0)
329
330 union semun { /* Used in calls to semctl() */
331 int val;
332 struct semid_ds * buf;
333 unsigned short * array;
334 #if defined(__linux__)
335 struct seminfo * __buf;
336 #endif
337 };
338
339 #define MEM_SIZE 4096
340 .EE
341 .\" SRC END
342 .in
343 .\"
344 .SS Program source: svshm_string_read.c
345 The "reader" program creates a shared memory segment and a semaphore set
346 containing one semaphore.
347 It then attaches the shared memory object into its address space
348 and initializes the semaphore value to 1.
349 Finally, the program waits for the semaphore value to become 0,
350 and afterwards prints the string that has been copied into the
351 shared memory segment by the "writer".
352 .PP
353 .in +4n
354 .\" SRC BEGIN (svshm_string_read.c)
355 .EX
356 /* svshm_string_read.c
357
358 Licensed under GNU General Public License v2 or later.
359 */
360 #include <stdio.h>
361 #include <stdlib.h>
362 #include <sys/ipc.h>
363 #include <sys/sem.h>
364 #include <sys/shm.h>
365
366 #include "svshm_string.h"
367
368 int
369 main(void)
370 {
371 int semid, shmid;
372 char *addr;
373 union semun arg, dummy;
374 struct sembuf sop;
375
376 /* Create shared memory and semaphore set containing one
377 semaphore. */
378
379 shmid = shmget(IPC_PRIVATE, MEM_SIZE, IPC_CREAT | 0600);
380 if (shmid == \-1)
381 errExit("shmget");
382
383 semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
384 if (semid == \-1)
385 errExit("semget");
386
387 /* Attach shared memory into our address space. */
388
389 addr = shmat(shmid, NULL, SHM_RDONLY);
390 if (addr == (void *) \-1)
391 errExit("shmat");
392
393 /* Initialize semaphore 0 in set with value 1. */
394
395 arg.val = 1;
396 if (semctl(semid, 0, SETVAL, arg) == \-1)
397 errExit("semctl");
398
399 printf("shmid = %d; semid = %d\en", shmid, semid);
400
401 /* Wait for semaphore value to become 0. */
402
403 sop.sem_num = 0;
404 sop.sem_op = 0;
405 sop.sem_flg = 0;
406
407 if (semop(semid, &sop, 1) == \-1)
408 errExit("semop");
409
410 /* Print the string from shared memory. */
411
412 printf("%s\en", addr);
413
414 /* Remove shared memory and semaphore set. */
415
416 if (shmctl(shmid, IPC_RMID, NULL) == \-1)
417 errExit("shmctl");
418 if (semctl(semid, 0, IPC_RMID, dummy) == \-1)
419 errExit("semctl");
420
421 exit(EXIT_SUCCESS);
422 }
423 .EE
424 .\" SRC END
425 .in
426 .\"
427 .SS Program source: svshm_string_write.c
428 The writer program takes three command-line arguments:
429 the IDs of the shared memory segment and semaphore set
430 that have already been created by the "reader", and a string.
431 It attaches the shared memory segment into its address space,
432 and then decrements the semaphore value to 0 in order to inform the
433 "reader" that it can now examine the contents of the shared memory.
434 .PP
435 .in +4n
436 .\" SRC BEGIN (svshm_string_write.c)
437 .EX
438 /* svshm_string_write.c
439
440 Licensed under GNU General Public License v2 or later.
441 */
442 #include <stdio.h>
443 #include <stdlib.h>
444 #include <string.h>
445 #include <sys/sem.h>
446 #include <sys/shm.h>
447
448 #include "svshm_string.h"
449
450 int
451 main(int argc, char *argv[])
452 {
453 int semid, shmid;
454 char *addr;
455 size_t len;
456 struct sembuf sop;
457
458 if (argc != 4) {
459 fprintf(stderr, "Usage: %s shmid semid string\en", argv[0]);
460 exit(EXIT_FAILURE);
461 }
462
463 len = strlen(argv[3]) + 1; /* +1 to include trailing \(aq\e0\(aq */
464 if (len > MEM_SIZE) {
465 fprintf(stderr, "String is too big!\en");
466 exit(EXIT_FAILURE);
467 }
468
469 /* Get object IDs from command\-line. */
470
471 shmid = atoi(argv[1]);
472 semid = atoi(argv[2]);
473
474 /* Attach shared memory into our address space and copy string
475 (including trailing null byte) into memory. */
476
477 addr = shmat(shmid, NULL, 0);
478 if (addr == (void *) \-1)
479 errExit("shmat");
480
481 memcpy(addr, argv[3], len);
482
483 /* Decrement semaphore to 0. */
484
485 sop.sem_num = 0;
486 sop.sem_op = \-1;
487 sop.sem_flg = 0;
488
489 if (semop(semid, &sop, 1) == \-1)
490 errExit("semop");
491
492 exit(EXIT_SUCCESS);
493 }
494 .EE
495 .\" SRC END
496 .in
497 .SH SEE ALSO
498 .BR brk (2),
499 .BR mmap (2),
500 .BR shmctl (2),
501 .BR shmget (2),
502 .BR capabilities (7),
503 .BR shm_overview (7),
504 .BR sysvipc (7)