]> git.ipfire.org Git - thirdparty/util-linux.git/blame - sys-utils/ipcs.c
Imported from util-linux-2.5 tarball.
[thirdparty/util-linux.git] / sys-utils / ipcs.c
CommitLineData
6dbe3af9
KZ
1/* Original author unknown, but may be "krishna balasub@cis.ohio-state.edu"
2 Modified Sat Oct 9 10:55:28 1993 for 0.99.13 */
3
4/* Patches from Mike Jagdis (jaggy@purplet.demon.co.uk) applied Wed Feb 8
512:12:21 1995 by faith@cs.unc.edu to print numeric uids if no passwd file
6entry. */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <getopt.h>
11#include <errno.h>
12#include <time.h>
13#include <pwd.h>
14#include <grp.h>
15#define __KERNEL__
726f69e2 16#include <linux/linkage.h>
6dbe3af9
KZ
17#include <sys/sem.h>
18#include <sys/msg.h>
19#include <sys/shm.h>
20
21
22#define LIMITS 1
23#define STATUS 2
24#define CREATOR 3
25#define TIME 4
26#define PID 5
27
28void do_shm (char format);
29void do_sem (char format);
30void do_msg (char format);
31void print_shm (int id);
32void print_msg (int id);
33void print_sem (int id);
34
35static char *progname;
36
37void usage(void)
38{
39 printf ("usage : %s -asmq -tclup \n", progname);
40 printf ("\t%s [-s -m -q] -i id\n", progname);
41 printf ("\t%s -h for help.\n", progname);
42 return;
43}
44
45void help (void)
46{
47 printf ("%s provides information on ipc facilities for", progname);
48 printf (" which you have read access.\n");
49 printf ("Resource Specification:\n\t-m : shared_mem\n\t-q : messages\n");
50 printf ("\t-s : semaphores\n\t-a : all (default)\n");
51 printf ("Output Format:\n\t-t : time\n\t-p : pid\n\t-c : creator\n");
52 printf ("\t-l : limits\n\t-u : summary\n");
53 printf ("-i id [-s -q -m] : details on resource identified by id\n");
54 usage();
55 return;
56}
57
58int main (int argc, char **argv)
59{
60 int opt, msg = 0, sem = 0, shm = 0, id=0, print=0;
61 char format = 0;
62 char options[] = "atcluphsmqi:";
63
64 progname = argv[0];
65 while ((opt = getopt (argc, argv, options)) != EOF) {
66 switch (opt) {
67 case 'i':
68 id = atoi (optarg);
69 print = 1;
70 break;
71 case 'a':
72 msg = shm = sem = 1;
73 break;
74 case 'q':
75 msg = 1;
76 break;
77 case 's':
78 sem = 1;
79 break;
80 case 'm':
81 shm = 1;
82 break;
83 case 't':
84 format = TIME;
85 break;
86 case 'c':
87 format = CREATOR;
88 break;
89 case 'p':
90 format = PID;
91 break;
92 case 'l':
93 format = LIMITS;
94 break;
95 case 'u':
96 format = STATUS;
97 break;
98 case 'h':
99 help();
100 exit (0);
101 case '?':
102 usage();
103 exit (0);
104 }
105 }
106
107 if (print) {
108 if (shm) {
109 print_shm (id);
110 exit (0);
111 }
112 if (sem) {
113 print_sem (id);
114 exit (0);
115 }
116 if (msg) {
117 print_msg (id);
118 exit (0);
119 }
120 usage();
121 }
122
123 if ( !shm && !msg && !sem)
124 msg = sem = shm = 1;
125 printf ("\n");
126
127 if (shm) {
128 do_shm (format);
129 printf ("\n");
130 }
131 if (sem) {
132 do_sem (format);
133 printf ("\n");
134 }
135 if (msg) {
136 do_msg (format);
137 printf ("\n");
138 }
139 return 0;
140}
141
142
143void print_perms (int id, struct ipc_perm *ipcp)
144{
145 struct passwd *pw;
146 struct group *gr;
147
148 printf ("%-10d%-10o", id, ipcp->mode & 0777);
149
150 if ((pw = getpwuid(ipcp->cuid)))
151 printf("%-10s", pw->pw_name);
152 else
153 printf("%-10d", ipcp->cuid);
154 if ((gr = getgrgid(ipcp->cgid)))
155 printf("%-10s", gr->gr_name);
156 else
157 printf("%-10d", ipcp->cgid);
158
159 if ((pw = getpwuid(ipcp->uid)))
160 printf("%-10s", pw->pw_name);
161 else
162 printf("%-10d", ipcp->uid);
163 if ((gr = getgrgid(ipcp->gid)))
164 printf("%-10s\n", gr->gr_name);
165 else
166 printf("%-10d\n", ipcp->gid);
167}
168
169
170void do_shm (char format)
171{
172 int maxid, shmid, id;
173 struct shmid_ds shmseg;
174 struct shm_info shm_info;
175 struct shminfo shminfo;
176 struct ipc_perm *ipcp = &shmseg.shm_perm;
177 struct passwd *pw;
178
179 maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) &shm_info);
180 if (maxid < 0) {
181 printf ("kernel not configured for shared memory\n");
182 return;
183 }
184
185 switch (format) {
186 case LIMITS:
187 printf ("------ Shared Memory Limits --------\n");
188 if ((shmctl (0, IPC_INFO, (struct shmid_ds *) &shminfo)) < 0 )
189 return;
190 printf ("max number of segments = %d\n", shminfo.shmmni);
191 printf ("max seg size (kbytes) = %d\n", shminfo.shmmax >> 10);
192 printf ("max total shared memory (kbytes) = %d\n", shminfo.shmall << 2);
193 printf ("min seg size (bytes) = %d\n", shminfo.shmmin);
194 return;
195
196 case STATUS:
197 printf ("------ Shared Memory Status --------\n");
198 printf ("segments allocated %d\n", shm_info.used_ids);
199 printf ("pages allocated %d\n", shm_info.shm_tot);
200 printf ("pages resident %d\n", shm_info.shm_rss);
201 printf ("pages swapped %d\n", shm_info.shm_swp);
202 printf ("Swap performance: %d attempts\t %d successes\n",
203 shm_info.swap_attempts, shm_info.swap_successes);
204 return;
205
206 case CREATOR:
207 printf ("------ Shared Memory Segment Creators/Owners --------\n");
208 printf ("%-10s%-10s%-10s%-10s%-10s%-10s\n",
209 "shmid","perms","cuid","cgid","uid","gid");
210 break;
211
212 case TIME:
213 printf ("------ Shared Memory Attach/Detach/Change Times --------\n");
214 printf ("%-10s%-10s %-20s%-20s%-20s\n",
215 "shmid","owner","attached","detached","changed");
216 break;
217
218 case PID:
219 printf ("------ Shared Memory Creator/Last-op --------\n");
220 printf ("%-10s%-10s%-10s%-10s\n","shmid","owner","cpid","lpid");
221 break;
222
223 default:
224 printf ("------ Shared Memory Segments --------\n");
225 printf ("%-10s%-10s%-10s%-10s%-10s%-12s\n", "shmid","owner",
226 "perms","bytes","nattch","status");
227 break;
228 }
229
230 for (id = 0; id <= maxid; id++) {
231 shmid = shmctl (id, SHM_STAT, &shmseg);
232 if (shmid < 0)
233 continue;
234 if (format == CREATOR) {
235 print_perms (shmid, ipcp);
236 continue;
237 }
238 pw = getpwuid(ipcp->uid);
239 switch (format) {
240 case TIME:
241 if (pw)
242 printf ("%-10d%-10.10s", shmid, pw->pw_name);
243 else
244 printf ("%-10d%-10d", shmid, ipcp->uid);
245 printf(" %-20.16s%-20.16s%-20.16s\n",
246 shmseg.shm_atime ? ctime(&shmseg.shm_atime) + 4 : "Not set",
247 shmseg.shm_dtime ? ctime(&shmseg.shm_dtime) + 4 : "Not set",
248 shmseg.shm_ctime ? ctime(&shmseg.shm_ctime) + 4 : "Not set");
249 break;
250 case PID:
251 if (pw)
252 printf ("%-10d%-10.10s", shmid, pw->pw_name);
253 else
254 printf ("%-10d%-10d", shmid, ipcp->uid);
255 printf ("%-10d%-10d\n",
256 shmseg.shm_cpid, shmseg.shm_lpid);
257 break;
258
259 default:
260 if (pw)
261 printf ("%-10d%-10.10s", shmid, pw->pw_name);
262 else
263 printf ("%-10d%-10d", shmid, ipcp->uid);
264 printf ("%-10o%-10d%-10d%-6s%-6s\n",
265 ipcp->mode & 0777,
266 shmseg.shm_segsz, shmseg.shm_nattch,
267 ipcp->mode & SHM_DEST ? "dest" : " ",
268 ipcp->mode & SHM_LOCKED ? "locked" : " ");
269 break;
270 }
271 }
272 return;
273}
274
275
276void do_sem (char format)
277{
278 int maxid, semid, id;
279 struct semid_ds semary;
280 struct seminfo seminfo;
281 struct ipc_perm *ipcp = &semary.sem_perm;
282 struct passwd *pw;
283 union semun arg;
284
285 arg.array = (ushort *) &seminfo;
286 maxid = semctl (0, 0, SEM_INFO, arg);
287 if (maxid < 0) {
288 printf ("kernel not configured for semaphores\n");
289 return;
290 }
291
292 switch (format) {
293 case LIMITS:
294 printf ("------ Semaphore Limits --------\n");
295 arg.array = (ushort *) &seminfo; /* damn union */
296 if ((semctl (0, 0, IPC_INFO, arg)) < 0 )
297 return;
298 printf ("max number of arrays = %d\n", seminfo.semmni);
299 printf ("max semaphores per array = %d\n", seminfo.semmsl);
300 printf ("max semaphores system wide = %d\n", seminfo.semmns);
301 printf ("max ops per semop call = %d\n", seminfo.semopm);
302 printf ("semaphore max value = %d\n", seminfo.semvmx);
303 return;
304
305 case STATUS:
306 printf ("------ Semaphore Status --------\n");
307 printf ("used arrays = %d\n", seminfo.semusz);
308 printf ("allocated semaphores = %d\n", seminfo.semaem);
309 return;
310
311 case CREATOR:
312 printf ("------ Semaphore Arrays Creators/Owners --------\n");
313 printf ("%-10s%-10s%-10s%-10s%-10s%-10s\n",
314 "semid","perms","cuid","cgid","uid","gid");
315 break;
316
317 case TIME:
318 printf ("------ Shared Memory Operation/Change Times --------\n");
319 printf ("%-8s%-10s %-26.24s %-26.24s\n",
320 "shmid","owner","last-op","last-changed");
321 break;
322
323 case PID:
324 break;
325
326 default:
327 printf ("------ Semaphore Arrays --------\n");
328 printf ("%-10s%-10s%-10s%-10s%-12s\n",
329 "semid","owner","perms","nsems","status");
330 break;
331 }
332
333 for (id = 0; id <= maxid; id++) {
334 arg.buf = (struct semid_ds *) &semary;
335 semid = semctl (id, 0, SEM_STAT, arg);
336 if (semid < 0)
337 continue;
338 if (format == CREATOR) {
339 print_perms (semid, ipcp);
340 continue;
341 }
342 pw = getpwuid(ipcp->uid);
343 switch (format) {
344 case TIME:
345 if (pw)
346 printf ("%-8d%-10.10s", semid, pw->pw_name);
347 else
348 printf ("%-8d%-10d", semid, ipcp->uid);
349 printf (" %-26.24s %-26.24s\n",
350 semary.sem_otime ? ctime(&semary.sem_otime) : "Not set",
351 semary.sem_ctime ? ctime(&semary.sem_ctime) : "Not set");
352 break;
353 case PID:
354 break;
355
356 default:
357 if (pw)
358 printf ("%-10d%-10.9s", semid, pw->pw_name);
359 else
360 printf ("%-10d%-9d", semid, ipcp->uid);
361 printf ("%-10o%-10d\n",
362 ipcp->mode & 0777,
363 semary.sem_nsems);
364 break;
365 }
366 }
367 return;
368}
369
370
371void do_msg (char format)
372{
373 int maxid, msqid, id;
374 struct msqid_ds msgque;
375 struct msginfo msginfo;
376 struct ipc_perm *ipcp = &msgque.msg_perm;
377 struct passwd *pw;
378
379 maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) &msginfo);
380 if (maxid < 0) {
381 printf ("kernel not configured for shared memory\n");
382 return;
383 }
384
385 switch (format) {
386 case LIMITS:
387 if ((msgctl (0, IPC_INFO, (struct msqid_ds *) &msginfo)) < 0 )
388 return;
389 printf ("------ Messages: Limits --------\n");
390 printf ("max queues system wide = %d\n", msginfo.msgmni);
391 printf ("max size of message (bytes) = %d\n", msginfo.msgmax);
392 printf ("default max size of queue (bytes) = %d\n", msginfo.msgmnb);
393 return;
394
395 case STATUS:
396 printf ("------ Messages: Status --------\n");
397 printf ("allocated queues = %d\n", msginfo.msgpool);
398 printf ("used headers = %d\n", msginfo.msgmap);
399 printf ("used space = %d bytes\n", msginfo.msgtql);
400 return;
401
402 case CREATOR:
403 printf ("------ Message Queues: Creators/Owners --------\n");
404 printf ("%-10s%-10s%-10s%-10s%-10s%-10s\n",
405 "msqid","perms","cuid","cgid","uid","gid");
406 break;
407
408 case TIME:
409 printf ("------ Message Queues Send/Recv/Change Times --------\n");
410 printf ("%-8s%-10s %-20s%-20s%-20s\n",
411 "msqid","owner","send","recv","change");
412 break;
413
414 case PID:
415 break;
416
417 default:
418 printf ("------ Message Queues --------\n");
419 printf ("%-10s%-10s%-10s%-12s%-12s\n", "msqid","owner",
420 "perms", "used-bytes", "messages");
421 break;
422 }
423
424 for (id = 0; id <= maxid; id++) {
425 msqid = msgctl (id, MSG_STAT, &msgque);
426 if (msqid < 0)
427 continue;
428 if (format == CREATOR) {
429 print_perms (msqid, ipcp);
430 continue;
431 }
432 pw = getpwuid(ipcp->uid);
433 switch (format) {
434 case TIME:
435 if (pw)
436 printf ("%-8d%-10.10s", msqid, pw->pw_name);
437 else
438 printf ("%-8d%-10d", msqid, ipcp->uid);
439 printf (" %-20.16s%-20.16s%-20.16s\n",
440 msgque.msg_stime ? ctime(&msgque.msg_stime) + 4 : "Not set",
441 msgque.msg_rtime ? ctime(&msgque.msg_rtime) + 4 : "Not set",
442 msgque.msg_ctime ? ctime(&msgque.msg_ctime) + 4 : "Not set");
443 break;
444 case PID:
445 break;
446
447 default:
448 if (pw)
449 printf ("%-10d%-10.10s", msqid, pw->pw_name);
450 else
451 printf ("%-10d%-10d", msqid, ipcp->uid);
452 printf ("%-10o%-12d%-12d\n",
453 ipcp->mode & 0777, msgque.msg_cbytes,
454 msgque.msg_qnum);
455 break;
456 }
457 }
458 return;
459}
460
461
462void print_shm (int shmid)
463{
464 struct shmid_ds shmds;
465 struct ipc_perm *ipcp = &shmds.shm_perm;
466
467 if (shmctl (shmid, IPC_STAT, &shmds) == -1) {
468 perror ("shmctl ");
469 return;
470 }
471
472 printf ("\nShared memory Segment shmid=%d\n", shmid);
473 printf ("uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n",
474 ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid);
475 printf ("mode=%#o\taccess_perms=%#o\n", ipcp->mode, ipcp->mode & 0777);
476 printf ("bytes=%d\tlpid=%d\tcpid=%d\tnattch=%d\n",
477 shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
478 shmds.shm_nattch);
479 printf ("att_time=%s", shmds.shm_atime ? ctime (&shmds.shm_atime) :
480 "Not set\n");
481 printf ("det_time=%s", shmds.shm_dtime ? ctime (&shmds.shm_dtime) :
482 "Not set\n");
483 printf ("change_time=%s", ctime (&shmds.shm_ctime));
484 printf ("\n");
485 return;
486}
487
488
489
490void print_msg (int msqid)
491{
492 struct msqid_ds buf;
493 struct ipc_perm *ipcp = &buf.msg_perm;
494
495 if (msgctl (msqid, IPC_STAT, &buf) == -1) {
496 perror ("msgctl ");
497 return;
498 }
499 printf ("\nMessage Queue msqid=%d\n", msqid);
500 printf ("uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n",
501 ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode);
502 printf ("cbytes=%d\tqbytes=%d\tqnum=%d\tlspid=%d\tlrpid=%d\n",
503 buf.msg_cbytes, buf.msg_qbytes, buf.msg_qnum, buf.msg_lspid,
504 buf.msg_lrpid);
505 printf ("send_time=%srcv_time=%schange_time=%s",
506 buf.msg_rtime? ctime (&buf.msg_rtime) : "Not Set\n",
507 buf.msg_stime? ctime (&buf.msg_stime) : "Not Set\n",
508 buf.msg_ctime? ctime (&buf.msg_ctime) : "Not Set\n");
509 printf ("\n");
510 return;
511}
512
513void print_sem (int semid)
514{
515 struct semid_ds semds;
516 struct ipc_perm *ipcp = &semds.sem_perm;
517 union semun arg;
518 int i;
519
520 arg.buf = &semds;
521 if (semctl (semid, 0, IPC_STAT, arg) < 0) {
522 perror ("semctl ");
523 return;
524 }
525 printf ("\nSemaphore Array semid=%d\n", semid);
526 printf ("uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n",
527 ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid);
528 printf ("mode=%#o, access_perms=%#o\n", ipcp->mode, ipcp->mode & 0777);
529 printf ("nsems = %d\n", semds.sem_nsems);
530 printf ("otime = %s", semds.sem_otime ? ctime (&semds.sem_otime) :
531 "Not set\n");
532 printf ("ctime = %s", ctime (&semds.sem_ctime));
533
534 printf ("%-10s%-10s%-10s%-10s%-10s\n", "semnum","value","ncount",
535 "zcount","pid");
536 arg.val = 0;
537 for (i=0; i< semds.sem_nsems; i++) {
538 int val, ncnt, zcnt, pid;
539 val = semctl (semid, i, GETVAL, arg);
540 ncnt = semctl (semid, i, GETNCNT, arg);
541 zcnt = semctl (semid, i, GETZCNT, arg);
542 pid = semctl (semid, i, GETPID, arg);
543 if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) {
544 perror ("semctl ");
545 exit (1);
546 }
547 printf ("%-10d%-10d%-10d%-10d%-10d\n", i, val, ncnt, zcnt, pid);
548 }
549 printf ("\n");
550 return;
551}
552