]>
Commit | Line | Data |
---|---|---|
1 | /***************************************************************************** | |
2 | Excerpt from "Linux Programmer's Guide - Chapter 6" | |
3 | (C)opyright 1994-1995, Scott Burkett | |
4 | ***************************************************************************** | |
5 | MODULE: shmtool.c | |
6 | ***************************************************************************** | |
7 | A command line tool for tinkering with shared memory | |
8 | ||
9 | *****************************************************************************/ | |
10 | /* | |
11 | * This program is free software: you can redistribute it and/or modify | |
12 | * it under the terms of the GNU General Public License as published by | |
13 | * the Free Software Foundation, either version 3 of the License, or | |
14 | * (at your option) any later version. | |
15 | * | |
16 | * This program is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | * GNU General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU General Public License | |
22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
23 | * | |
24 | * See the COPYING file for full license information. | |
25 | */ | |
26 | ||
27 | #if HAVE_CONFIG_H | |
28 | # include "config.h" | |
29 | #endif | |
30 | ||
31 | #include "common.h" | |
32 | ||
33 | #if HAVE_SYS_IPC_H | |
34 | # include <sys/ipc.h> | |
35 | #endif | |
36 | #if HAVE_SYS_SHM_H | |
37 | # include <sys/shm.h> | |
38 | #endif | |
39 | ||
40 | #define SEGSIZE 100 | |
41 | ||
42 | int | |
43 | usage () | |
44 | { | |
45 | fprintf (stderr, "shmtool - A utility for tinkering with shared memory\n"); | |
46 | fprintf (stderr, "\nUSAGE: shmtool (w)rite <text>\n"); | |
47 | fprintf (stderr, " (r)ead\n"); | |
48 | fprintf (stderr, " (d)elete\n"); | |
49 | fprintf (stderr, " (m)ode change <octal mode>\n"); | |
50 | exit (1); | |
51 | } | |
52 | ||
53 | int | |
54 | writeshm (int shmid, char *segptr, char *text) | |
55 | { | |
56 | strcpy (segptr, text); | |
57 | printf ("Done...\n"); | |
58 | } | |
59 | ||
60 | int | |
61 | readshm (int shmid, char *segptr) | |
62 | { | |
63 | printf ("segptr: %s\n", segptr); | |
64 | } | |
65 | ||
66 | int | |
67 | removeshm (int shmid) | |
68 | { | |
69 | shmctl (shmid, IPC_RMID, 0); | |
70 | printf ("Shared memory segment marked for deletion\n"); | |
71 | } | |
72 | ||
73 | int | |
74 | changemode (int shmid, char *mode) | |
75 | { | |
76 | struct shmid_ds myshmds; | |
77 | ||
78 | /* Get current values for internal data structure */ | |
79 | shmctl (shmid, IPC_STAT, &myshmds); | |
80 | ||
81 | /* Display old permissions */ | |
82 | printf ("Old permissions were: %o\n", myshmds.shm_perm.mode); | |
83 | ||
84 | /* Convert and load the mode */ | |
85 | sscanf (mode, "%o", &myshmds.shm_perm.mode); | |
86 | ||
87 | /* Update the mode */ | |
88 | shmctl (shmid, IPC_SET, &myshmds); | |
89 | ||
90 | printf ("New permissions are : %o\n", myshmds.shm_perm.mode); | |
91 | } | |
92 | ||
93 | int | |
94 | main (int argc, char *argv[]) | |
95 | { | |
96 | key_t key; | |
97 | int shmid, cntr; | |
98 | char *segptr; | |
99 | ||
100 | if (argc == 1) | |
101 | usage (); | |
102 | ||
103 | /* Create unique key via call to ftok() */ | |
104 | key = ftok (".", 'S'); | |
105 | ||
106 | /* Open the shared memory segment - create if necessary */ | |
107 | if ((shmid = shmget (key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666)) == -1) | |
108 | { | |
109 | printf ("Shared memory segment exists - opening as client\n"); | |
110 | ||
111 | /* Segment probably already exists - try as a client */ | |
112 | if ((shmid = shmget (key, SEGSIZE, 0)) == -1) | |
113 | { | |
114 | perror ("shmget"); | |
115 | exit (1); | |
116 | } | |
117 | } | |
118 | else | |
119 | { | |
120 | printf ("Creating new shared memory segment\n"); | |
121 | } | |
122 | ||
123 | /* Attach (map) the shared memory segment into the current process */ | |
124 | if ((segptr = shmat (shmid, 0, 0)) == ((char *) -1)) | |
125 | { | |
126 | perror ("shmat"); | |
127 | exit (1); | |
128 | } | |
129 | ||
130 | switch (tolower (argv[1][0])) | |
131 | { | |
132 | case 'w': | |
133 | writeshm (shmid, segptr, argv[2]); | |
134 | break; | |
135 | case 'r': | |
136 | readshm (shmid, segptr); | |
137 | break; | |
138 | case 'd': | |
139 | removeshm (shmid); | |
140 | break; | |
141 | case 'm': | |
142 | changemode (shmid, argv[2]); | |
143 | break; | |
144 | default: | |
145 | usage (); | |
146 | ||
147 | } | |
148 | } |