diff options
Diffstat (limited to 'sys-utils/ipcutils.c')
-rw-r--r-- | sys-utils/ipcutils.c | 38 |
1 files changed, 37 insertions, 1 deletions
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; } |