1SHMOP(2)                   Linux Programmer's Manual                  SHMOP(2)
2
3
4

NAME

6       shmat, shmdt - System V shared memory operations
7

SYNOPSIS

9       #include <sys/shm.h>
10
11       void *shmat(int shmid, const void *shmaddr, int shmflg);
12       int shmdt(const void *shmaddr);
13

DESCRIPTION

15   shmat()
16       shmat() attaches the System V shared memory segment identified by shmid
17       to the address space of the calling process.  The attaching address  is
18       specified by shmaddr with one of the following criteria:
19
20       • If  shmaddr  is  NULL,  the  system chooses a suitable (unused) page-
21         aligned address to attach the segment.
22
23       • If shmaddr isn't NULL and SHM_RND is specified in shmflg, the  attach
24         occurs  at  the  address equal to shmaddr rounded down to the nearest
25         multiple of SHMLBA.
26
27       • Otherwise, shmaddr must be a page-aligned address at which the attach
28         occurs.
29
30       In  addition  to  SHM_RND,  the following flags may be specified in the
31       shmflg bit-mask argument:
32
33       SHM_EXEC (Linux-specific; since Linux 2.6.9)
34              Allow the contents of the segment to be  executed.   The  caller
35              must have execute permission on the segment.
36
37       SHM_RDONLY
38              Attach  the segment for read-only access.  The process must have
39              read permission for the segment.  If this flag is not specified,
40              the  segment  is  attached  for  read  and write access, and the
41              process must have read and write  permission  for  the  segment.
42              There is no notion of a write-only shared memory segment.
43
44       SHM_REMAP (Linux-specific)
45              This  flag  specifies that the mapping of the segment should re‐
46              place any existing mapping in the range starting at shmaddr  and
47              continuing  for  the  size of the segment.  (Normally, an EINVAL
48              error would result if a mapping already exists in  this  address
49              range.)  In this case, shmaddr must not be NULL.
50
51       The  brk(2)  value of the calling process is not altered by the attach.
52       The segment will automatically be detached at process exit.   The  same
53       segment  may  be  attached  as a read and as a read-write one, and more
54       than once, in the process's address space.
55
56       A successful shmat() call updates the members of the shmid_ds structure
57       (see shmctl(2)) associated with the shared memory segment as follows:
58
59shm_atime is set to the current time.
60
61shm_lpid is set to the process-ID of the calling process.
62
63shm_nattch is incremented by one.
64
65   shmdt()
66       shmdt() detaches the shared memory segment located at the address spec‐
67       ified by shmaddr from the address space of the  calling  process.   The
68       to-be-detached segment must be currently attached with shmaddr equal to
69       the value returned by the attaching shmat() call.
70
71       On a successful shmdt() call, the system updates  the  members  of  the
72       shmid_ds  structure  associated  with the shared memory segment as fol‐
73       lows:
74
75shm_dtime is set to the current time.
76
77shm_lpid is set to the process-ID of the calling process.
78
79shm_nattch is decremented by one.  If it becomes 0 and the segment is
80         marked for deletion, the segment is deleted.
81

RETURN VALUE

83       On  success,  shmat() returns the address of the attached shared memory
84       segment; on error, (void *) -1 is returned, and errno is set  to  indi‐
85       cate the error.
86
87       On  success,  shmdt()  returns 0; on error -1 is returned, and errno is
88       set to indicate the error.
89

ERRORS

91       shmat() can fail with one of the following errors:
92
93       EACCES The calling process does not have the required  permissions  for
94              the  requested  attach type, and does not have the CAP_IPC_OWNER
95              capability in the user namespace that governs its IPC namespace.
96
97       EIDRM  shmid points to a removed identifier.
98
99       EINVAL Invalid shmid  value,  unaligned  (i.e.,  not  page-aligned  and
100              SHM_RND  was  not  specified) or invalid shmaddr value, or can't
101              attach segment  at  shmaddr,  or  SHM_REMAP  was  specified  and
102              shmaddr was NULL.
103
104       ENOMEM Could not allocate memory for the descriptor or for the page ta‐
105              bles.
106
107       shmdt() can fail with one of the following errors:
108
109       EINVAL There is no shared  memory  segment  attached  at  shmaddr;  or,
110              shmaddr is not aligned on a page boundary.
111

