X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sources%2FSharedMem.c;h=eab28f471368364e0ce34b950f81edd22712858f;hp=23f9c097d30cec89a4953586a25bd73f60550729;hb=730b0bb045c1794c4f4675605dc106b756e82d69;hpb=d6636dc7afc27b7ac5b9feb214031ae1e7fd2594 diff --git a/sources/SharedMem.c b/sources/SharedMem.c index 23f9c09..eab28f4 100644 --- a/sources/SharedMem.c +++ b/sources/SharedMem.c @@ -19,11 +19,14 @@ /*************************************************************** * * File SharedMem.c - * Routine for Shared Memory use + * Routines for Shared Memory use. + * + * Define two interfaces, the first one use SysV shared memory, the + * second POSIX shared memory. * * Author: S. Piccardi * - * $Id: SharedMem.c,v 1.2 2002/12/03 22:30:11 piccardi Exp $ + * $Id: SharedMem.c,v 1.3 2003/02/02 20:35:33 piccardi Exp $ * ***************************************************************/ #include /* SysV IPC shared memory declarations */ @@ -32,6 +35,15 @@ #include /* standard I/O functions */ #include #include /* signal handling declarations */ +#include +#include +#include +#include +/* ************************************************************************* + * + * Functions for SysV shared memory + * + * ************************************************************************* */ /* * Function ShmCreate: * Create and attach a SysV shared memory segment to the current process. @@ -46,42 +58,141 @@ * * Input: an IPC key value * the shared memory segment size - * Return: the address of the segment + * the permissions + * the fill value + * Return: the address of the shared memory segment (NULL on error) */ -void * ShmCreate(key_t ipc_key, int shm_size, char fill) +void * ShmCreate(key_t ipc_key, int shm_size, int perm, char fill) { - void * shptr; - int shmid; /* ID of the IPC shared memory segment */ - shmid = shmget(ipc_key,shm_size,IPC_CREAT|0666); /* get shm ID */ - if (shmid < 0) { - return (void *) shmid; + void * shm_ptr; + int shm_id; /* ID of the IPC shared memory segment */ + shm_id = shmget(ipc_key, shm_size, IPC_CREAT|perm); /* get shm ID */ + if (shm_id < 0) { + return NULL; } - shptr = shmat(shmid,0,0); /* take the pointer to it */ - if ( shptr == 0 ){ - perror("cannot attach shared memory"); - exit(1); + shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */ + if (shm_ptr < 0) { + return NULL; } - memset((void *)shptr, fill, shm_size); /* second counter starts from "0" */ - return shptr; + memset((void *)shm_ptr, fill, shm_size); /* fill segment */ + return shm_ptr; } /* * Function ShmFind: - * Find a shared memory segment + * Find a SysV shared memory segment * Input: an IPC key value * the shared memory segment size - * Return: the address of the segment + * Return: the address of the segment (NULL on error) */ void * ShmFind(key_t ipc_key, int shm_size) { - void * shptr; - int shmid; /* ID of the IPC shared memory segment */ - if ( (shmid=shmget(ipc_key,shm_size,0))<0 ){ /* find shared memory ID */ - perror("cannot find shared memory"); - exit(1); + void * shm_ptr; + int shm_id; /* ID of the SysV shared memory segment */ + shm_id = shmget(ipc_key, shm_size, 0); /* find shared memory ID */ + if (shm_id < 0) { + return NULL; + } + shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */ + if (shm_ptr < 0) { + return NULL; + } + return shm_ptr; +} +/* + * Function ShmRemove: + * Scheudle removal for a SysV shared memory segment + * Input: an IPC key value + * the shared memory segment size + * Return: 0 on success, -1 on error + */ +int ShmRemove(key_t ipc_key, void * shm_ptr) +{ + int shm_id; /* ID of the SysV shared memory segment */ + /* first detach segment */ + if (shmdt(shm_ptr) < 0) { + return -1; + } + /* schedule segment removal */ + shm_id = shmget(ipc_key, 0, 0); /* find shared memory ID */ + if (shm_id < 0) { + if (errno == EIDRM) return 0; + return -1; } - if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */ - perror("cannot attach shared memory"); - exit(1); + if (shmctl(shm_id, IPC_RMID, NULL) < 0) { /* ask for removal */ + if (errno == EIDRM) return 0; + return -1; } - return shptr; + return 0; +} +/* ************************************************************************* + * + * Functions for POSIX shared memory + * + * ************************************************************************* */ +/* + * Function CreateShm: + * Create a POSIX shared memory segment and map it to the current process. + * + * + * Input: a pathname + * the shared memory segment size + * the permissions + * the fill value + * Return: the address of the shared memory segment (NULL on error) + */ +void * CreateShm(char * shm_name, int shm_size, int perm, char fill) +{ + void * shm_ptr; + int fd; + int flag; + /* first open the object, creating it if not existent */ + flag = O_RDWR|O_TRUNC|O_CREAT|O_EXCL; + fd = shm_open(shm_name, flag, perm); /* get object file descriptor */ + if (fd < 0) { + return NULL; + } + /* set the object size */ + if (ftruncate(fd, shm_size)) { + return NULL; + } + /* map it in the process address space */ + shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); + if (shm_ptr == MAP_FAILED) { + return NULL; + } + memset((void *) shm_ptr, fill, shm_size); /* fill segment */ + return shm_ptr; +} +/* + * Function FindShm: + * Find a POSIX shared memory segment + * Input: a name + * the shared memory segment size + * Return: the address of the segment (NULL on error) + */ +void * FindShm(char * shm_name, int shm_size) +{ + void * shm_ptr; + int fd; /* ID of the IPC shared memory segment */ + /* find shared memory ID */ + if ((fd = shm_open(shm_name, O_RDWR|O_EXCL, 0)) < 0) { + return NULL; + } + /* take the pointer to it */ + shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); + if (shm_ptr == MAP_FAILED) { + return NULL; + } + return shm_ptr; +} +/* + * Function RemoveShm: + * Remove a POSIX shared memory segment + * Input: the object name + * Return: 0 on success, -1 on error + */ +int RemoveShm(char * shm_name) +{ + shm_unlink(shm_name); + return 0; }