[DTrace-devel] [PATCH 06/17] dof_parser: restructure the dof_copyin*() code

Kris Van Hees kris.van.hees at oracle.com
Sat Jun 7 06:14:59 UTC 2025


All logic for reading data from the DOF parser pipe is now consolidated
in dof_copyin().

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
---
 dtprobed/dtprobed.c    |   6 +--
 libcommon/dof_parser.c | 115 ++++++++++++++++-------------------------
 libcommon/dof_parser.h |   4 +-
 3 files changed, 49 insertions(+), 76 deletions(-)

diff --git a/dtprobed/dtprobed.c b/dtprobed/dtprobed.c
index 5f260f0a..a9944894 100644
--- a/dtprobed/dtprobed.c
+++ b/dtprobed/dtprobed.c
@@ -302,7 +302,7 @@ cleanup_userdata(void)
 }
 
 /*
- * Parse a piece of DOF.  Return 0 iff the pipe has closed and no more parsing
+ * Parse a piece of DOF.  Return 0 iff the pipe has closed or no more parsing
  * is possible.
  */
 static int
@@ -312,9 +312,9 @@ parse_dof(int in, int out)
 	dof_helper_t *dh;
 	dof_hdr_t *dof;
 
-	dh = dof_copyin_helper(in, out, &ok);
+	dh = dof_copyin_helper(in);
 	if (!dh)
-		return ok;
+		return 0;
 
 	dof = dof_copyin_dof(in, out, &ok);
 	if (!dof) {
diff --git a/libcommon/dof_parser.c b/libcommon/dof_parser.c
index 58bbd604..ec80cee8 100644
--- a/libcommon/dof_parser.c
+++ b/libcommon/dof_parser.c
@@ -83,22 +83,24 @@ static void dof_error(int out, int err_no, const char *fmt, ...)
 	free(msg);
 }
 
-dof_helper_t *
-dof_copyin_helper(int in, int out, int *ok)
+static char *
+dof_copyin(int in, char *buf_, size_t sz)
 {
-	dof_helper_t *dh;
+	char *buf = buf_;
 	size_t i;
 
-	dh = malloc(sizeof(dof_helper_t));
-	if (!dh)
-		abort();
+	if (!buf) {
+		buf = malloc(sz);
+		if (!buf)
+			abort();
+	}
 
-	memset(dh, 0, sizeof(dof_helper_t));
+	memset(buf, 0, sz);
 
-	for (i = 0; i < sizeof(dof_helper_t);) {
+	for (i = 0; i < sz; ) {
 		size_t ret;
 
-		ret = read(in, ((char *) dh) + i, sizeof(dof_helper_t) - i);
+		ret = read(in, buf + i, sz - i);
 
 		if (ret < 0) {
 			switch (errno) {
@@ -119,89 +121,60 @@ dof_copyin_helper(int in, int out, int *ok)
 		i += ret;
 	}
 
-	*ok = 1;
-	return dh;
+	return buf;
 
 err:
-	*ok = 0;
-	free(dh);
+	if (!buf_)
+		free(buf);
 	return NULL;
 }
 
+dof_helper_t *
+dof_copyin_helper(int in)
+{
+	return (dof_helper_t *)dof_copyin(in, NULL, sizeof(dof_helper_t));
+}
+
 dof_hdr_t *
 dof_copyin_dof(int in, int out, int *ok)
 {
 	dof_hdr_t *dof;
-	size_t i, sz;
 
 	*ok = 1;
 
-	/*
-	 * First get the header, which gives the size of everything else.
-	 */
-	dof = malloc(sizeof(dof_hdr_t));
+	/* First get the header, which gives the size of everything else. */
+	dof = (dof_hdr_t *)dof_copyin(in, NULL, sizeof(dof_hdr_t));
 	if (!dof)
 		abort();
 
-	memset(dof, 0, sizeof(dof_hdr_t));
-
-	for (i = 0, sz = sizeof(dof_hdr_t); i < sz;) {
-		size_t ret;
-
-		ret = read(in, ((char *) dof) + i, sz - i);
-
-		if (ret < 0) {
-			switch (errno) {
-			case EINTR:
-				continue;
-			default:
-				goto err;
-			}
-		}
-
-		/*
-		 * EOF: parsing done, process shutting down or message
-		 * truncated.  Fail, in any case.
-		 */
-		if (ret == 0)
-			goto err;
-
-		/* Allocate more room if needed for the reply.  */
-		if (i < sizeof(dof_hdr_t) &&
-		    i + ret >= sizeof(dof_hdr_t)) {
-			dof_hdr_t *new_dof;
-
-			if (dof->dofh_loadsz >= dof_maxsize) {
-				dof_error(out, E2BIG, "load size %zi exceeds maximum %zi",
-					  dof->dofh_loadsz, dof_maxsize);
-				return NULL;
-			}
-
-			if (dof->dofh_loadsz < sizeof(dof_hdr_t)) {
-				dof_error(out, EINVAL, "invalid load size %zi, "
-					  "smaller than header size %zi", dof->dofh_loadsz,
-					  sizeof(dof_hdr_t));
-				return NULL;
-			}
+	/* Validate the DOF load size. */
+	if (dof->dofh_loadsz >= dof_maxsize) {
+		dof_error(out, E2BIG, "load size %zi exceeds maximum %zi",
+			  dof->dofh_loadsz, dof_maxsize);
+		return NULL;
+	}
 
-			new_dof = realloc(dof, dof->dofh_loadsz);
-			if (!new_dof)
-				abort();
+	if (dof->dofh_loadsz < sizeof(dof_hdr_t)) {
+		dof_error(out, EINVAL, "invalid load size %zi, "
+			  "smaller than header size %zi", dof->dofh_loadsz,
+			  sizeof(dof_hdr_t));
+		return NULL;
+	}
 
-			memset(((char *)new_dof) + i + ret, 0, new_dof->dofh_loadsz - (i + ret));
-			dof = new_dof;
-			sz = dof->dofh_loadsz;
-		}
+	/* Resize the allocated memory to fit the actual data as well. */
+	dof = realloc(dof, dof->dofh_loadsz);
+	if (!dof)
+		abort();
 
-		i += ret;
+	/* Read the actual data in the allocated buffer. */
+	if (!dof_copyin(in, ((char *)dof) + sizeof(dof_hdr_t),
+			dof->dofh_loadsz - sizeof(dof_hdr_t))) {
+		*ok = 0;
+		free(dof);
+		return NULL;
 	}
 
 	return dof;
-
-err:
-	*ok = 0;
-	free(dof);
-	return NULL;
 }
 
 static void dof_destroy(dof_helper_t *dhp, dof_hdr_t *dof)
diff --git a/libcommon/dof_parser.h b/libcommon/dof_parser.h
index 75aa3082..de6cea4c 100644
--- a/libcommon/dof_parser.h
+++ b/libcommon/dof_parser.h
@@ -180,9 +180,9 @@ dof_parsed_t *dof_parser_host_read(int in, int timeout);
 /*
  * Get a dof_helper_t from the input fd.
  *
- * Set OK to zero if no further parsing is possible.
+ * Returns NULL on failure - no further processing is possible in that case.
  */
-dof_helper_t *dof_copyin_helper(int in, int out, int *ok);
+dof_helper_t *dof_copyin_helper(int in);
 
 /*
  * Get a buffer of DOF from the input fd and sanity-check it.
-- 
2.45.2




More information about the DTrace-devel mailing list