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