home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.2 / util-lin / util-linux-2.2 / sys-utils / ipcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  13.2 KB  |  552 lines

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