]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
ipcs: clean up do_msg(), and add ipc_msg_get_info()
authorSami Kerola <kerolasa@iki.fi>
Sun, 11 Nov 2012 22:10:54 +0000 (22:10 +0000)
committerKarel Zak <kzak@redhat.com>
Fri, 23 Nov 2012 13:58:22 +0000 (14:58 +0100)
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
sys-utils/ipcs.c
sys-utils/ipcutils.c
sys-utils/ipcutils.h

index 7f44aaf6f4f2d83eabf28dc45e957201df761293..78bec7d5f98bc06924bc40d4c39e1938bdbf9cc8 100644 (file)
@@ -35,8 +35,8 @@ static void do_shm (char format);
 static void print_shm (int id);
 static void do_sem (char format);
 static void print_sem (int id);
+static void do_msg (char format);
 
-void do_msg (char format);
 void print_msg (int id);
 
 static void __attribute__ ((__noreturn__)) usage(FILE * out)
@@ -433,23 +433,16 @@ static void do_sem (char format)
        return;
 }
 
-void do_msg (char format)
+static void do_msg (char format)
 {
-       int maxid, msqid, id;
-       struct msqid_ds msgque;
-       struct msginfo msginfo;
-       struct ipc_perm *ipcp = &msgque.msg_perm;
        struct passwd *pw;
-       struct ipc_limits lim;
-
-       maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo);
-       if (maxid < 0) {
-               printf (_("kernel not configured for message queues\n"));
-               return;
-       }
+       struct msg_data *msgds, *msgdsp;
 
        switch (format) {
        case LIMITS:
+       {
+               struct ipc_limits lim;
+
                if (ipc_msg_get_limits(&lim))
                        return;
                printf (_("------ Messages Limits --------\n"));
@@ -457,14 +450,20 @@ void do_msg (char format)
                printf (_("max size of message (bytes) = %zu\n"), lim.msgmax);
                printf (_("default max size of queue (bytes) = %d\n"), lim.msgmnb);
                return;
-
+       }
        case STATUS:
+       {
+               struct msginfo msginfo;
+               if (msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo) < 0) {
+                       printf (_("kernel not configured for message queues\n"));
+                       return;
+               }
                printf (_("------ Messages Status --------\n"));
                printf (_("allocated queues = %d\n"), msginfo.msgpool);
                printf (_("used headers = %d\n"), msginfo.msgmap);
                printf (_("used space = %d bytes\n"), msginfo.msgtql);
                return;
-
+       }
        case CREATOR:
                printf (_("------ Message Queues Creators/Owners --------\n"));
                printf ("%-10s %-10s %-10s %-10s %-10s %-10s\n",
@@ -491,56 +490,56 @@ void do_msg (char format)
                break;
        }
 
-       for (id = 0; id <= maxid; id++) {
-               msqid = msgctl (id, MSG_STAT, &msgque);
-               if (msqid < 0)
-                       continue;
-               if (format == CREATOR)  {
-                       print_perms (msqid, ipcp);
+       /*
+        * Print data
+        */
+       if (ipc_msg_get_info(-1, &msgds) < 1)
+               return;
+       msgdsp = msgds;
+
+       for (msgdsp = msgds; msgdsp->next != NULL; msgdsp = msgdsp->next) {
+               if (format == CREATOR) {
+                       ipc_print_perms(stdout, &msgdsp->msg_perm);
                        continue;
                }
-               pw = getpwuid(ipcp->uid);
+               pw = getpwuid(msgdsp->msg_perm.uid);
                switch (format) {
                case TIME:
                        if (pw)
-                               printf ("%-8d %-10.10s", msqid, pw->pw_name);
+                               printf ("%-8d %-10.10s", msgdsp->msg_perm.id, pw->pw_name);
                        else
-                               printf ("%-8d %-10u", msqid, ipcp->uid);
-                       printf (" %-20.16s", msgque.msg_stime
-                               ? ctime(&msgque.msg_stime) + 4 : _("Not set"));
-                       printf (" %-20.16s", msgque.msg_rtime
-                               ? ctime(&msgque.msg_rtime) + 4 : _("Not set"));
-                       printf (" %-20.16s\n", msgque.msg_ctime
-                               ? ctime(&msgque.msg_ctime) + 4 : _("Not set"));
+                               printf ("%-8d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid);
+                       printf (" %-20.16s", msgdsp->q_stime
+                               ? ctime(&msgdsp->q_stime) + 4 : _("Not set"));
+                       printf (" %-20.16s", msgdsp->q_rtime
+                               ? ctime(&msgdsp->q_rtime) + 4 : _("Not set"));
+                       printf (" %-20.16s\n", msgdsp->q_ctime
+                               ? ctime(&msgdsp->q_ctime) + 4 : _("Not set"));
                        break;
                case PID:
                        if (pw)
-                               printf ("%-8d %-10.10s", msqid, pw->pw_name);
+                               printf ("%-8d %-10.10s", msgdsp->msg_perm.id, pw->pw_name);
                        else
-                               printf ("%-8d %-10u", msqid, ipcp->uid);
+                               printf ("%-8d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid);
                        printf ("  %5d     %5d\n",
-                               msgque.msg_lspid, msgque.msg_lrpid);
+                               msgdsp->q_lspid, msgdsp->q_lrpid);
                        break;
 
                default:
-                       printf( "0x%08x ",ipcp->KEY );
+                       printf( "0x%08x ",msgdsp->msg_perm.key );
                        if (pw)
-                               printf ("%-10d %-10.10s", msqid, pw->pw_name);
+                               printf ("%-10d %-10.10s", msgdsp->msg_perm.id, pw->pw_name);
                        else
-                               printf ("%-10d %-10u", msqid, ipcp->uid);
+                               printf ("%-10d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid);
                        printf (" %-10o %-12ld %-12ld\n",
-                               ipcp->mode & 0777,
-                               /*
-                                * glibc-2.1.3 and earlier has unsigned
-                                * short. glibc-2.1.91 has variation between
-                                * unsigned short, unsigned long. Austin has
-                                * msgqnum_t
-                                */
-                               (long) msgque.msg_cbytes,
-                               (long) msgque.msg_qnum);
+                               msgdsp->msg_perm.mode & 0777,
+                               msgdsp->q_cbytes,
+                               msgdsp->q_qnum);
                        break;
                }
        }
+
+       ipc_msg_free_info(msgds);
        return;
 }
 
index 80148ee63bae45f062fc5b2a5a09c771b4d92c7a..772863c544e72806123e63d9f29db9f7fe692943 100644 (file)
@@ -356,6 +356,120 @@ void ipc_sem_free_info(struct sem_data *semds)
        }
 }
 
