ipcs.c revision 1.1 1 1.1 cgd /*
2 1.1 cgd * Simplified implementation of SYSV ipcs.
3 1.1 cgd *
4 1.1 cgd * $Id: ipcs.c,v 1.1 1993/11/14 16:17:58 cgd Exp $
5 1.1 cgd */
6 1.1 cgd
7 1.1 cgd #include <nlist.h>
8 1.1 cgd #include <stdio.h>
9 1.1 cgd #include <stdlib.h>
10 1.1 cgd #include <unistd.h>
11 1.1 cgd #include <paths.h>
12 1.1 cgd
13 1.1 cgd #include <sys/types.h>
14 1.1 cgd #include <sys/param.h>
15 1.1 cgd #include <sys/proc.h>
16 1.1 cgd #define KERNEL
17 1.1 cgd #include <sys/ipc.h>
18 1.1 cgd #include <sys/sem.h>
19 1.1 cgd #include <sys/shm.h>
20 1.1 cgd #include <sys/msg.h>
21 1.1 cgd
22 1.1 cgd static kmem_fd;
23 1.1 cgd
24 1.1 cgd getsymbol(struct nlist * symbols, char *symname, void *dptr, int len)
25 1.1 cgd {
26 1.1 cgd int i, rlen;
27 1.1 cgd
28 1.1 cgd for (i = 0; symbols[i].n_name != NULL; i += 1) {
29 1.1 cgd if (strcmp(symbols[i].n_name, symname) == 0) {
30 1.1 cgd break;
31 1.1 cgd }
32 1.1 cgd }
33 1.1 cgd
34 1.1 cgd if (symbols[i].n_name == NULL) {
35 1.1 cgd fprintf(stderr,
36 1.1 cgd "ipcs(getsymbol): symbol %s not in local symbols list\n",
37 1.1 cgd symname);
38 1.1 cgd exit(1);
39 1.1 cgd }
40 1.1 cgd
41 1.1 cgd if (symbols[i].n_value == NULL) {
42 1.1 cgd fprintf(stderr, "ipcs(getsymbol): symbol %s not in %s\n",
43 1.1 cgd symname, _PATH_UNIX);
44 1.1 cgd return (0);
45 1.1 cgd }
46 1.1 cgd
47 1.1 cgd if (kmem_fd == 0) {
48 1.1 cgd kmem_fd = open("/dev/kmem", 0);
49 1.1 cgd if (kmem_fd < 0) {
50 1.1 cgd perror("ipcs(getsymbol(open /dev/kmem))");
51 1.1 cgd exit(1);
52 1.1 cgd }
53 1.1 cgd }
54 1.1 cgd
55 1.1 cgd lseek(kmem_fd, symbols[i].n_value, SEEK_SET);
56 1.1 cgd if ((rlen = read(kmem_fd, dptr, len)) != len) {
57 1.1 cgd fprintf(stderr,
58 1.1 cgd "ipcs(getsymbol): can't fetch symbol %s from /dev/kmem\n",
59 1.1 cgd symname);
60 1.1 cgd exit(1);
61 1.1 cgd }
62 1.1 cgd return (1);
63 1.1 cgd }
64 1.1 cgd
65 1.1 cgd void
66 1.1 cgd getlocation(void *addr, void *dptr, int len)
67 1.1 cgd {
68 1.1 cgd int i, rlen;
69 1.1 cgd
70 1.1 cgd if (kmem_fd == 0) {
71 1.1 cgd kmem_fd = open("/dev/kmem", 0);
72 1.1 cgd if (kmem_fd < 0) {
73 1.1 cgd perror("ipcs(getlocation(open /dev/kmem))");
74 1.1 cgd exit(1);
75 1.1 cgd }
76 1.1 cgd }
77 1.1 cgd
78 1.1 cgd lseek(kmem_fd, (long) addr, SEEK_SET);
79 1.1 cgd if ((rlen = read(kmem_fd, dptr, len)) != len) {
80 1.1 cgd fprintf(stderr,"ipcs(getlocation): can't fetch location %08x from /dev/kmem\n",
81 1.1 cgd addr);
82 1.1 cgd exit(1);
83 1.1 cgd }
84 1.1 cgd }
85 1.1 cgd
86 1.1 cgd char *
87 1.1 cgd fmt_perm(ushort mode)
88 1.1 cgd {
89 1.1 cgd static char buffer[100];
90 1.1 cgd
91 1.1 cgd buffer[0] = '-';
92 1.1 cgd buffer[1] = '-';
93 1.1 cgd buffer[2] = ((mode & 0400) ? 'r' : '-');
94 1.1 cgd buffer[3] = ((mode & 0200) ? 'w' : '-');
95 1.1 cgd buffer[4] = ((mode & 0100) ? 'a' : '-');
96 1.1 cgd buffer[5] = ((mode & 0040) ? 'r' : '-');
97 1.1 cgd buffer[6] = ((mode & 0020) ? 'w' : '-');
98 1.1 cgd buffer[7] = ((mode & 0010) ? 'a' : '-');
99 1.1 cgd buffer[8] = ((mode & 0004) ? 'r' : '-');
100 1.1 cgd buffer[9] = ((mode & 0002) ? 'w' : '-');
101 1.1 cgd buffer[10] = ((mode & 0001) ? 'a' : '-');
102 1.1 cgd buffer[11] = '\0';
103 1.1 cgd return (&buffer[0]);
104 1.1 cgd }
105 1.1 cgd
106 1.1 cgd void
107 1.1 cgd cvt_time(time_t t, char *buf)
108 1.1 cgd {
109 1.1 cgd struct tm tms;
110 1.1 cgd static char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
111 1.1 cgd "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
112 1.1 cgd
113 1.1 cgd if (t == 0) {
114 1.1 cgd strcpy(buf, "<not set>");
115 1.1 cgd }
116 1.1 cgd else {
117 1.1 cgd tms = *localtime(&t);
118 1.1 cgd if (t > time(0) - 6 * 30 * 24 * 3600) { /* less than about 6
119 1.1 cgd months ago? */
120 1.1 cgd sprintf(buf, "%s %2d %2d:%2d",
121 1.1 cgd months[tms.tm_mon], tms.tm_mday, tms.tm_hour,
122 1.1 cgd tms.tm_min);
123 1.1 cgd }
124 1.1 cgd else {
125 1.1 cgd sprintf(buf, "%s %2d %5d",
126 1.1 cgd months[tms.tm_mon], tms.tm_mday,
127 1.1 cgd tms.tm_year + 1900);
128 1.1 cgd }
129 1.1 cgd }
130 1.1 cgd }
131 1.1 cgd
132 1.1 cgd main()
133 1.1 cgd {
134 1.1 cgd static struct nlist symbols[] = {
135 1.1 cgd {"_sema"},
136 1.1 cgd {"_seminfo"},
137 1.1 cgd {"_semu"},
138 1.1 cgd {"_msginfo"},
139 1.1 cgd {"_msqids"},
140 1.1 cgd {NULL}
141 1.1 cgd };
142 1.1 cgd int i;
143 1.1 cgd int show_sem_values = 1;
144 1.1 cgd int show_undo_values = 1;
145 1.1 cgd
146 1.1 cgd switch (nlist(_PATH_UNIX, &symbols[0])) {
147 1.1 cgd case 0:
148 1.1 cgd break;
149 1.1 cgd case -1:
150 1.1 cgd fprintf(stderr, "ipcs: can't open %s - bye!\n", _PATH_UNIX);
151 1.1 cgd exit(1);
152 1.1 cgd default:
153 1.1 cgd fprintf(stderr, "ipcs: nlist failed\n");
154 1.1 cgd for (i = 0; symbols[i].n_name != NULL; i += 1) {
155 1.1 cgd if (symbols[i].n_value == 0) {
156 1.1 cgd fprintf(stderr, "\tsymbol %s not found\n",
157 1.1 cgd symbols[i].n_name);
158 1.1 cgd }
159 1.1 cgd }
160 1.1 cgd break;
161 1.1 cgd }
162 1.1 cgd
163 1.1 cgd #ifdef notdef
164 1.1 cgd for ( i = 0; symbols[i].n_name != NULL; i += 1 ) {
165 1.1 cgd fprintf(stderr,"\t%s : %08x\n",symbols[i].n_name,
166 1.1 cgd symbols[i].n_value);
167 1.1 cgd }
168 1.1 cgd #endif
169 1.1 cgd
170 1.1 cgd if (getsymbol(symbols, "_seminfo", &seminfo, sizeof(seminfo))) {
171 1.1 cgd struct semid_ds *xsema;
172 1.1 cgd
173 1.1 cgd printf("seminfo:\n");
174 1.1 cgd printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",
175 1.1 cgd seminfo.semmap);
176 1.1 cgd printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",
177 1.1 cgd seminfo.semmni);
178 1.1 cgd printf("\tsemmns: %6d\t(# of semaphores in system)\n",
179 1.1 cgd seminfo.semmns);
180 1.1 cgd printf("\tsemmnu: %6d\t(# of undo structures in system)\n",
181 1.1 cgd seminfo.semmnu);
182 1.1 cgd printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",
183 1.1 cgd seminfo.semmsl);
184 1.1 cgd printf("\tsemopm: %6d\t(max # of operations per semop call)\n",
185 1.1 cgd seminfo.semopm);
186 1.1 cgd printf("\tsemume: %6d\t(max # of undo entries per process)\n",
187 1.1 cgd seminfo.semume);
188 1.1 cgd printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",
189 1.1 cgd seminfo.semusz);
190 1.1 cgd printf("\tsemvmx: %6d\t(semaphore maximum value)\n",
191 1.1 cgd seminfo.semvmx);
192 1.1 cgd printf("\tsemaem: %6d\t(adjust on exit max value)\n",
193 1.1 cgd seminfo.semaem);
194 1.1 cgd
195 1.1 cgd /*
196 1.1 cgd * Lock out other users of the semaphore facility
197 1.1 cgd */
198 1.1 cgd
199 1.1 cgd if (semconfig(SEM_CONFIG_FREEZE) != 0) {
200 1.1 cgd perror("semconfig");
201 1.1 cgd fprintf(stderr,
202 1.1 cgd "Can't lock semaphore facility - winging it...\n");
203 1.1 cgd }
204 1.1 cgd
205 1.1 cgd getsymbol(symbols, "_sema", &sema, sizeof(sema));
206 1.1 cgd xsema = malloc(sizeof(struct semid_ds) * seminfo.semmni);
207 1.1 cgd getlocation(sema, xsema, sizeof(struct semid_ds) *
208 1.1 cgd seminfo.semmni);
209 1.1 cgd
210 1.1 cgd for (i = 0; i < seminfo.semmni; i += 1) {
211 1.1 cgd if ((xsema[i].sem_perm.mode & SEM_ALLOC) != 0) {
212 1.1 cgd char ctime_buf[100], otime_buf[100];
213 1.1 cgd struct semid_ds *semaptr = &xsema[i];
214 1.1 cgd
215 1.1 cgd cvt_time(semaptr->sem_ctime, ctime_buf);
216 1.1 cgd cvt_time(semaptr->sem_otime, otime_buf);
217 1.1 cgd
218 1.1 cgd printf("\nsema id: %d key: 0x%08x:\n",
219 1.1 cgd IXSEQ_TO_IPCID(i, semaptr->sem_perm),
220 1.1 cgd semaptr->sem_perm.key);
221 1.1 cgd
222 1.1 cgd printf(" cuid: %6d cgid: %6d ctime: %s\n",
223 1.1 cgd semaptr->sem_perm.cuid,
224 1.1 cgd semaptr->sem_perm.cgid, ctime_buf);
225 1.1 cgd
226 1.1 cgd printf(" uid: %6d gid: %6d otime: %s\n",
227 1.1 cgd semaptr->sem_perm.uid,
228 1.1 cgd semaptr->sem_perm.gid, otime_buf);
229 1.1 cgd
230 1.1 cgd printf(" nsems: %6d perm: %s\n",
231 1.1 cgd semaptr->sem_nsems,
232 1.1 cgd fmt_perm(semaptr->sem_perm.mode));
233 1.1 cgd
234 1.1 cgd if (show_sem_values) {
235 1.1 cgd int j, value;
236 1.1 cgd union semun junk;
237 1.1 cgd
238 1.1 cgd for (j = 0; j < semaptr->sem_nsems;
239 1.1 cgd j += 1) {
240 1.1 cgd if ((value = semctl(IXSEQ_TO_IPCID(i, semaptr->sem_perm), j, GETVAL, junk)) < 0) {
241 1.1 cgd printf("can't get semaphore values\n");
242 1.1 cgd break;
243 1.1 cgd }
244 1.1 cgd if (j % 5 == 0) {
245 1.1 cgd if (j == 0) {
246 1.1 cgd printf(" values: {");
247 1.1 cgd }
248 1.1 cgd else {
249 1.1 cgd printf("\n");
250 1.1 cgd printf(" ");
251 1.1 cgd }
252 1.1 cgd }
253 1.1 cgd printf(" %d", value);
254 1.1 cgd if (j == semaptr->sem_nsems - 1) {
255 1.1 cgd printf(" }\n");
256 1.1 cgd }
257 1.1 cgd else {
258 1.1 cgd printf(", ");
259 1.1 cgd }
260 1.1 cgd }
261 1.1 cgd }
262 1.1 cgd }
263 1.1 cgd }
264 1.1 cgd
265 1.1 cgd if (show_undo_values) {
266 1.1 cgd int j;
267 1.1 cgd int *ksemu, *semu;
268 1.1 cgd int semu_size;
269 1.1 cgd int got_one_undo = 0;
270 1.1 cgd
271 1.1 cgd semu = 0;
272 1.1 cgd semu_size = (int) SEMU(seminfo.semmnu);
273 1.1 cgd semu = (int *) malloc(semu_size);
274 1.1 cgd getsymbol(symbols, "_semu", &ksemu, sizeof(ksemu));
275 1.1 cgd getlocation(ksemu, semu, semu_size);
276 1.1 cgd
277 1.1 cgd printf("\nsem undos:\n");
278 1.1 cgd for (j = 0; j < seminfo.semmnu; j += 1) {
279 1.1 cgd struct sem_undo *suptr;
280 1.1 cgd int k;
281 1.1 cgd
282 1.1 cgd suptr = SEMU(j);
283 1.1 cgd if (suptr->un_proc != NULL) {
284 1.1 cgd struct proc proc;
285 1.1 cgd
286 1.1 cgd getlocation(suptr->un_proc, &proc,
287 1.1 cgd sizeof(proc));
288 1.1 cgd got_one_undo = 1;
289 1.1 cgd printf(" pid %d: semid semnum adjval\n",
290 1.1 cgd proc.p_pid);
291 1.1 cgd for (k = 0; k < suptr->un_cnt; k += 1) {
292 1.1 cgd printf(" %10d %5d %6d\n",
293 1.1 cgd IXSEQ_TO_IPCID(suptr->un_ent[k].un_id, xsema[suptr->un_ent[k].un_id].sem_perm),
294 1.1 cgd suptr->un_ent[k].un_num,
295 1.1 cgd suptr->un_ent[k].un_adjval);
296 1.1 cgd }
297 1.1 cgd }
298 1.1 cgd }
299 1.1 cgd if (!got_one_undo) {
300 1.1 cgd printf(" none allocated\n");
301 1.1 cgd }
302 1.1 cgd }
303 1.1 cgd
304 1.1 cgd (void) semconfig(SEM_CONFIG_THAW);
305 1.1 cgd
306 1.1 cgd }
307 1.1 cgd else {
308 1.1 cgd fprintf(stderr, "SVID semaphores facility not configured in the system\n");
309 1.1 cgd }
310 1.1 cgd
311 1.1 cgd if (getsymbol(symbols, "_msginfo", &msginfo, sizeof(msginfo))) {
312 1.1 cgd struct msqid_ds *xmsqids;
313 1.1 cgd
314 1.1 cgd printf("\nmsginfo:\n");
315 1.1 cgd printf("\tmsgmax: %6d\t(max characters in a message)\n",
316 1.1 cgd msginfo.msgmax);
317 1.1 cgd printf("\tmsgmni: %6d\t(# of message queues)\n",
318 1.1 cgd msginfo.msgmni);
319 1.1 cgd printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",
320 1.1 cgd msginfo.msgmnb);
321 1.1 cgd printf("\tmsgtql: %6d\t(max # of messages in system)\n",
322 1.1 cgd msginfo.msgtql);
323 1.1 cgd printf("\tmsgssz: %6d\t(size of a message segment)\n",
324 1.1 cgd msginfo.msgssz);
325 1.1 cgd printf("\tmsgseg: %6d\t(# of message segments in system)\n",
326 1.1 cgd msginfo.msgseg);
327 1.1 cgd
328 1.1 cgd getsymbol(symbols, "_msqids", &msqids, sizeof(msqids));
329 1.1 cgd xmsqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni);
330 1.1 cgd getlocation(msqids, xmsqids, sizeof(struct msqid_ds) *
331 1.1 cgd msginfo.msgmni);
332 1.1 cgd
333 1.1 cgd for (i = 0; i < msginfo.msgmni; i += 1) {
334 1.1 cgd if (xmsqids[i].msg_qbytes != 0) {
335 1.1 cgd char stime_buf[100], rtime_buf[100],
336 1.1 cgd ctime_buf[100];
337 1.1 cgd struct msqid_ds *msqptr = &xmsqids[i];
338 1.1 cgd
339 1.1 cgd cvt_time(msqptr->msg_stime, stime_buf);
340 1.1 cgd cvt_time(msqptr->msg_rtime, rtime_buf);
341 1.1 cgd cvt_time(msqptr->msg_ctime, ctime_buf);
342 1.1 cgd
343 1.1 cgd printf("\nmsgq id: %d key: 0x%08x\n",
344 1.1 cgd IXSEQ_TO_IPCID(i, msqptr->msg_perm),
345 1.1 cgd msqptr->msg_perm.key);
346 1.1 cgd
347 1.1 cgd printf(" cuid: %6d cgid: %6d ctime: %s\n",
348 1.1 cgd msqptr->msg_perm.cuid,
349 1.1 cgd msqptr->msg_perm.cgid, ctime_buf);
350 1.1 cgd
351 1.1 cgd printf(" uid: %6d gid: %6d\n",
352 1.1 cgd msqptr->msg_perm.uid,
353 1.1 cgd msqptr->msg_perm.gid);
354 1.1 cgd
355 1.1 cgd printf(" lspid: %6d stime: %s\n",
356 1.1 cgd msqptr->msg_lspid, stime_buf);
357 1.1 cgd
358 1.1 cgd printf(" lrpid: %6d qnum: %6d rtime: %s\n",
359 1.1 cgd msqptr->msg_lrpid, msqptr->msg_qnum,
360 1.1 cgd rtime_buf);
361 1.1 cgd
362 1.1 cgd printf(" cbytes:%6d qbytes:%6d perm: %s\n",
363 1.1 cgd msqptr->msg_cbytes, msqptr->msg_qbytes,
364 1.1 cgd fmt_perm(msqptr->msg_perm.mode));
365 1.1 cgd }
366 1.1 cgd }
367 1.1 cgd }
368 1.1 cgd else {
369 1.1 cgd fprintf(stderr,
370 1.1 cgd "SVID messages facility not configured in the system\n");
371 1.1 cgd }
372 1.1 cgd
373 1.1 cgd exit(0);
374 1.1 cgd }
375