/*****************************************************************************
Excerpt from "Linux Programmer's Guide - Chapter 6"
(C)opyright 1994-1995, Scott Burkett
*****************************************************************************
MODULE: shmtool.c
*****************************************************************************
A command line tool for tinkering with shared memory
*****************************************************************************/
/*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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, see .
*
* See the COPYING file for full license information.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "common.h"
#if HAVE_SYS_IPC_H
# include
#endif
#if HAVE_SYS_SHM_H
# include
#endif
#define SEGSIZE 100
int
usage ()
{
fprintf (stderr, "shmtool - A utility for tinkering with shared memory\n");
fprintf (stderr, "\nUSAGE: shmtool (w)rite \n");
fprintf (stderr, " (r)ead\n");
fprintf (stderr, " (d)elete\n");
fprintf (stderr, " (m)ode change \n");
exit (1);
}
int
writeshm (int shmid, char *segptr, char *text)
{
strcpy (segptr, text);
printf ("Done...\n");
}
int
readshm (int shmid, char *segptr)
{
printf ("segptr: %s\n", segptr);
}
int
removeshm (int shmid)
{
shmctl (shmid, IPC_RMID, 0);
printf ("Shared memory segment marked for deletion\n");
}
int
changemode (int shmid, char *mode)
{
struct shmid_ds myshmds;
/* Get current values for internal data structure */
shmctl (shmid, IPC_STAT, &myshmds);
/* Display old permissions */
printf ("Old permissions were: %o\n", myshmds.shm_perm.mode);
/* Convert and load the mode */
sscanf (mode, "%o", &myshmds.shm_perm.mode);
/* Update the mode */
shmctl (shmid, IPC_SET, &myshmds);
printf ("New permissions are : %o\n", myshmds.shm_perm.mode);
}
int
main (int argc, char *argv[])
{
key_t key;
int shmid, cntr;
char *segptr;
if (argc == 1)
usage ();
/* Create unique key via call to ftok() */
key = ftok (".", 'S');
/* Open the shared memory segment - create if necessary */
if ((shmid = shmget (key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666)) == -1)
{
printf ("Shared memory segment exists - opening as client\n");
/* Segment probably already exists - try as a client */
if ((shmid = shmget (key, SEGSIZE, 0)) == -1)
{
perror ("shmget");
exit (1);
}
}
else
{
printf ("Creating new shared memory segment\n");
}
/* Attach (map) the shared memory segment into the current process */
if ((segptr = shmat (shmid, 0, 0)) == ((char *) -1))
{
perror ("shmat");
exit (1);
}
switch (tolower (argv[1][0]))
{
case 'w':
writeshm (shmid, segptr, argv[2]);
break;
case 'r':
readshm (shmid, segptr);
break;
case 'd':
removeshm (shmid);
break;
case 'm':
changemode (shmid, argv[2]);
break;
default:
usage ();
}
}