summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys-utils/ipcs.c63
-rw-r--r--sys-utils/ipcutils.c38
-rw-r--r--sys-utils/ipcutils.h7
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;
};