]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
ipcs: make individual semaphore id printing to use /proc
authorSami Kerola <kerolasa@iki.fi>
Sun, 11 Nov 2012 21:12:20 +0000 (21:12 +0000)
committerKarel Zak <kzak@redhat.com>
Fri, 23 Nov 2012 13:58:22 +0000 (14:58 +0100)
And reindent the print_shm() function.

[kzak@redhat.com: move semctl(GET*...) calls to ipcutils.c]

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/ipcs.c
sys-utils/ipcutils.c
sys-utils/ipcutils.h

index 1180299ebb8533cfb2eb2419379741dc5ae2b723..7f44aaf6f4f2d83eabf28dc45e957201df761293 100644 (file)
 static void do_shm (char format);
 static void print_shm (int id);
 static void do_sem (char format);
+static void print_sem (int id);
 
 void do_msg (char format);
 void print_msg (int id);
-void print_sem (int id);
 
 static void __attribute__ ((__noreturn__)) usage(FILE * out)
 {
@@ -602,42 +602,35 @@ void print_msg (int msqid)
        return;
 }
 
-void print_sem (int semid)
+static void print_sem(int semid)
 {
-       struct semid_ds semds;
-       struct ipc_perm *ipcp = &semds.sem_perm;
-       union semun arg;
+       struct sem_data *semdata;
        size_t i;
 
-       arg.buf = &semds;
-       if (semctl (semid, 0, IPC_STAT, arg) < 0)
-               err(EXIT_FAILURE, _("semctl failed"));
-
-       printf (_("\nSemaphore Array semid=%d\n"), semid);
-       printf (_("uid=%u\t gid=%u\t cuid=%u\t cgid=%u\n"),
-               ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid);
-       printf (_("mode=%#o, access_perms=%#o\n"),
-               ipcp->mode, ipcp->mode & 0777);
-       printf (_("nsems = %ld\n"), (long) semds.sem_nsems);
-       printf (_("otime = %-26.24s\n"),
-               semds.sem_otime ? ctime (&semds.sem_otime) : _("Not set"));
-       printf (_("ctime = %-26.24s\n"), ctime (&semds.sem_ctime));
-
-       printf ("%-10s %-10s %-10s %-10s %-10s\n",
-               _("semnum"),_("value"),_("ncount"),_("zcount"),_("pid"));
-       arg.val = 0;
-       for (i=0; i< semds.sem_nsems; i++) {
-               int val, ncnt, zcnt, pid;
-               val = semctl (semid, i, GETVAL, arg);
-               ncnt = semctl (semid, i, GETNCNT, arg);
-               zcnt = semctl (semid, i, GETZCNT, arg);
-               pid = semctl (semid, i, GETPID, arg);
-               if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0)
-                       err(EXIT_FAILURE, _("semctl failed"));
-
-               printf ("%-10zd %-10d %-10d %-10d %-10d\n",
-                       i, val, ncnt, zcnt, pid);
+       if (ipc_sem_get_info(semid, &semdata) < 1) {
+               warnx(_("id %d not found"), semid);
+               return;
        }
-       printf ("\n");
-       return;
+
+       printf(_("\nSemaphore Array semid=%d\n"), semid);
+       printf(_("uid=%u\t gid=%u\t cuid=%u\t cgid=%u\n"),
+              semdata->sem_perm.uid, semdata->sem_perm.uid,
+              semdata->sem_perm.cuid, semdata->sem_perm.cgid);
+       printf(_("mode=%#o, access_perms=%#o\n"),
+              semdata->sem_perm.mode, semdata->sem_perm.mode & 0777);
+       printf(_("nsems = %ld\n"), semdata->sem_nsems);
+       printf(_("otime = %-26.24s\n"),
+              semdata->sem_otime ? ctime(&semdata->sem_otime) : _("Not set"));
+       printf(_("ctime = %-26.24s\n"), ctime(&semdata->sem_ctime));
+
+       printf("%-10s %-10s %-10s %-10s %-10s\n",
+              _("semnum"), _("value"), _("ncount"), _("zcount"), _("pid"));
+
+       for (i = 0; i < semdata->sem_nsems; i++) {
+               struct sem_elem *e = &semdata->elements[i];
+               printf("%-10zd %-10d %-10d %-10d %-10d\n",
+                      i, e->semval, e->ncount, e->zcount, e->pid);
+       }
+       printf("\n");
+       ipc_sem_free_info(semdata);
 }
