diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2018-08-30 09:38:55 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2018-08-30 19:29:19 +0100 |
commit | 3f89d7b02dcf662e994c7135b13d52bc8e09a4ea (patch) | |
tree | 9827ed62b6edfd0ae4f6063b692bb49c54e43d67 /lib/igt_sysfs.c | |
parent | e39e09910fc8e369e24f6a0cabaeb9356dbfae08 (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.c | 37 |
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; } |