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