3 * Copyright (C) 2002 Simone Piccardi
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /***************************************************************
22 * Routines for Shared Memory use.
24 * Define two interfaces, the first one use SysV shared memory, the
25 * second POSIX shared memory.
29 * $Id: SharedMem.c,v 1.6 2003/03/05 00:45:30 piccardi Exp $
31 ***************************************************************/
32 #include <sys/shm.h> /* SysV IPC shared memory declarations */
33 #include <sys/types.h>
35 #include <stdio.h> /* standard I/O functions */
37 #include <signal.h> /* signal handling declarations */
44 /* *************************************************************************
46 * Functions for SysV shared memory
48 * ************************************************************************* */
51 * Create and attach a SysV shared memory segment to the current process.
53 * First call get a shared memory segment with KEY key access and size SIZE,
54 * by creating it with R/W privilege for the user (this is the meaning of
55 * the ored flags). The function return an identifier shmid used for any
56 * further reference to the shared memory segment.
57 * Second call attach the shared memory segment to this process and return a
58 * pointer to it (of void * type).
59 * Then initialize shared memory to the given value
61 * Input: an IPC key value
62 * the shared memory segment size
65 * Return: the address of the shared memory segment (NULL on error)
67 void * ShmCreate(key_t ipc_key, int shm_size, int perm, int fill)
70 int shm_id; /* ID of the IPC shared memory segment */
71 shm_id = shmget(ipc_key, shm_size, IPC_CREAT|perm); /* get shm ID */
75 shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */
79 memset((void *)shm_ptr, fill, shm_size); /* fill segment */
84 * Find a SysV shared memory segment
85 * Input: an IPC key value
86 * the shared memory segment size
87 * Return: the address of the segment (NULL on error)
89 void * ShmFind(key_t ipc_key, int shm_size)
92 int shm_id; /* ID of the SysV shared memory segment */
93 shm_id = shmget(ipc_key, shm_size, 0); /* find shared memory ID */
97 shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */
104 * Function ShmRemove:
105 * Schedule removal for a SysV shared memory segment
106 * Input: an IPC key value
107 * the shared memory segment size
108 * Return: 0 on success, -1 on error
110 int ShmRemove(key_t ipc_key, void * shm_ptr)
112 int shm_id; /* ID of the SysV shared memory segment */
113 /* first detach segment */
114 if (shmdt(shm_ptr) < 0) {
117 /* schedule segment removal */
118 shm_id = shmget(ipc_key, 0, 0); /* find shared memory ID */
120 if (errno == EIDRM) return 0;
123 if (shmctl(shm_id, IPC_RMID, NULL) < 0) { /* ask for removal */
124 if (errno == EIDRM) return 0;
129 /* *************************************************************************
131 * Functions for POSIX shared memory
133 * ************************************************************************* */
135 * Function CreateShm:
136 * Create a POSIX shared memory segment and map it to the current process.
140 * the shared memory segment size
143 * Return: the address of the shared memory segment (NULL on error)
145 void * CreateShm(char * shm_name, off_t shm_size, mode_t perm, int fill)
150 /* first open the object, creating it if not existent */
151 flag = O_CREAT|O_EXCL|O_RDWR;
152 fd = shm_open(shm_name, flag, perm); /* get object file descriptor */
154 perror("errore in shm_open");
157 /* set the object size */
158 if (ftruncate(fd, shm_size)) {
159 perror("errore in ftruncate");
162 /* map it in the process address space */
163 shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
164 if (shm_ptr == MAP_FAILED) {
165 perror("errore in mmap");
168 memset((void *) shm_ptr, fill, shm_size); /* fill segment */
173 * Find a POSIX shared memory segment
175 * the shared memory segment size
176 * Return: the address of the segment (NULL on error)
178 void * FindShm(char * shm_name, off_t shm_size)
181 int fd; /* ID of the IPC shared memory segment */
182 /* find shared memory ID */
183 if ((fd = shm_open(shm_name, O_RDWR|O_EXCL, 0)) < 0) {
184 debug("Cannot open %s\n", shm_name);
187 /* take the pointer to it */
188 shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
189 if (shm_ptr == MAP_FAILED) {
195 * Function RemoveShm:
196 * Remove a POSIX shared memory segment
197 * Input: the object name
198 * Return: 0 on success, -1 on error
200 int RemoveShm(char * shm_name)
202 return shm_unlink(shm_name);