[CRIU] [PATCH 2/2] proc: read all data from /proc/pid/task/tid/children (v2)

Andrey Vagin avagin at openvz.org
Mon Oct 26 10:20:43 PDT 2015


From: Andrew Vagin <avagin at openvz.org>

Currently we read only 4096 bytes (the size of buf).

v2: use the bfd engine
Signed-off-by: Andrew Vagin <avagin at openvz.org>
---
 proc_parse.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/proc_parse.c b/proc_parse.c
index c654c1f..24b81ec 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -2153,47 +2153,50 @@ int __parse_children(pid_t pid, pid_t **_c, int *_n)
 	int nr = *_n;
 	DIR *dir;
 	struct dirent *de;
+	struct bfd f;
 
 	dir = opendir_proc(pid, "task");
 	if (dir == NULL)
 		return -1;
 
 	while ((de = readdir(dir))) {
-		int fd, len;
-		char *pos;
+		char *pos, *end;
 
 		if (dir_dots(de))
 			continue;
 
-		fd = open_proc(pid, "task/%s/children", de->d_name);
-		if (fd < 0)
+		f.fd = open_proc(pid, "task/%s/children", de->d_name);
+		if (f.fd < 0)
 			goto err;
 
-		len = read(fd, buf, BUF_SIZE);
-		close(fd);
-		if (len < 0)
+		if (bfdopenr(&f))
 			goto err;
 
-		buf[len] = '\0';
-		pos = buf;
 		while (1) {
 			pid_t val, *tmp;
 
-			val = strtol(pos, &pos, 0);
-			if (!val) {
-				BUG_ON(*pos != '\0');
+			pos = breadchr(&f, ' ');
+			if (IS_ERR(pos))
+				goto err_close;
+			if (pos == NULL)
 				break;
+
+			val = strtol(pos, &end, 0);
+
+			if (*end != 0 && *end != ' ') {
+				pr_err("Unable to parse %s\n", end);
+				goto err_close;
 			}
 
 			tmp = xrealloc(ch, (nr + 1) * sizeof(pid_t));
 			if (!tmp)
-				goto err;
+				goto err_close;
 
 			ch = tmp;
 			ch[nr] = val;
 			nr++;
-			pos++; /* space goes after each pid */
 		}
+		bclose(&f);
 	}
 
 	*_c = ch;
@@ -2201,6 +2204,8 @@ int __parse_children(pid_t pid, pid_t **_c, int *_n)
 
 	closedir(dir);
 	return 0;
+err_close:
+	bclose(&f);
 err:
 	closedir(dir);
 	xfree(ch);
-- 
2.4.3



More information about the CRIU mailing list