diff options
author | Sami Kerola | 2012-11-11 23:10:54 +0100 |
---|---|---|
committer | Karel Zak | 2012-11-23 14:58:22 +0100 |
commit | 35118dfc31ac15e14380c3773334b5b7c10b423f (patch) | |
tree | 1eb997209f43992d089cbdff892d42511f97516f | |
parent | ipcs: make individual semaphore id printing to use /proc (diff) | |
download | kernel-qcow2-util-linux-35118dfc31ac15e14380c3773334b5b7c10b423f.tar.gz kernel-qcow2-util-linux-35118dfc31ac15e14380c3773334b5b7c10b423f.tar.xz kernel-qcow2-util-linux-35118dfc31ac15e14380c3773334b5b7c10b423f.zip |
ipcs: clean up do_msg(), and add ipc_msg_get_info()
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
-rw-r--r-- | sys-utils/ipcs.c | 89 | ||||
-rw-r--r-- | sys-utils/ipcutils.c | 114 | ||||
-rw-r--r-- | sys-utils/ipcutils.h | 20 |
3 files changed, 178 insertions, 45 deletions
diff --git a/sys-utils/ipcs.c b/sys-utils/ipcs.c index 7f44aaf6f..78bec7d5f 100644 --- a/sys-utils/ipcs.c +++ b/sys-utils/ipcs.c @@ -35,8 +35,8 @@ static void do_shm (char format); static void print_shm (int id); static void do_sem (char format); static void print_sem (int id); +static void do_msg (char format); -void do_msg (char format); void print_msg (int id); static void __attribute__ ((__noreturn__)) usage(FILE * out) @@ -433,23 +433,16 @@ static void do_sem (char format) return; } -void do_msg (char format) +static void do_msg (char format) { - int maxid, msqid, id; - struct msqid_ds msgque; - struct msginfo msginfo; - struct ipc_perm *ipcp = &msgque.msg_perm; struct passwd *pw; - struct ipc_limits lim; - - maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo); - if (maxid < 0) { - printf (_("kernel not configured for message queues\n")); - return; - } + struct msg_data *msgds, *msgdsp; switch (format) { case LIMITS: + { + struct ipc_limits lim; + if (ipc_msg_get_limits(&lim)) return; printf (_("------ Messages Limits --------\n")); @@ -457,14 +450,20 @@ void do_msg (char format) printf (_("max size of message (bytes) = %zu\n"), lim.msgmax); printf (_("default max size of queue (bytes) = %d\n"), lim.msgmnb); return; - + } case STATUS: + { + struct msginfo msginfo; + if (msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo) < 0) { + printf (_("kernel not configured for message queues\n")); + return; + } printf (_("------ Messages Status --------\n")); printf (_("allocated queues = %d\n"), msginfo.msgpool); printf (_("used headers = %d\n"), msginfo.msgmap); printf (_("used space = %d bytes\n"), msginfo.msgtql); return; - + } case CREATOR: printf (_("------ Message Queues Creators/Owners --------\n")); printf ("%-10s %-10s %-10s %-10s %-10s %-10s\n", @@ -491,56 +490,56 @@ void do_msg (char format) break; } - for (id = 0; id <= maxid; id++) { - msqid = msgctl (id, MSG_STAT, &msgque); - if (msqid < 0) - continue; - if (format == CREATOR) { - print_perms (msqid, ipcp); + /* + * Print data + */ + if (ipc_msg_get_info(-1, &msgds) < 1) + return; + msgdsp = msgds; + + for (msgdsp = msgds; msgdsp->next != NULL; msgdsp = msgdsp->next) { + if (format == CREATOR) { + ipc_print_perms(stdout, &msgdsp->msg_perm); continue; } - pw = getpwuid(ipcp->uid); + pw = getpwuid(msgdsp->msg_perm.uid); switch (format) { case TIME: if (pw) - printf ("%-8d %-10.10s", msqid, pw->pw_name); + printf ("%-8d %-10.10s", msgdsp->msg_perm.id, pw->pw_name); else - printf ("%-8d %-10u", msqid, ipcp->uid); - printf (" %-20.16s", msgque.msg_stime - ? ctime(&msgque.msg_stime) + 4 : _("Not set")); - printf (" %-20.16s", msgque.msg_rtime - ? ctime(&msgque.msg_rtime) + 4 : _("Not set")); - printf (" %-20.16s\n", msgque.msg_ctime - ? ctime(&msgque.msg_ctime) + 4 : _("Not set")); + printf ("%-8d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid); + printf (" %-20.16s", msgdsp->q_stime + ? ctime(&msgdsp->q_stime) + 4 : _("Not set")); + printf (" %-20.16s", msgdsp->q_rtime + ? ctime(&msgdsp->q_rtime) + 4 : _("Not set")); + printf (" %-20.16s\n", msgdsp->q_ctime + ? ctime(&msgdsp->q_ctime) + 4 : _("Not set")); break; case PID: if (pw) - printf ("%-8d %-10.10s", msqid, pw->pw_name); + printf ("%-8d %-10.10s", msgdsp->msg_perm.id, pw->pw_name); else - printf ("%-8d %-10u", msqid, ipcp->uid); + printf ("%-8d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid); printf (" %5d %5d\n", - msgque.msg_lspid, msgque.msg_lrpid); + msgdsp->q_lspid, msgdsp->q_lrpid); break; default: - printf( "0x%08x ",ipcp->KEY ); + printf( "0x%08x ",msgdsp->msg_perm.key ); if (pw) - printf ("%-10d %-10.10s", msqid, pw->pw_name); + printf ("%-10d %-10.10s", msgdsp->msg_perm.id, pw->pw_name); else - printf ("%-10d %-10u", msqid, ipcp->uid); + printf ("%-10d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid); printf (" %-10o %-12ld %-12ld\n", - ipcp->mode & 0777, - /* - * glibc-2.1.3 and earlier has unsigned - * short. glibc-2.1.91 has variation between - * unsigned short, unsigned long. Austin has - * msgqnum_t - */ - (long) msgque.msg_cbytes, - (long) msgque.msg_qnum); + msgdsp->msg_perm.mode & 0777, + msgdsp->q_cbytes, + msgdsp->q_qnum); break; } } + + ipc_msg_free_info(msgds); return; } diff --git a/sys-utils/ipcutils.c b/sys-utils/ipcutils.c index 80148ee63..772863c54 100644 --- a/sys-utils/ipcutils.c +++ b/sys-utils/ipcutils.c @@ -356,6 +356,120 @@ void ipc_sem_free_info(struct sem_data *semds) } } +int ipc_msg_get_info(int id, struct msg_data **msgds) +{ + FILE *f; + int i, maxid; + struct msg_data *p; + struct msqid_ds dummy; + + p = *msgds = xcalloc(1, sizeof(struct msg_data)); + p->next = NULL; + + f = path_fopen("r", 0, _PATH_PROC_SYSV_MSG); + if (!f) + goto msg_fallback; + + while (fgetc(f) != '\n') ; /* skip header */ + + while (feof(f) == 0) { + if (fscanf(f, + "%d %d %o %" SCNu64 " %" SCNu64 " %u %u %u %u %u %u %" SCNu64 " %" SCNu64 " %" SCNu64 "\n", + &p->msg_perm.key, + &p->msg_perm.id, + &p->msg_perm.mode, + &p->q_cbytes, + &p->q_qnum, + &p->q_lspid, + &p->q_lrpid, + &p->msg_perm.uid, + &p->msg_perm.gid, + &p->msg_perm.cuid, + &p->msg_perm.cgid, + &p->q_stime, + &p->q_rtime, + &p->q_ctime) != 14) + continue; + + if (id > -1) { + /* ID specified */ + if (id == p->msg_perm.id) { + i = 1; + break; + } else + continue; + } + + p->next = xcalloc(1, sizeof(struct msg_data)); + p = p->next; + p->next = NULL; + i++; + } + + if (i == 0) + free(*msgds); + fclose(f); + return i; + + /* Fallback; /proc or /sys file(s) missing. */ + msg_fallback: + i = id < 0 ? 0 : id; + + maxid = msgctl(id, MSG_STAT, &dummy); + if (maxid < 0) + return 0; + + while (i <= maxid) { + int msgid; + struct msqid_ds msgseg; + struct ipc_perm *ipcp = &msgseg.msg_perm; + + msgid = msgctl(id, MSG_STAT, &msgseg); + if (msgid < 0) { + if (-1 < id) { + free(*msgds); + return 0; + } + i++; + continue; + } + + p->msg_perm.key = ipcp->KEY; + p->msg_perm.id = msgid; + p->msg_perm.mode = ipcp->mode; + p->q_cbytes = msgseg.msg_cbytes; + p->q_qnum = msgseg.msg_qnum; + p->q_lspid = msgseg.msg_lspid; + p->q_lrpid = msgseg.msg_lrpid; + p->msg_perm.uid = ipcp->uid; + p->msg_perm.gid = ipcp->gid; + p->msg_perm.cuid = ipcp->cuid; + p->msg_perm.cgid = ipcp->cgid; + p->q_stime = msgseg.msg_stime; + p->q_rtime = msgseg.msg_rtime; + p->q_ctime = msgseg.msg_ctime; + + if (id < 0) { + p->next = xcalloc(1, sizeof(struct msg_data)); + p = p->next; + p->next = NULL; + i++; + } else + return 1; + } + + return i; +} + +void ipc_msg_free_info(struct msg_data *msgds) +{ + while (msgds) { + struct msg_data *next = msgds->next; + free(msgds); + msgds = 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 f50e03c61..28b35c136 100644 --- a/sys-utils/ipcutils.h +++ b/sys-utils/ipcutils.h @@ -154,4 +154,24 @@ struct sem_data { extern int ipc_sem_get_info(int id, struct sem_data **semds); extern void ipc_sem_free_info(struct sem_data *semds); +/* See 'struct msg_queue' in kernel sources + */ +struct msg_data { + struct ipc_stat msg_perm; + + time_t q_stime; + time_t q_rtime; + time_t q_ctime; + uint64_t q_cbytes; + uint64_t q_qnum; + uint64_t q_qbytes; + pid_t q_lspid; + pid_t q_lrpid; + + struct msg_data *next; +}; + +extern int ipc_msg_get_info(int id, struct msg_data **msgds); +extern void ipc_msg_free_info(struct msg_data *msgds); + #endif /* UTIL_LINUX_IPCUTILS_H */ |