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/types.h>
10       #include <sys/shm.h>
11
12       void *shmat(int shmid, const void *shmaddr, int shmflg);
13
14       int shmdt(const void *shmaddr);
15

DESCRIPTION

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

RETURN VALUE

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

ERRORS

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

CONFORMING TO

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

NOTES

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

EXAMPLES

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

SEE ALSO

340       brk(2),  mmap(2),  shmctl(2),  shmget(2),  capabilities(7),   shm_over‐
341       view(7), sysvipc(7)
342

COLOPHON

344       This  page  is  part of release 5.07 of the Linux man-pages project.  A
345       description of the project, information about reporting bugs,  and  the
346       latest     version     of     this    page,    can    be    found    at
347       https://www.kernel.org/doc/man-pages/.
348
349
350
351Linux                             2020-04-11                          SHMOP(2)
Impressum