Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Jun 2013 19:30:32 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r252066 - stable/8/usr.bin/procstat
Message-ID:  <201306211930.r5LJUWIv007109@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Jun 21 19:30:32 2013
New Revision: 252066
URL: http://svnweb.freebsd.org/changeset/base/252066

Log:
  MFC 251637:
  Borrow the algorithm from kvm_getprocs() to fix procstat(1) to handle the
  case where the process tables grows in between the calls to fetch the size
  and fetch the table.
  
  Note that this is not a true MFC as the libprocstat library doesn't exist
  in 8.x and the relevant code is in the procstat binary instead.

Modified:
  stable/8/usr.bin/procstat/procstat.c

Modified: stable/8/usr.bin/procstat/procstat.c
==============================================================================
--- stable/8/usr.bin/procstat/procstat.c	Fri Jun 21 19:28:58 2013	(r252065)
+++ stable/8/usr.bin/procstat/procstat.c	Fri Jun 21 19:30:32 2013	(r252066)
@@ -107,7 +107,7 @@ main(int argc, char *argv[])
 	int ch, interval, name[4], tmp;
 	unsigned int i;
 	struct kinfo_proc *kipp;
-	size_t len;
+	size_t len, olen;
 	long l;
 	pid_t pid;
 	char *dummy;
@@ -204,13 +204,21 @@ main(int argc, char *argv[])
 			if (sysctl(name, 3, NULL, &len, NULL, 0) < 0)
 				err(-1, "sysctl: kern.proc.all");
 
-			kipp = malloc(len);
-			if (kipp == NULL)
-				err(-1, "malloc");
-
-			if (sysctl(name, 3, kipp, &len, NULL, 0) < 0) {
-				free(kipp);
-				err(-1, "sysctl: kern.proc.all");
+			kipp = NULL;
+			for (;;) {
+				len += len / 10;
+				kipp = reallocf(kipp, len);
+				if (kipp == NULL)
+					err(-1, "malloc");
+
+				olen = len;
+				if (sysctl(name, 3, kipp, &len, NULL, 0) < 0) {
+					if (errno == ENOMEM && olen == len)
+						continue;
+					free(kipp);
+					err(-1, "sysctl: kern.proc.all");
+				}
+				break;
 			}
 			if (len % sizeof(*kipp) != 0)
 				err(-1, "kinfo_proc mismatch");
@@ -242,13 +250,22 @@ main(int argc, char *argv[])
 			if (sysctl(name, 4, NULL, &len, NULL, 0) < 0)
 				err(-1, "sysctl: kern.proc.pid: %d", pid);
 
-			kipp = malloc(len);
-			if (kipp == NULL)
-				err(-1, "malloc");
-
-			if (sysctl(name, 4, kipp, &len, NULL, 0) < 0) {
-				free(kipp);
-				err(-1, "sysctl: kern.proc.pid: %d", pid);
+			kipp = NULL;
+			for (;;) {
+				len += len / 10;
+				kipp = reallocf(kipp, len);
+				if (kipp == NULL)
+					err(-1, "malloc");
+
+				olen = len;
+				if (sysctl(name, 4, kipp, &len, NULL, 0) < 0) {
+					if (errno == ENOMEM && olen == len)
+						continue;
+					free(kipp);
+					err(-1, "sysctl: kern.proc.pid: %d",
+					    pid);
+				}
+				break;
 			}
 			if (len != sizeof(*kipp))
 				err(-1, "kinfo_proc mismatch");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306211930.r5LJUWIv007109>