From e3db32aadaccdea2d0af0d340fc605b514512578 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 17 Nov 2016 19:22:02 +0000 Subject: [PATCH] backlight: Protect iface writes against signal interruptions Handle EINTR (and EAGAIN) by repeating until the write is complete. References: https://bugs.freedesktop.org/show_bug.cgi?id=98759 Signed-off-by: Chris Wilson --- src/backlight.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/backlight.c b/src/backlight.c index d020a7c..3cba577 100644 --- a/src/backlight.c +++ b/src/backlight.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -216,6 +217,24 @@ __backlight_read(const char *iface, const char *file) } static int +writen(int fd, const char *value, int len) +{ + int ret; + + do { + ret = write(fd, value, len); + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + + return ret; + } + } while (value += ret, len -= ret); + + return 0; +} + +static int __backlight_write(const char *iface, const char *file, const char *value) { int fd, ret; @@ -224,7 +243,7 @@ __backlight_write(const char *iface, const char *file, const char *value) if (fd < 0) return -1; - ret = write(fd, value, strlen(value)+1); + ret = writen(fd, value, strlen(value)+1); close(fd); return ret; @@ -458,7 +477,7 @@ err: int backlight_set(struct backlight *b, int level) { char val[BACKLIGHT_VALUE_LEN]; - int len, ret = 0; + int len; if (b->iface == NULL) return 0; @@ -467,10 +486,7 @@ int backlight_set(struct backlight *b, int level) level = b->max; len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level); - if (write(b->fd, val, len) != len) - ret = -1; - - return ret; + return writen(b->fd, val, len); } int backlight_get(struct backlight *b) -- 2.7.4