From 1e2418a234e2361fe1916a835ea59aa19c0e4810 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sun, 11 Nov 2012 20:53:07 +0000 Subject: ipcs: clean up do_sem(), and add ipc_sem_get_info() Signed-off-by: Sami Kerola --- sys-utils/ipcutils.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) (limited to 'sys-utils/ipcutils.c') diff --git a/sys-utils/ipcutils.c b/sys-utils/ipcutils.c index 3b52a7e6b..61671c128 100644 --- a/sys-utils/ipcutils.c +++ b/sys-utils/ipcutils.c @@ -211,6 +211,115 @@ void ipc_shm_free_info(struct shm_data *shmds) } } +int ipc_sem_get_info(int id, struct sem_data **semds) +{ + FILE *f; + int i, maxid; + struct sem_data *p; + struct seminfo dummy; + union semun arg; + + p = *semds = xcalloc(1, sizeof(struct sem_data)); + p->next = NULL; + + f = path_fopen("r", 0, _PATH_PROC_SYSV_SEM); + if (!f) + goto sem_fallback; + + while (fgetc(f) != '\n') ; /* skip header */ + + while (feof(f) == 0) { + if (fscanf(f, + "%d %d %o %" SCNu64 " %u %u %u %u %" SCNu64 " %" SCNu64 "\n", + &p->sem_perm.key, + &p->sem_perm.id, + &p->sem_perm.mode, + &p->sem_nsems, + &p->sem_perm.uid, + &p->sem_perm.gid, + &p->sem_perm.cuid, + &p->sem_perm.cgid, + &p->sem_otime, + &p->sem_ctime) != 10) + continue; + + if (id > -1) { + /* ID specified */ + if (id == p->sem_perm.id) { + i = 1; + break; + } else + continue; + } + + p->next = xcalloc(1, sizeof(struct sem_data)); + p = p->next; + p->next = NULL; + i++; + } + + if (i == 0) + free(*semds); + fclose(f); + return i; + + /* Fallback; /proc or /sys file(s) missing. */ + sem_fallback: + i = id < 0 ? 0 : id; + + arg.array = (ushort *) (void *)&dummy; + maxid = semctl(0, 0, SEM_INFO, arg); + if (maxid < 0) + return 0; + + while (i <= maxid) { + int semid; + struct semid_ds semseg; + struct ipc_perm *ipcp = &semseg.sem_perm; + arg.buf = (struct semid_ds *)&semseg; + + semid = semctl(i, 0, SEM_STAT, arg); + if (semid < 0) { + if (-1 < id) { + free(*semds); + return 0; + } + i++; + continue; + } + + p->sem_perm.key = ipcp->KEY; + p->sem_perm.id = semid; + p->sem_perm.mode = ipcp->mode; + p->sem_nsems = semseg.sem_nsems; + p->sem_perm.uid = ipcp->uid; + p->sem_perm.gid = ipcp->gid; + p->sem_perm.cuid = ipcp->cuid; + p->sem_perm.cgid = ipcp->cuid; + p->sem_otime = semseg.sem_otime; + p->sem_ctime = semseg.sem_ctime; + + if (id < 0) { + p->next = xcalloc(1, sizeof(struct sem_data)); + p = p->next; + p->next = NULL; + i++; + } else + return 1; + } + + return i; +} + +void ipc_sem_free_info(struct sem_data *semds) +{ + while (semds) { + struct sem_data *next = semds->next; + free(semds); + semds = next; + } +} + void ipc_print_perms(FILE *f, struct ipc_stat *is) { struct passwd *pw; -- cgit v1.2.3-55-g7522