index 61671c1285a952c6f9913239fd3d2e4a920a4aad..80148ee63bae45f062fc5b2a5a09c771b4d92c7a 100644 (file)
@@ -2,6 +2,7 @@
 #include <inttypes.h>
 
 #include "c.h"
+#include "nls.h"
 #include "xalloc.h"
 #include "path.h"
 #include "pathnames.h"
@@ -211,6 +212,37 @@ void ipc_shm_free_info(struct shm_data *shmds)
        }
 }
 
+static void get_sem_elements(struct sem_data *p)
+{
+       size_t i;
+
+       if (!p || !p->sem_nsems || p->sem_perm.id < 0)
+               return;
+
+       p->elements = xcalloc(p->sem_nsems, sizeof(struct sem_elem));
+
+       for (i = 0; i < p->sem_nsems; i++) {
+               struct sem_elem *e = &p->elements[i];
+               union semun arg = { .val = 0 };
+
+               e->semval = semctl(p->sem_perm.id, i, GETVAL, arg);
+               if (e->semval < 0)
+                       err(EXIT_FAILURE, _("%s failed"), "semctl(GETVAL)");
+
+               e->ncount = semctl(p->sem_perm.id, i, GETNCNT, arg);
+               if (e->ncount < 0)
+                       err(EXIT_FAILURE, _("%s failed"), "semctl(GETNCNT)");
+
+               e->zcount = semctl(p->sem_perm.id, i, GETZCNT, arg);
+               if (e->zcount < 0)
+                       err(EXIT_FAILURE, _("%s failed"), "semctl(GETZCNT)");
+
+               e->pid = semctl(p->sem_perm.id, i, GETPID, arg);
+               if (e->pid < 0)
+                       err(EXIT_FAILURE, _("%s failed"), "semctl(GETPID)");
+       }
+}
+
 int ipc_sem_get_info(int id, struct sem_data **semds)
 {
        FILE *f;
@@ -246,6 +278,7 @@ int ipc_sem_get_info(int id, struct sem_data **semds)
                if (id > -1) {
                        /* ID specified */
                        if (id == p->sem_perm.id) {
+                               get_sem_elements(p);
                                i = 1;
                                break;
                        } else
@@ -304,8 +337,10 @@ int ipc_sem_get_info(int id, struct sem_data **semds)
                        p = p->next;
                        p->next = NULL;
                        i++;
-               } else
+               } else {
+                       get_sem_elements(p);
                        return 1;
+               }
        }
 
        return i;
@@ -315,6 +350,7 @@ void ipc_sem_free_info(struct sem_data *semds)
 {
        while (semds) {
                struct sem_data *next = semds->next;
+               free(semds->elements);
                free(semds);
                semds = next;
        }
index 3ab5da0cac3168fc6c3bb07f3b3248abb5ec38ef..f50e03c61a00f9d3194b77b119a19b09329d99bc 100644 (file)
@@ -134,6 +134,12 @@ extern void ipc_shm_free_info(struct shm_data *shmds);
 
 /* See 'struct sem_array' in kernel sources
  */
+struct sem_elem {
+       int     semval;
+       int     ncount;         /* processes waiting on increase semval */
+       int     zcount;         /* processes waiting on semval set to zero */
+       pid_t   pid;            /* process last executed semop(2) call */
+};
 struct sem_data {
        struct ipc_stat sem_perm;
 
@@ -141,6 +147,7 @@ struct sem_data {
        time_t          sem_otime;
        uint64_t        sem_nsems;
 
+       struct sem_elem *elements;
        struct sem_data *next;
 };