[PATCH 05/13] ipcs: read shared memory values from /proc

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

 



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

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

diff --git a/sys-utils/ipcs.c b/sys-utils/ipcs.c
index 8ac7e1c..b2d4649 100644
--- a/sys-utils/ipcs.c
+++ b/sys-utils/ipcs.c
@@ -35,6 +35,7 @@
 #include "nls.h"
 #include "closestream.h"
 #include "pathnames.h"
+#include "xalloc.h"
 
 /*
  * SHM_DEST and SHM_LOCKED are defined in kernel headers, but inside
@@ -262,6 +263,106 @@ static int shmctl_limits_wrapper(struct proc_limits *lim, int use_proc)
 	return 0;
 }
 
+#if BITS_PER_LONG <= 32		/* FIXME: autotools needs to determine this */
+# define SIZE_SPEC "%10lu"
+#else
+# define SIZE_SPEC "%21lu"
+#endif
+static int shmctl_info_wrapper(int maxid, int id, struct shm_data **shmds,
+			       int use_proc)
+{
+	char skipheader[1024];
+	int i, shmid;
+	struct shm_data *shmdsp;
+
+	struct shmid_ds shmseg;
+	struct ipc_perm *ipcp = &shmseg.shm_perm;
+
+	*shmds = xmalloc(sizeof(struct shm_data));
+	shmdsp = *shmds;
+	shmdsp->next = NULL;
+	if (use_proc) {
+		FILE *f;
+		if ((f = fopen(_PATH_PROC_IPCSHM, "r")) == NULL)
+			return -1;
+		fgets(skipheader, 1024, f);
+		for (i = 0; !feof(f); i++) {
+			fscanf(f,
+			       "%10d %10d  %4o " SIZE_SPEC
+			       " %5lu %5lu  %5lu %5u %5u %5u %5u %10lu %10lu %10lu "
+			       SIZE_SPEC " " SIZE_SPEC "\n",
+			       &(shmdsp->shm_perm.key),
+			       &(shmdsp->shm_perm.id),
+			       &(shmdsp->shm_perm.mode),
+			       &(shmdsp->shm_segsz),
+			       &(shmdsp->shm_cprid),
+			       &(shmdsp->shm_lprid),
+			       &(shmdsp->shm_nattch),
+			       &(shmdsp->shm_perm.uid),
+			       &(shmdsp->shm_perm.gid),
+			       &(shmdsp->shm_perm.cuid),
+			       &(shmdsp->shm_perm.cgid),
+			       &(shmdsp->shm_atim),
+			       &(shmdsp->shm_dtim),
+			       &(shmdsp->shm_ctim),
+			       &(shmdsp->shm_rss),
+			       &(shmdsp->shm_swp)
+			    );
+			if (id < 0) {
+				shmdsp->next = xmalloc(sizeof(struct shm_data));
+				shmdsp = shmdsp->next;
+				shmdsp->next = NULL;
+			}
+		}
+		if (i == 0)
+			free(*shmds);
+		fclose(f);
+		return i;
+	}
+
+	/* Fallback; /proc or /sys file(s) missing. */
+	if (id < 0)
+		i = 0;
+	else
+		i = id;
+	while (i <= maxid) {
+		shmid = shmctl(i, SHM_STAT, &shmseg);
+		if (shmid < 0) {
+			if (-1 < id) {
+				free(*shmds);
+				return 0;
+			}
+			i++;
+			continue;
+		}
+		shmdsp->shm_perm.key = ipcp->KEY;
+		shmdsp->shm_perm.id = shmid;
+		shmdsp->shm_perm.mode = ipcp->mode;
+		shmdsp->shm_segsz = shmseg.shm_segsz;
+		shmdsp->shm_cprid = shmseg.shm_cpid;
+		shmdsp->shm_lprid = shmseg.shm_lpid;
+		shmdsp->shm_nattch = shmseg.shm_nattch;
+		shmdsp->shm_perm.uid = ipcp->uid;
+		shmdsp->shm_perm.gid = ipcp->gid;
+		shmdsp->shm_perm.cuid = ipcp->cuid;
+		shmdsp->shm_perm.cgid = ipcp->cuid;
+		shmdsp->shm_atim = shmseg.shm_atime;
+		shmdsp->shm_dtim = shmseg.shm_dtime;
+		shmdsp->shm_ctim = shmseg.shm_ctime;
+		shmdsp->shm_rss = 0xdead;
+		shmdsp->shm_swp = 0xdead;
+		if (id < 0) {
+			shmdsp->next = xmalloc(sizeof(struct shm_data));
+			shmdsp = shmdsp->next;
+			shmdsp->next = NULL;
+			i++;
+		} else {
+			return 1;
+		}
+	}
+	return i;
+}
+
 static int test_ipc_proc_paths(void)
 {
 	if (access(_PATH_PROC_IPCMSG, F_OK) == 0 &&
@@ -277,7 +378,7 @@ static int test_ipc_proc_paths(void)
 	return 0;
 }
 
-void do_shm (char format, int use_proc);
+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);
 void print_shm (int id);
