[PATCH 06/13] ipcs: read message queue values from /proc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add msgctl_info_wrapper(), which does the job and take it in use.

Signed-off-by: Sami Kerola <kerolasa@xxxxxx>
---
 sys-utils/ipcs.c | 160 +++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 126 insertions(+), 34 deletions(-)

diff --git a/sys-utils/ipcs.c b/sys-utils/ipcs.c
index b2d4649..db1919b 100644
--- a/sys-utils/ipcs.c
+++ b/sys-utils/ipcs.c
@@ -363,6 +363,96 @@ static int shmctl_info_wrapper(int maxid, int id, struct shm_data **shmds,
 	return i;
 }
 
+static int msgctl_info_wrapper(int maxid, int id, struct msg_data **msgds,
+			       int use_proc)
+{
+	char skipheader[1024];
+	int i, msgid;
+	struct msg_data *msgdsp;
+
+	struct msqid_ds msgque;
+	struct ipc_perm *ipcp = &msgque.msg_perm;
+
+	*msgds = xmalloc(sizeof(struct msg_data));
+	msgdsp = *msgds;
+	msgdsp->next = NULL;
+	if (use_proc) {
+		FILE *f;
+		if ((f = fopen(_PATH_PROC_IPCMSG, "r")) == NULL)
+			return -1;
+		fgets(skipheader, 1024, f);
+		for (i = 0; !feof(f); i++) {
+			fscanf(f,
+			       "%10d %10d  %4o  %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
+			       &(msgdsp->msg_perm.key),
+			       &(msgdsp->msg_perm.id),
+			       &(msgdsp->msg_perm.mode),
+			       &(msgdsp->q_cbytes),
+			       &(msgdsp->q_qnum),
+			       &(msgdsp->q_lspid),
+			       &(msgdsp->q_lrpid),
+			       &(msgdsp->msg_perm.uid),
+			       &(msgdsp->msg_perm.gid),
+			       &(msgdsp->msg_perm.cuid),
+			       &(msgdsp->msg_perm.cgid),
+			       &(msgdsp->q_stime),
+			       &(msgdsp->q_rtime),
+			       &(msgdsp->q_ctime)
+			    );
+			if (id < 0) {
+				msgdsp->next = xmalloc(sizeof(struct msg_data));
+				msgdsp = msgdsp->next;
+				msgdsp->next = NULL;
+			}
+		}
+		if (i == 0)
+			free(*msgds);
+		fclose(f);
+		return i;
+	}
+
+	/* Fallback; /proc or /sys file(s) missing. */
+	if (id < 0)
+		i = 0;
+	else
+		i = id;
+	while (i <= maxid) {
+		msgid = msgctl(id, MSG_STAT, &msgque);
+		if (msgid < 0) {
+			if (-1 < id) {
+				free(*msgds);
+				return 0;
+			}
+			i++;
+			continue;
+		}
+		msgdsp->msg_perm.key = ipcp->KEY;
+		msgdsp->msg_perm.id = msgid;
+		msgdsp->msg_perm.mode = ipcp->mode;
+		msgdsp->q_cbytes = msgque.msg_cbytes;
+		msgdsp->q_qnum = msgque.msg_qnum;
+		msgdsp->q_lspid = msgque.msg_lspid;
+		msgdsp->q_lrpid = msgque.msg_lrpid;
+		msgdsp->msg_perm.uid = ipcp->uid;
+		msgdsp->msg_perm.gid = ipcp->gid;
+		msgdsp->msg_perm.cuid = ipcp->cuid;
+		msgdsp->msg_perm.cgid = ipcp->cgid;
+		msgdsp->q_stime = msgque.msg_stime;
+		msgdsp->q_rtime = msgque.msg_rtime;
+		msgdsp->q_ctime = msgque.msg_ctime;
+
+		if (id < 0) {
+			msgdsp->next = xmalloc(sizeof(struct msg_data));
+			msgdsp = msgdsp->next;
+			msgdsp->next = NULL;
+			i++;
+		} else {
+			return 1;
+		}
+	}
+	return i;
+}
+
 static int test_ipc_proc_paths(void)
 {
 	if (access(_PATH_PROC_IPCMSG, F_OK) == 0 &&
@@ -380,7 +470,7 @@ static int test_ipc_proc_paths(void)
 
 static void do_shm (char format, int use_proc);
 void do_sem (char format, int use_proc);
-void do_msg (char format, int use_proc);
+static void do_msg (char format, int use_proc);
 void print_shm (int id);
 void print_msg (int id);
 void print_sem (int id);
@@ -807,13 +897,22 @@ void do_sem (char format, int use_proc)
 	}
 }
 
-void do_msg (char format, int use_proc)
+static void freemsgs(struct msg_data *msgds)
 {
-	int maxid, msqid, id;
-	struct msqid_ds msgque;
+	while (msgds) {
+		struct msg_data *next = msgds->next;
+		free(msgds);
+		msgds = next;
+	}
+	return;
+}
+
+static void do_msg (char format, int use_proc)
+{
+	int maxid;
 	struct msginfo msginfo;
-	struct ipc_perm *ipcp = &msgque.msg_perm;
 	struct passwd *pw;
+	struct msg_data *msgds, *msgdsp;
 	struct proc_limits lim;
 
 	maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo);
@@ -865,56 +964,49 @@ void do_msg (char format, int use_proc)
 		break;
 	}
 
-	for (id = 0; id <= maxid; id++) {
-		msqid = msgctl (id, MSG_STAT, &msgque);
-		if (msqid < 0)
-			continue;
+	if (msgctl_info_wrapper (maxid, -1, &msgds, use_proc) < 1)
+		return;
+
+	for (msgdsp = msgds; msgdsp->next != NULL; msgdsp = msgdsp->next) {
 		if (format == CREATOR)  {
-			print_perms (msqid, ipcp);
+			FIXED_print_perms (&(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;
 		}
 	}
+	freemsgs(msgds);
 	return;
 }
 
-- 
1.7.12.3

--
To unsubscribe from this list: send the line "unsubscribe util-linux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux