Blob Blame History Raw
From 5a8d3bab6f492b3932299d9e80fb247ab00b8102 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@strace.io>
Date: Sun, 7 Mar 2021 08:00:00 +0000
Subject: [PATCH 147/149] file_handle: print f_handle as a hexadecimal string

Printing the sequence of bytes as a hexadecimal number is misleading
because the latter depends on endianness.

* src/file_handle.c (print_f_handle): New function.
(SYS_FUNC(name_to_handle_at), SYS_FUNC(open_by_handle_at)): Use it
to print struct file_handle.f_handle.
* tests/file_handle.c (print_handle_data, do_open_by_handle_at, main):
Update expected output.
---
 file_handle.c       | 47 ++++++++++++++++++++++-------------------------
 tests/file_handle.c | 26 +++++++++++---------------
 2 files changed, 33 insertions(+), 40 deletions(-)

diff --git a/file_handle.c b/file_handle.c
index d82a1bc..343111f 100644
--- a/file_handle.c
+++ b/file_handle.c
@@ -19,6 +19,22 @@ typedef struct {
 	int handle_type;
 } file_handle_header;
 
+static void
+print_f_handle(struct tcb *tcp, kernel_ulong_t addr, unsigned int handle_bytes)
+{
+	unsigned int len = MIN(handle_bytes, MAX_HANDLE_SZ);
+	char f_handle[MAX_HANDLE_SZ];
+	addr += sizeof(file_handle_header);
+	if (addr > sizeof(file_handle_header) &&
+	    !umoven(tcp, addr, len, f_handle)) {
+		print_quoted_string(f_handle, len, QUOTE_FORCE_HEX);
+		if (handle_bytes > len)
+			tprints("...");
+	} else {
+		tprints("???");
+	}
+}
+
 SYS_FUNC(name_to_handle_at)
 {
 	file_handle_header h;
@@ -53,24 +69,15 @@ SYS_FUNC(name_to_handle_at)
 
 		return 0;
 	} else {
-		unsigned int i = get_tcb_priv_ulong(tcp);
-
 		if ((!syserror(tcp) || EOVERFLOW == tcp->u_error)
 		    && !umove(tcp, addr, &h)) {
-			unsigned char f_handle[MAX_HANDLE_SZ];
 
-			if (i != h.handle_bytes)
+			if (h.handle_bytes != get_tcb_priv_ulong(tcp))
 				tprintf(" => %u", h.handle_bytes);
 			if (!syserror(tcp)) {
-				tprintf(", handle_type=%d", h.handle_type);
-				if (h.handle_bytes > MAX_HANDLE_SZ)
-					h.handle_bytes = MAX_HANDLE_SZ;
-				if (!umoven(tcp, addr + sizeof(h), h.handle_bytes,
-					    f_handle)) {
-					tprints(", f_handle=0x");
-					for (i = 0; i < h.handle_bytes; ++i)
-						tprintf("%02x", f_handle[i]);
-				}
+				tprintf(", handle_type=%d, f_handle=",
+					h.handle_type);
+				print_f_handle(tcp, addr, h.handle_bytes);
 			}
 		}
 		tprints("}, ");
@@ -96,19 +103,9 @@ SYS_FUNC(open_by_handle_at)
 
 	/* handle */
 	if (!umove_or_printaddr(tcp, addr, &h)) {
-		unsigned char f_handle[MAX_HANDLE_SZ];
-
-		tprintf("{handle_bytes=%u, handle_type=%d",
+		tprintf("{handle_bytes=%u, handle_type=%d, f_handle=",
 			h.handle_bytes, h.handle_type);
-		if (h.handle_bytes > MAX_HANDLE_SZ)
-			h.handle_bytes = MAX_HANDLE_SZ;
-		if (!umoven(tcp, addr + sizeof(h), h.handle_bytes, &f_handle)) {
-			unsigned int i;
-
-			tprints(", f_handle=0x");
-			for (i = 0; i < h.handle_bytes; ++i)
-				tprintf("%02x", f_handle[i]);
-		}
+		print_f_handle(tcp, addr, h.handle_bytes);
 		tprints("}");
 	}
 	tprints(", ");
diff --git a/tests/file_handle.c b/tests/file_handle.c
index edabde6..07af7ba 100644
--- a/tests/file_handle.c
+++ b/tests/file_handle.c
@@ -42,14 +42,10 @@ struct file_handle {
 void
 print_handle_data(unsigned char *bytes, unsigned int size)
 {
-	unsigned int i;
-
-	if (size > MAX_HANDLE_SZ)
-		size = MAX_HANDLE_SZ;
-
-	printf("0x");
-	for (i = 0; i < size; ++i)
-		printf("%02x", bytes[i]);
+	unsigned int len = MIN(size, MAX_HANDLE_SZ);
+	print_quoted_hex(bytes, len);
+	if (size > len)
+		printf("...");
 }
 
 void
@@ -111,11 +107,13 @@ do_open_by_handle_at(kernel_ulong_t mount_fd,
 		printf("{handle_bytes=%u, handle_type=%d", fh->handle_bytes,
 		       fh->handle_type);
 
+		printf(", f_handle=");
 		if (valid_data) {
-			printf(", f_handle=");
 			print_handle_data((unsigned char *) fh +
 					  sizeof(struct file_handle),
 					  fh->handle_bytes);
+		} else {
+			printf("???");
 		}
 
 		printf("}");
@@ -275,16 +273,14 @@ main(void)
 	assert(syscall(__NR_name_to_handle_at, fdcwd, ".", handle, &mount_id,
 		flags) == 0);
 	printf("name_to_handle_at(AT_FDCWD, \".\", {handle_bytes=%u"
-	       ", handle_type=%d, f_handle=0x",
+	       ", handle_type=%d, f_handle=",
 	       handle->handle_bytes, handle->handle_type);
-	for (i = 0; i < handle->handle_bytes; ++i)
-		printf("%02x", handle->f_handle[i]);
+	print_handle_data(handle->f_handle, handle->handle_bytes);
 	printf("}, [%d], AT_SYMLINK_FOLLOW) = 0\n", mount_id);
 
 	printf("open_by_handle_at(-1, {handle_bytes=%u, handle_type=%d"
-	       ", f_handle=0x", handle->handle_bytes, handle->handle_type);
-	for (i = 0; i < handle->handle_bytes; ++i)
-		printf("%02x", handle->f_handle[i]);
+	       ", f_handle=", handle->handle_bytes, handle->handle_type);
+	print_handle_data(handle->f_handle, handle->handle_bytes);
 	int rc = syscall(__NR_open_by_handle_at, -1, handle,
 		O_RDONLY | O_DIRECTORY);
 	printf("}, O_RDONLY|O_DIRECTORY) = %d %s (%m)\n", rc, errno2name());
diff --git a/tests-m32/file_handle.c b/tests-m32/file_handle.c
index edabde6..07af7ba 100644
--- a/tests-m32/file_handle.c
+++ b/tests-m32/file_handle.c
@@ -42,14 +42,10 @@ struct file_handle {
 void
 print_handle_data(unsigned char *bytes, unsigned int size)
 {
-	unsigned int i;
-
-	if (size > MAX_HANDLE_SZ)
-		size = MAX_HANDLE_SZ;
-
-	printf("0x");
-	for (i = 0; i < size; ++i)
-		printf("%02x", bytes[i]);
+	unsigned int len = MIN(size, MAX_HANDLE_SZ);
+	print_quoted_hex(bytes, len);
+	if (size > len)
+		printf("...");
 }
 
 void
@@ -111,11 +107,13 @@ do_open_by_handle_at(kernel_ulong_t mount_fd,
 		printf("{handle_bytes=%u, handle_type=%d", fh->handle_bytes,
 		       fh->handle_type);
 
+		printf(", f_handle=");
 		if (valid_data) {
-			printf(", f_handle=");
 			print_handle_data((unsigned char *) fh +
 					  sizeof(struct file_handle),
 					  fh->handle_bytes);
+		} else {
+			printf("???");
 		}
 
 		printf("}");
@@ -275,16 +273,14 @@ main(void)
 	assert(syscall(__NR_name_to_handle_at, fdcwd, ".", handle, &mount_id,
 		flags) == 0);
 	printf("name_to_handle_at(AT_FDCWD, \".\", {handle_bytes=%u"
-	       ", handle_type=%d, f_handle=0x",
+	       ", handle_type=%d, f_handle=",
 	       handle->handle_bytes, handle->handle_type);
-	for (i = 0; i < handle->handle_bytes; ++i)
-		printf("%02x", handle->f_handle[i]);
+	print_handle_data(handle->f_handle, handle->handle_bytes);
 	printf("}, [%d], AT_SYMLINK_FOLLOW) = 0\n", mount_id);
 
 	printf("open_by_handle_at(-1, {handle_bytes=%u, handle_type=%d"
-	       ", f_handle=0x", handle->handle_bytes, handle->handle_type);
-	for (i = 0; i < handle->handle_bytes; ++i)
-		printf("%02x", handle->f_handle[i]);
+	       ", f_handle=", handle->handle_bytes, handle->handle_type);
+	print_handle_data(handle->f_handle, handle->handle_bytes);
 	int rc = syscall(__NR_open_by_handle_at, -1, handle,
 		O_RDONLY | O_DIRECTORY);
 	printf("}, O_RDONLY|O_DIRECTORY) = %d %s (%m)\n", rc, errno2name());
diff --git a/tests-mx32/file_handle.c b/tests-mx32/file_handle.c
index edabde6..07af7ba 100644
--- a/tests-mx32/file_handle.c
+++ b/tests-mx32/file_handle.c
@@ -42,14 +42,10 @@ struct file_handle {
 void
 print_handle_data(unsigned char *bytes, unsigned int size)
 {
-	unsigned int i;
-
-	if (size > MAX_HANDLE_SZ)
-		size = MAX_HANDLE_SZ;
-
-	printf("0x");
-	for (i = 0; i < size; ++i)
-		printf("%02x", bytes[i]);
+	unsigned int len = MIN(size, MAX_HANDLE_SZ);
+	print_quoted_hex(bytes, len);
+	if (size > len)
+		printf("...");
 }
 
 void
@@ -111,11 +107,13 @@ do_open_by_handle_at(kernel_ulong_t mount_fd,
 		printf("{handle_bytes=%u, handle_type=%d", fh->handle_bytes,
 		       fh->handle_type);
 
+		printf(", f_handle=");
 		if (valid_data) {
-			printf(", f_handle=");
 			print_handle_data((unsigned char *) fh +
 					  sizeof(struct file_handle),
 					  fh->handle_bytes);
+		} else {
+			printf("???");
 		}
 
 		printf("}");
@@ -275,16 +273,14 @@ main(void)
 	assert(syscall(__NR_name_to_handle_at, fdcwd, ".", handle, &mount_id,
 		flags) == 0);
 	printf("name_to_handle_at(AT_FDCWD, \".\", {handle_bytes=%u"
-	       ", handle_type=%d, f_handle=0x",
+	       ", handle_type=%d, f_handle=",
 	       handle->handle_bytes, handle->handle_type);
-	for (i = 0; i < handle->handle_bytes; ++i)
-		printf("%02x", handle->f_handle[i]);
+	print_handle_data(handle->f_handle, handle->handle_bytes);
 	printf("}, [%d], AT_SYMLINK_FOLLOW) = 0\n", mount_id);
 
 	printf("open_by_handle_at(-1, {handle_bytes=%u, handle_type=%d"
-	       ", f_handle=0x", handle->handle_bytes, handle->handle_type);
-	for (i = 0; i < handle->handle_bytes; ++i)
-		printf("%02x", handle->f_handle[i]);
+	       ", f_handle=", handle->handle_bytes, handle->handle_type);
+	print_handle_data(handle->f_handle, handle->handle_bytes);
 	int rc = syscall(__NR_open_by_handle_at, -1, handle,
 		O_RDONLY | O_DIRECTORY);
 	printf("}, O_RDONLY|O_DIRECTORY) = %d %s (%m)\n", rc, errno2name());
-- 
2.1.4