CONFORMING TO

113       POSIX.1-2001, POSIX.1-2008, SVr4.
114
115       In  SVID  3  (or perhaps earlier), the type of the shmaddr argument was
116       changed from char * into const void *, and the returned type of shmat()
117       from char * into void *.
118

NOTES

120       After  a  fork(2),  the  child inherits the attached shared memory seg‐
121       ments.
122
123       After an execve(2), all attached shared memory  segments  are  detached
124       from the process.
125
126       Upon  _exit(2),  all  attached shared memory segments are detached from
127       the process.
128
129       Using shmat() with shmaddr equal to NULL is the preferred, portable way
130       of  attaching a shared memory segment.  Be aware that the shared memory
131       segment attached in this way may be attached at different addresses  in
132       different  processes.   Therefore,  any  pointers maintained within the
133       shared memory must be made relative (typically to the starting  address
134       of the segment), rather than absolute.
135
136       On  Linux,  it is possible to attach a shared memory segment even if it
137       is already marked to be deleted.  However,  POSIX.1  does  not  specify
138       this behavior and many other implementations do not support it.
139
140       The following system parameter affects shmat():
141
142       SHMLBA Segment low boundary address multiple.  When explicitly specify‐
143              ing an attach address in a call to shmat(),  the  caller  should
144              ensure  that  the  address is a multiple of this value.  This is
145              necessary on some architectures, in order either to ensure  good
146              CPU  cache  performance  or to ensure that different attaches of
147              the same segment have consistent views  within  the  CPU  cache.
148              SHMLBA  is  normally some multiple of the system page size.  (On
149              many Linux architectures, SHMLBA is the same as the system  page
150              size.)
151
152       The  implementation places no intrinsic per-process limit on the number
153       of shared memory segments (SHMSEG).
154

EXAMPLES

