summaryrefslogtreecommitdiff
path: root/lib/igt_sysfs.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-08-30 09:38:55 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2018-08-30 19:29:19 +0100
commit3f89d7b02dcf662e994c7135b13d52bc8e09a4ea (patch)
tree9827ed62b6edfd0ae4f6063b692bb49c54e43d67 /lib/igt_sysfs.c
parente39e09910fc8e369e24f6a0cabaeb9356dbfae08 (diff)
lib/sysfs: Avoid using FILE* temporary for igt_sysfs_[v]printf
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@chris-wilson.co.uk> Cc: Katarzyna Dec <katarzyna.dec@intel.com> Reviewed-by: Katarzyna Dec <katarzyna.dec@intel.com>
Diffstat (limited to 'lib/igt_sysfs.c')
-rw-r--r--lib/igt_sysfs.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
index 8efe889b..9012cc73 100644
--- a/lib/igt_sysfs.c
+++ b/lib/igt_sysfs.c
@@ -387,22 +387,39 @@ 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)) {
+ unsigned int len = ret + 1;
+
+ buf = malloc(len);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = vsnprintf(buf, ret, fmt, ap);
+ if (ret > len) {
+ free(buf);
+ return -EINVAL;
+ }
}
+
+ ret = writeN(fd, buf, ret);
+
close(fd);
+ if (buf != stack)
+ free(buf);
return ret;
}