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 ***************************************************************/
30 #include <sys/shm.h> /* SysV shared memory */
31 #include <sys/types.h> /* primitive system data types */
32 #include <sys/stat.h> /* file characteristics constants and functions */
33 #include <stdio.h> /* standard I/O library */
34 #include <fcntl.h> /* file control functions */
35 #include <signal.h> /* signal constants, types and functions */
36 #include <unistd.h> /* unix standard library */
38 #include <string.h> /* C strings library */
39 #include <errno.h> /* error definitions and routines */
42 /* *************************************************************************
44 * Functions for SysV shared memory
46 * ************************************************************************* */
49 * Create and attach a SysV shared memory segment to the current process.
51 * First call get a shared memory segment with KEY key access and size SIZE,
52 * by creating it with R/W privilege for the user (this is the meaning of
53 * the ored flags). The function return an identifier shmid used for any
54 * further reference to the shared memory segment.
55 * Second call attach the shared memory segment to this process and return a
56 * pointer to it (of void * type).
57 * Then initialize shared memory to the given value
59 * Input: an IPC key value
60 * the shared memory segment size
63 * Return: the address of the shared memory segment (NULL on error)
65 void * ShmCreate(key_t ipc_key, int shm_size, int perm, int fill)
68 int shm_id; /* ID of the IPC shared memory segment */
69 shm_id = shmget(ipc_key, shm_size, IPC_CREAT|perm); /* get shm ID */
73 shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */
77 memset((void *)shm_ptr, fill, shm_size); /* fill segment */
82 * Find a SysV shared memory segment
83 * Input: an IPC key value
84 * the shared memory segment size
85 * Return: the address of the segment (NULL on error)
87 void * ShmFind(key_t ipc_key, int shm_size)
90 int shm_id; /* ID of the SysV shared memory segment */
91 shm_id = shmget(ipc_key, shm_size, 0); /* find shared memory ID */
95 shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */
102 * Function ShmRemove:
103 * Schedule removal for a SysV shared memory segment
104 * Input: an IPC key value
105 * the shared memory segment size
106 * Return: 0 on success, -1 on error
108 int ShmRemove(key_t ipc_key, void * shm_ptr)
110 int shm_id; /* ID of the SysV shared memory segment */
111 /* first detach segment */
112 if (shmdt(shm_ptr) < 0) {
115 /* schedule segment removal */
116 shm_id = shmget(ipc_key, 0, 0); /* find shared memory ID */
118 if (errno == EIDRM) return 0;
121 if (shmctl(shm_id, IPC_RMID, NULL) < 0) { /* ask for removal */
122 if (errno == EIDRM) return 0;
127 /* *************************************************************************
129 * Functions for POSIX shared memory
131 * ************************************************************************* */
133 * Function CreateShm:
134 * Create a POSIX shared memory segment and map it to the current process.
138 * the shared memory segment size
141 * Return: the address of the shared memory segment (NULL on error)
143 void * CreateShm(char * shm_name, off_t shm_size, mode_t perm, int fill)
148 /* first open the object, creating it if not existent */
149 flag = O_CREAT|O_EXCL|O_RDWR;
150 fd = shm_open(shm_name, flag, perm); /* get object file descriptor */
152 perror("errore in shm_open");
155 /* set the object size */
156 if (ftruncate(fd, shm_size)) {
157 perror("errore in ftruncate");
160 /* map it in the process address space */
161 shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
162 if (shm_ptr == MAP_FAILED) {
163 perror("errore in mmap");
166 memset((void *) shm_ptr, fill, shm_size); /* fill segment */
171 * Find a POSIX shared memory segment
173 * the shared memory segment size
174 * Return: the address of the segment (NULL on error)
176 void * FindShm(char * shm_name, off_t shm_size)
179 int fd; /* ID of the IPC shared memory segment */
180 /* find shared memory ID */
181 if ((fd = shm_open(shm_name, O_RDWR|O_EXCL, 0)) < 0) {
182 debug("Cannot open %s\n", shm_name);
185 /* take the pointer to it */
186 shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
187 if (shm_ptr == MAP_FAILED) {
193 * Function RemoveShm:
194 * Remove a POSIX shared memory segment
195 * Input: the object name
196 * Return: 0 on success, -1 on error
198 int RemoveShm(char * shm_name)
200 return shm_unlink(shm_name);