156       The two programs shown below exchange a string using  a  shared  memory
157       segment.   Further  details about the programs are given below.  First,
158       we show a shell session demonstrating their use.
159
160       In one terminal window, we run the "reader" program,  which  creates  a
161       System  V shared memory segment and a System V semaphore set.  The pro‐
162       gram prints out the IDs of the created objects, and then waits for  the
163       semaphore to change value.
164
165           $ ./svshm_string_read
166           shmid = 1114194; semid = 15
167
168       In  another terminal window, we run the "writer" program.  The "writer"
169       program takes three command-line arguments: the IDs of the shared  mem‐
170       ory  segment  and  semaphore set created by the "reader", and a string.
171       It attaches the existing shared memory segment, copies  the  string  to
172       the shared memory, and modifies the semaphore value.
173
174           $ ./svshm_string_write 1114194 15 'Hello, world'
175
176       Returning  to  the  terminal where the "reader" is running, we see that
177       the program has ceased waiting on the semaphore  and  has  printed  the
178       string that was copied into the shared memory segment by the writer:
179
180           Hello, world
181
182   Program source: svshm_string.h
183       The following header file is included by the "reader" and "writer" pro‐
184       grams:
185
186           /* svshm_string.h
187
188              Licensed under GNU General Public License v2 or later.
189           */
190           #include <sys/types.h>
191           #include <sys/ipc.h>
192           #include <sys/shm.h>
193           #include <sys/sem.h>
194           #include <stdio.h>
195           #include <stdlib.h>
196           #include <string.h>
197
198           #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
199                                   } while (0)
200
201           union semun {                   /* Used in calls to semctl() */
202               int                 val;
203               struct semid_ds *   buf;
204               unsigned short *    array;
205           #if defined(__linux__)
206               struct seminfo *    __buf;
207           #endif
208           };
209
210           #define MEM_SIZE 4096
211
212   Program source: svshm_string_read.c
213       The "reader" program creates a shared memory segment  and  a  semaphore
214       set  containing  one semaphore.  It then attaches the shared memory ob‐
215       ject into its address space and initializes the semaphore value  to  1.
216       Finally, the program waits for the semaphore value to become 0, and af‐
217       terwards prints the string that has been copied into the shared  memory
218       segment by the "writer".
219
220           /* svshm_string_read.c
221
222              Licensed under GNU General Public License v2 or later.
223           */
224           #include "svshm_string.h"
225
226           int
227           main(int argc, char *argv[])
228           {
229               int semid, shmid;
230               union semun arg, dummy;
231               struct sembuf sop;
232               char *addr;
233
234               /* Create shared memory and semaphore set containing one
235                  semaphore. */
236
237               shmid = shmget(IPC_PRIVATE, MEM_SIZE, IPC_CREAT | 0600);
238               if (shmid == -1)
239                   errExit("shmget");
240
241               semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
242               if (semid == -1)
243                   errExit("semget");
244
245               /* Attach shared memory into our address space. */
246
247               addr = shmat(shmid, NULL, SHM_RDONLY);
248               if (addr == (void *) -1)
249                   errExit("shmat");
250
251               /* Initialize semaphore 0 in set with value 1. */
252
253               arg.val = 1;
254               if (semctl(semid, 0, SETVAL, arg) == -1)
255                   errExit("semctl");
256
257               printf("shmid = %d; semid = %d\n", shmid, semid);
258
259               /* Wait for semaphore value to become 0. */
260
261               sop.sem_num = 0;
262               sop.sem_op = 0;
263               sop.sem_flg = 0;
264
265               if (semop(semid, &sop, 1) == -1)
266                   errExit("semop");
267
268               /* Print the string from shared memory. */
269
270               printf("%s\n", addr);
271
272               /* Remove shared memory and semaphore set. */
273
274               if (shmctl(shmid, IPC_RMID, NULL) == -1)
275                   errExit("shmctl");
276               if (semctl(semid, 0, IPC_RMID, dummy) == -1)
277                   errExit("semctl");
278
279               exit(EXIT_SUCCESS);
280           }
281
282   Program source: svshm_string_write.c
283       The  writer  program takes three command-line arguments: the IDs of the
284       shared memory segment and semaphore set that have already been  created
285       by  the  "reader", and a string.  It attaches the shared memory segment
286       into its address space, and then decrements the semaphore value to 0 in
287       order  to  inform  the "reader" that it can now examine the contents of
288       the shared memory.
289
290           /* svshm_string_write.c
291
292              Licensed under GNU General Public License v2 or later.
293           */
294           #include "svshm_string.h"
295
296           int
297           main(int argc, char *argv[])
298           {
299               int semid, shmid;
300               struct sembuf sop;
301               char *addr;
302               size_t len;
303
304               if (argc != 4) {
305                   fprintf(stderr, "Usage: %s shmid semid string\n", argv[0]);
306                   exit(EXIT_FAILURE);
307               }
308
309               len = strlen(argv[3]) + 1;  /* +1 to include trailing '\0' */
310               if (len > MEM_SIZE) {
311                   fprintf(stderr, "String is too big!\n");
312                   exit(EXIT_FAILURE);
313               }
314
315               /* Get object IDs from command-line. */
316
317               shmid = atoi(argv[1]);
318               semid = atoi(argv[2]);
319
320               /* Attach shared memory into our address space and copy string
321                  (including trailing null byte) into memory. */
322
323               addr = shmat(shmid, NULL, 0);
324               if (addr == (void *) -1)
325                   errExit("shmat");
326
327               memcpy(addr, argv[3], len);
328
329               /* Decrement semaphore to 0. */
330
331               sop.sem_num = 0;
332               sop.sem_op = -1;
333               sop.sem_flg = 0;
334
335               if (semop(semid, &sop, 1) == -1)
336                   errExit("semop");
337
338               exit(EXIT_SUCCESS);
339           }
340

SEE ALSO

342       brk(2),  mmap(2),  shmctl(2),  shmget(2),  capabilities(7),   shm_over‐
343       view(7), sysvipc(7)
344

COLOPHON

346       This  page  is  part of release 5.13 of the Linux man-pages project.  A
347       description of the project, information about reporting bugs,  and  the
348       latest     version     of     this    page,    can    be    found    at
349       https://www.kernel.org/doc/man-pages/.
350
351
352
353Linux                             2021-03-22                          SHMOP(2)
Impressum