@@ -465,13 +566,22 @@ static void FIXED_print_perms(struct ipc_stat *is)
 		printf(" %-10u\n", is->gid);
 }
 
-void do_shm (char format, int use_proc)
+static void freeshms(struct shm_data *shmds)
 {
-	int maxid, shmid, id;
-	struct shmid_ds shmseg;
+	while (shmds) {
+		struct shm_data *next = shmds->next;
+		free(shmds);
+		shmds = next;
+	}
+	return;
+}
+
+static void do_shm (char format, int use_proc)
+{
+	int maxid;
 	struct shm_info shm_info;
-	struct ipc_perm *ipcp = &shmseg.shm_perm;
 	struct passwd *pw;
+	struct shm_data *shmds, *shmdsp;
 	struct proc_limits lim;
 
 	maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info);
@@ -544,60 +654,55 @@ void do_shm (char format, int use_proc)
 		break;
 	}
 
-	for (id = 0; id <= maxid; id++) {
-		shmid = shmctl (id, SHM_STAT, &shmseg);
-		if (shmid < 0)
-			continue;
+	if (shmctl_info_wrapper (maxid, -1, &shmds, use_proc) < 1)
+		return;
+	shmdsp = shmds;
+
+	for (shmdsp = shmds; shmdsp->next != NULL; shmdsp = shmdsp->next) {
 		if (format == CREATOR)  {
-			print_perms (shmid, ipcp);
+			FIXED_print_perms (&(shmdsp->shm_perm));
 			continue;
 		}
-		pw = getpwuid(ipcp->uid);
+		pw = getpwuid(shmdsp->shm_perm.uid);
 		switch (format) {
 		case TIME:
 			if (pw)
-				printf ("%-10d %-10.10s", shmid, pw->pw_name);
+				printf ("%-10d %-10.10s", shmdsp->shm_perm.id, pw->pw_name);
 			else
-				printf ("%-10d %-10u", shmid, ipcp->uid);
+				printf ("%-10d %-10u", shmdsp->shm_perm.id, shmdsp->shm_perm.uid);
 			/* ctime uses static buffer: use separate calls */
-			printf(" %-20.16s", shmseg.shm_atime
-			       ? ctime(&shmseg.shm_atime) + 4 : _("Not set"));
-			printf(" %-20.16s", shmseg.shm_dtime
-			       ? ctime(&shmseg.shm_dtime) + 4 : _("Not set"));
-			printf(" %-20.16s\n", shmseg.shm_ctime
-			       ? ctime(&shmseg.shm_ctime) + 4 : _("Not set"));
+			printf(" %-20.16s", shmdsp->shm_atim
+			       ? ctime(&(shmdsp->shm_atim)) + 4 : _("Not set"));
+			printf(" %-20.16s", shmdsp->shm_dtim
+			       ? ctime(&(shmdsp->shm_dtim)) + 4 : _("Not set"));
+			printf(" %-20.16s\n", shmdsp->shm_ctim
+			       ? ctime(&(shmdsp->shm_ctim)) + 4 : _("Not set"));
 			break;
 		case PID:
 			if (pw)
-				printf ("%-10d %-10.10s", shmid, pw->pw_name);
+				printf ("%-10d %-10.10s", shmdsp->shm_perm.id, pw->pw_name);
 			else
-				printf ("%-10d %-10u", shmid, ipcp->uid);
+				printf ("%-10d %-10u", shmdsp->shm_perm.id, shmdsp->shm_perm.uid);
 			printf (" %-10d %-10d\n",
-				shmseg.shm_cpid, shmseg.shm_lpid);
+				shmdsp->shm_cprid, shmdsp->shm_lprid);
 			break;
 
 		default:
-			printf("0x%08x ",ipcp->KEY );
+			printf("0x%08x ", shmdsp->shm_perm.key);
 			if (pw)
-				printf ("%-10d %-10.10s", shmid, pw->pw_name);
+				printf ("%-10d %-10.10s", shmdsp->shm_perm.id, pw->pw_name);
 			else
-				printf ("%-10d %-10u", shmid, ipcp->uid);
+				printf ("%-10d %-10u", shmdsp->shm_perm.id, shmdsp->shm_perm.uid);
 			printf (" %-10o %-10lu %-10ld %-6s %-6s\n",
-				ipcp->mode & 0777,
-				/*
-				 * earlier: int, Austin has size_t
-				 */
-				(unsigned long) shmseg.shm_segsz,
-				/*
-				 * glibc-2.1.3 and earlier has unsigned short;
-				 * Austin has shmatt_t
-				 */
-				(long) shmseg.shm_nattch,
-				ipcp->mode & SHM_DEST ? _("dest") : " ",
-				ipcp->mode & SHM_LOCKED ? _("locked") : " ");
+				shmdsp->shm_perm.mode & 0777,
+				shmdsp->shm_segsz,
+				shmdsp->shm_nattch,
+				shmdsp->shm_perm.mode & SHM_DEST ? _("dest") : " ",
+				shmdsp->shm_perm.mode & SHM_LOCKED ? _("locked") : " ");
 			break;
 		}
 	}
+	freeshms(shmds);
 	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