[igt-dev] [PATCH i-g-t] lib/sysfs: Avoid using FILE* temporary for igt_sysfs_[v]printf

Chris Wilson chris at chris-wilson.co.uk
Thu Aug 30 08:44:33 UTC 2018


Currently we wrap our fd inside a FILE* stream to make use of vfprintf,
but the man page leaves the question of errno and signal handling in
doubt. It is documented as returning a negative value and setting
ferror(), but we have been interpreting errno to handle signal
restarting. As that is in doubt, reduce it to a sprintf and reuse our
common interrupt handling write() that already returns -errno.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Katarzyna Dec <katarzyna.dec at intel.com>
---
 lib/igt_sysfs.c | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
index 8efe889be..b39da4c2a 100644
--- a/lib/igt_sysfs.c
+++ b/lib/igt_sysfs.c
@@ -387,22 +387,37 @@ int igt_sysfs_scanf(int dir, const char *attr, const char *fmt, ...)
 
 int igt_sysfs_vprintf(int dir, const char *attr, const char *fmt, va_list ap)
 {
-	FILE *file;
-	int fd;
-	int ret = -1;
+	char stack[128], *buf = stack;
+	va_list tmp;
+	int ret, fd;
 
 	fd = openat(dir, attr, O_WRONLY);
 	if (fd < 0)
-		return -1;
+		return -errno;
 
-	file = fdopen(fd, "w");
-	if (file) {
-		do {
-			ret = vfprintf(file, fmt, ap);
-		} while (ret == -1 && errno == EINTR);
-		fclose(file);
+	va_copy(tmp, ap);
+	ret = vsnprintf(buf, sizeof(stack), fmt, tmp);
+	va_end(tmp);
+	if (ret < 0)
+		return -EINVAL;
+
+	if (ret > sizeof(stack)) {
+		int len = ret + 1;
+
+		buf = malloc(len);
+		if (!buf)
+			return -ENOMEM;
+
+		ret = vsnprintf(buf, ret, fmt, ap);
+		if (ret > len) {
+			free(buf);
+			return -EINVAL;
+		}
 	}
-	close(fd);
+
+	ret = writeN(fd, buf, ret);
+	if (buf != stack)
+		free(buf);
 
 	return ret;
 }
-- 
2.19.0.rc1



More information about the igt-dev mailing list