summaryrefslogtreecommitdiffstats
path: root/sys-utils/ipcutils.c
diff options
context:
space:
mode:
authorSami Kerola2012-11-11 21:53:07 +0100
committerKarel Zak2012-11-23 14:58:22 +0100
commit1e2418a234e2361fe1916a835ea59aa19c0e4810 (patch)
tree6a01bcce8200edc95cb2b246cd9967e03f55a522 /sys-utils/ipcutils.c
parentipcs: make individual shared memory id printing to use /proc (diff)
downloadkernel-qcow2-util-linux-1e2418a234e2361fe1916a835ea59aa19c0e4810.tar.gz
kernel-qcow2-util-linux-1e2418a234e2361fe1916a835ea59aa19c0e4810.tar.xz
kernel-qcow2-util-linux-1e2418a234e2361fe1916a835ea59aa19c0e4810.zip
ipcs: clean up do_sem(), and add ipc_sem_get_info()
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'sys-utils/ipcutils.c')
-rw-r--r--sys-utils/ipcutils.c109
1 files changed, 109 insertions, 0 deletions
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;