summaryrefslogtreecommitdiffstats
path: root/sys-utils
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
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')
-rw-r--r--sys-utils/ipcs.c80
-rw-r--r--sys-utils/ipcutils.c109
-rw-r--r--sys-utils/ipcutils.h15
3 files changed, 164 insertions, 40 deletions
diff --git a/sys-utils/ipcs.c b/sys-utils/ipcs.c
index 4945d8dcc..1180299eb 100644
--- a/sys-utils/ipcs.c
+++ b/sys-utils/ipcs.c
@@ -33,8 +33,8 @@
static void do_shm (char format);
static void print_shm (int id);
+static void do_sem (char format);
-void do_sem (char format);
void do_msg (char format);
void print_msg (int id);
void print_sem (int id);
@@ -332,25 +332,16 @@ static void do_shm (char format)
return;
}
-void do_sem (char format)
+static void do_sem (char format)
{
- int maxid, semid, id;
- struct semid_ds semary;
- struct seminfo seminfo;
- struct ipc_perm *ipcp = &semary.sem_perm;
struct passwd *pw;
- union semun arg;
- struct ipc_limits lim;
-
- arg.array = (ushort *) (void *) &seminfo;
- maxid = semctl (0, 0, SEM_INFO, arg);
- if (maxid < 0) {
- printf (_("kernel not configured for semaphores\n"));
- return;
- }
+ struct sem_data *semds, *semdsp;
switch (format) {
case LIMITS:
+ {
+ struct ipc_limits lim;
+
printf (_("------ Semaphore Limits --------\n"));
if (ipc_sem_get_limits(&lim))
return;
@@ -360,12 +351,21 @@ void do_sem (char format)
printf (_("max ops per semop call = %d\n"), lim.semopm);
printf (_("semaphore max value = %d\n"), lim.semvmx);
return;
-
+ }
case STATUS:
+ {
+ struct seminfo seminfo;
+ union semun arg;
+ arg.array = (ushort *) (void *) &seminfo;
+ if (semctl (0, 0, SEM_INFO, arg) < 0) {
+ printf (_("kernel not configured for semaphores\n"));
+ return;
+ }
printf (_("------ Semaphore Status --------\n"));
printf (_("used arrays = %d\n"), seminfo.semusz);
printf (_("allocated semaphores = %d\n"), seminfo.semaem);
return;
+ }
case CREATOR:
printf (_("------ Semaphore Arrays Creators/Owners --------\n"));
@@ -389,48 +389,48 @@ void do_sem (char format)
break;
}
- for (id = 0; id <= maxid; id++) {
- arg.buf = (struct semid_ds *) &semary;
- semid = semctl (id, 0, SEM_STAT, arg);
- if (semid < 0)
- continue;
+ /*
+ * Print data
+ */
+ if (ipc_sem_get_info(-1, &semds) < 1)
+ return;
+ semdsp = semds;
+
+ for (semdsp = semds; semdsp->next != NULL; semdsp = semdsp->next) {
if (format == CREATOR) {
- print_perms (semid, ipcp);
+ ipc_print_perms(stdout, &semdsp->sem_perm);
continue;
}
- pw = getpwuid(ipcp->uid);
+ pw = getpwuid(semdsp->sem_perm.uid);
switch (format) {
case TIME:
if (pw)
- printf ("%-8d %-10.10s", semid, pw->pw_name);
+ printf ("%-8d %-10.10s", semdsp->sem_perm.id, pw->pw_name);
else
- printf ("%-8d %-10u", semid, ipcp->uid);
- printf (" %-26.24s", semary.sem_otime
- ? ctime(&semary.sem_otime) : _("Not set"));
- printf (" %-26.24s\n", semary.sem_ctime
- ? ctime(&semary.sem_ctime) : _("Not set"));
+ printf ("%-8d %-10u", semdsp->sem_perm.id, semdsp->sem_perm.uid);
+ printf (" %-26.24s", semdsp->sem_otime
+ ? ctime(&semdsp->sem_otime) : _("Not set"));
+ printf (" %-26.24s\n", semdsp->sem_ctime
+ ? ctime(&semdsp->sem_ctime) : _("Not set"));
break;
case PID:
break;
default:
- printf("0x%08x ", ipcp->KEY);
+ printf("0x%08x ", semdsp->sem_perm.key);
if (pw)
- printf ("%-10d %-10.10s", semid, pw->pw_name);
+ printf ("%-10d %-10.10s", semdsp->sem_perm.id, pw->pw_name);
else
- printf ("%-10d %-10u", semid, ipcp->uid);
+ printf ("%-10d %-10u", semdsp->sem_perm.id, semdsp->sem_perm.uid);
printf (" %-10o %-10ld\n",
- ipcp->mode & 0777,
- /*
- * glibc-2.1.3 and earlier has unsigned
- * short. glibc-2.1.91 has variation between
- * unsigned short and unsigned long. Austin
- * prescribes unsigned short.
- */
- (long) semary.sem_nsems);
+ semdsp->sem_perm.mode & 0777,
+ semdsp->sem_nsems);
break;
}
}
+
+ ipc_sem_free_info(semds);
+ return;
}
void do_msg (char format)
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;
diff --git a/sys-utils/ipcutils.h b/sys-utils/ipcutils.h
index 45a75d84f..3ab5da0ca 100644
--- a/sys-utils/ipcutils.h
+++ b/sys-utils/ipcutils.h
@@ -132,4 +132,19 @@ struct shm_data {
extern int ipc_shm_get_info(int id, struct shm_data **shmds);
extern void ipc_shm_free_info(struct shm_data *shmds);
+/* See 'struct sem_array' in kernel sources
+ */
+struct sem_data {
+ struct ipc_stat sem_perm;
+
+ time_t sem_ctime;
+ time_t sem_otime;
+ uint64_t sem_nsems;
+
+ struct sem_data *next;
+};
+
+extern int ipc_sem_get_info(int id, struct sem_data **semds);
+extern void ipc_sem_free_info(struct sem_data *semds);
+
#endif /* UTIL_LINUX_IPCUTILS_H */