diff options
author | Sami Kerola | 2012-11-11 22:12:20 +0100 |
---|---|---|
committer | Karel Zak | 2012-11-23 14:58:22 +0100 |
commit | b5504a3d4b318ef30600749b490c06b89f99349e (patch) | |
tree | 721695cdc4a6445cff4f7f27c350d42f71483004 | |
parent | ipcs: clean up do_sem(), and add ipc_sem_get_info() (diff) | |
download | kernel-qcow2-util-linux-b5504a3d4b318ef30600749b490c06b89f99349e.tar.gz kernel-qcow2-util-linux-b5504a3d4b318ef30600749b490c06b89f99349e.tar.xz kernel-qcow2-util-linux-b5504a3d4b318ef30600749b490c06b89f99349e.zip |
ipcs: make individual semaphore id printing to use /proc
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>
-rw-r--r-- | sys-utils/ipcs.c | 63 | ||||
-rw-r--r-- | sys-utils/ipcutils.c | 38 | ||||
-rw-r--r-- | sys-utils/ipcutils.h | 7 |
3 files changed, 72 insertions, 36 deletions
diff --git a/sys-utils/ipcs.c b/sys-utils/ipcs.c index 1180299eb..7f44aaf6f 100644 --- a/sys-utils/ipcs.c +++ b/sys-utils/ipcs.c @@ -34,10 +34,10 @@ 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); } diff --git a/sys-utils/ipcutils.c b/sys-utils/ipcutils.c index 61671c128..80148ee63 100644 --- a/sys-utils/ipcutils.c +++ b/sys-utils/ipcutils.c @@ -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; } diff --git a/sys-utils/ipcutils.h b/sys-utils/ipcutils.h index 3ab5da0ca..f50e03c61 100644 --- a/sys-utils/ipcutils.h +++ b/sys-utils/ipcutils.h @@ -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; }; |