/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* COPYING NOTES
*
* shmtool.c -- functions to manage shared memory
*
* Copyright (C) 1995 Scott Burkett <scottb@IntNet.net>.
* as heavily derived from the Chapter 6 of The Linux Programmer's Guide
* Copyright (C) 2002 Roberto A. Foglietta <robang@libero.it>
* Copyright (C) 2002 GEA-Automotive <fogliettar@gea-automotive.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* REVISION NOTES:
* released 17-10-2002 by Roberto A. Foglietta
* bugfixed 22-01-2003 by Roberto A. Foglietta
* modified 29-05-2003 by Roberto A. Foglietta
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "shmtool.h"
//LOCAL FUNCTION
static char *getsegprt (int shmid);
int
initshm (key_t key, int del)
{
int shmid;
if(del) {
/* RAF 2003-05-29: Delete segment if it exist */
shmid = shmget (key, 0, 0);
if(shmid != -1)
removeshm(shmid);
}
/* Open the shared memory segment - create if necessary */
if ((shmid = shmget (key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666)) == -1) {
#ifdef SHM_TEST
perror ("shmget (key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666)");
printf ("Shared memory key: %ld - opening as client\n", (unsigned long)key);
#endif
/* RAF 2003-05-29: Segment wasn't deleted or didn't create proprely */
if(del) return -1;
/* Segment probably already exists - try as a client */
shmid = shmget (key, 0, 0);
if (shmid == -1)
perror ("shmget (key, 0, 0)");
} else {
#ifdef SHM_TEST
printf ("Creating new shared memory segment\n");
#endif
}
return shmid;
}
static char *
getsegprt (int shmid)
{
static char *segptr = NULL;
//printf("shmtools> getsegprt(%d);\n", shmid);
/* RAF 2003-01-22: set off bug that induce a memory leak every call of this func */
if(segptr == NULL) {
/* Attach (map) the shared memory segment into the current process */
segptr = (char *) shmat (shmid, 0, 0);
if (segptr == (char *) -1) {
perror ("shmat");
segptr = NULL;
}
}
return segptr;
}
int
writeshm (int shmid, char *text)
{
int ret = 0;
char *segptr = getsegprt (shmid);
//printf("shmtools> writeshm(%d, 0x%lx);\n", shmid, (unsigned long)text);
if (segptr != NULL) {
//printf("shmtools> %s\n", text);
ret = strlen (strncpy (segptr, text, SEGSIZE));
segptr[SEGSIZE-1] = 0; //RAF 2003-05-29
} else
ret = -1;
return ret;
}
char *
readshm (int shmid)
{
char *segptr = getsegprt (shmid);
if (segptr != NULL)
return strdup (segptr);
else
return NULL;
}
int
removeshm (int shmid)
{
#ifdef SHM_TEST
printf("Shared memory segment marked for deletion\n");
#endif
return shmctl (shmid, IPC_RMID, 0);
}
int
changemode (int shmid, char *mode)
{
struct shmid_ds myshmds;
unsigned int perms;
/* Get current values for internal data structure */
shmctl (shmid, IPC_STAT, &myshmds);
#ifdef SHM_TEST
/* Display old permissions */
printf("Old permissions were: %o\n", myshmds.shm_perm.mode);
#endif
/* Convert and load the mode */
sscanf (mode, "%o", &perms);
myshmds.shm_perm.mode = (unsigned short) perms;
/* Update the mode */
#ifdef SHM_TEST
printf("New permissions are : %o\n", myshmds.shm_perm.mode);
#endif
return shmctl (shmid, IPC_SET, &myshmds);
}