+int ipc_msg_get_info(int id, struct msg_data **msgds)
+{
+       FILE *f;
+       int i, maxid;
+       struct msg_data *p;
+       struct msqid_ds dummy;
+
+       p = *msgds = xcalloc(1, sizeof(struct msg_data));
+       p->next = NULL;
+
+       f = path_fopen("r", 0, _PATH_PROC_SYSV_MSG);
+       if (!f)
+               goto msg_fallback;
+
+       while (fgetc(f) != '\n') ;      /* skip header */
+
+       while (feof(f) == 0) {
+               if (fscanf(f,
+                          "%d %d  %o  %" SCNu64 " %" SCNu64 " %u %u %u %u %u %u %" SCNu64 " %" SCNu64 " %" SCNu64 "\n",
+                          &p->msg_perm.key,
+                          &p->msg_perm.id,
+                          &p->msg_perm.mode,
+                          &p->q_cbytes,
+                          &p->q_qnum,
+                          &p->q_lspid,
+                          &p->q_lrpid,
+                          &p->msg_perm.uid,
+                          &p->msg_perm.gid,
+                          &p->msg_perm.cuid,
+                          &p->msg_perm.cgid,
+                          &p->q_stime,
+                          &p->q_rtime,
+                          &p->q_ctime) != 14)
+                       continue;
+
+               if (id > -1) {
+                       /* ID specified */
+                       if (id == p->msg_perm.id) {
+                               i = 1;
+                               break;
+                       } else
+                               continue;
+               }
+
+               p->next = xcalloc(1, sizeof(struct msg_data));
+               p = p->next;
+               p->next = NULL;
+               i++;
+       }
+
+       if (i == 0)
+               free(*msgds);
+       fclose(f);
+       return i;
+
+       /* Fallback; /proc or /sys file(s) missing. */
+ msg_fallback:
+       i = id < 0 ? 0 : id;
+
+       maxid = msgctl(id, MSG_STAT, &dummy);
+       if (maxid < 0)
+               return 0;
+
+       while (i <= maxid) {
+               int msgid;
+               struct msqid_ds msgseg;
+               struct ipc_perm *ipcp = &msgseg.msg_perm;
+
+               msgid = msgctl(id, MSG_STAT, &msgseg);
+               if (msgid < 0) {
+                       if (-1 < id) {
+                               free(*msgds);
+                               return 0;
+                       }
+                       i++;
+                       continue;
+               }
+
+               p->msg_perm.key = ipcp->KEY;
+               p->msg_perm.id = msgid;
+               p->msg_perm.mode = ipcp->mode;
+               p->q_cbytes = msgseg.msg_cbytes;
+               p->q_qnum = msgseg.msg_qnum;
+               p->q_lspid = msgseg.msg_lspid;
+               p->q_lrpid = msgseg.msg_lrpid;
+               p->msg_perm.uid = ipcp->uid;
+               p->msg_perm.gid = ipcp->gid;
+               p->msg_perm.cuid = ipcp->cuid;
+               p->msg_perm.cgid = ipcp->cgid;
+               p->q_stime = msgseg.msg_stime;
+               p->q_rtime = msgseg.msg_rtime;
+               p->q_ctime = msgseg.msg_ctime;
+
+               if (id < 0) {
+                       p->next = xcalloc(1, sizeof(struct msg_data));
+                       p = p->next;
+                       p->next = NULL;
+                       i++;
+               } else
+                       return 1;
+       }
+
+       return i;
+}
+
+void ipc_msg_free_info(struct msg_data *msgds)
+{
+       while (msgds) {
+               struct msg_data *next = msgds->next;
+               free(msgds);
+               msgds = next;
+       }
+}
+
 void ipc_print_perms(FILE *f, struct ipc_stat *is)
 {
        struct passwd *pw;
index f50e03c61a00f9d3194b77b119a19b09329d99bc..28b35c1361201fa42dc1295fa996a663fa72f371 100644 (file)
@@ -154,4 +154,24 @@ struct sem_data {
 extern int ipc_sem_get_info(int id, struct sem_data **semds);
 extern void ipc_sem_free_info(struct sem_data *semds);
 
+/* See 'struct msg_queue' in kernel sources
+ */
+struct msg_data {
+       struct ipc_stat msg_perm;
+
+       time_t          q_stime;
+       time_t          q_rtime;
+       time_t          q_ctime;
+       uint64_t        q_cbytes;
+       uint64_t        q_qnum;
+       uint64_t        q_qbytes;
+       pid_t           q_lspid;
+       pid_t           q_lrpid;
+
+       struct msg_data *next;
+};
+
+extern int ipc_msg_get_info(int id, struct msg_data **msgds);
+extern void ipc_msg_free_info(struct msg_data *msgds);
+
 #endif /* UTIL_LINUX_IPCUTILS_H */