From ae2ac05cedecca553f8f8c19c69bab6b0eebafa6 Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 6 Aug 2014 22:04:15 +0400 Subject: [PATCH 1/3] Handle errors from write() Fixes #964 --- client/powerline.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/client/powerline.c b/client/powerline.c index fd08c066..97f433c3 100644 --- a/client/powerline.c +++ b/client/powerline.c @@ -120,7 +120,30 @@ int main(int argc, char *argv[]) { close(sd); HANDLE_ERROR("read() failed"); } else if (i > 0) { - (void) write(STDOUT_FILENO, buf, (size_t) i); + ptrdiff_t written = 0; + const char *bufp = &(buf[0]); + while (written < i) { + written = write(STDOUT_FILENO, buf, (size_t) i); + if (written >= 0) { + bufp += written; + i -= written; + written = 0; + } else { + errno = 0; + switch (errno) { + case EAGAIN: +#if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: +#endif + case EINTR: + break; + default: + (void) printf("Error while writing output: %s", strerror(errno)); + close(sd); + return 2; + } + } + } } } From 0a6bb9ce083ad48c724c5f0395f2f786c988d3c8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 6 Aug 2014 22:31:16 +0400 Subject: [PATCH 2/3] Some style fixes --- client/powerline.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/client/powerline.c b/client/powerline.c index 97f433c3..6e8c8df1 100644 --- a/client/powerline.c +++ b/client/powerline.c @@ -13,14 +13,15 @@ #define HANDLE_ERROR(msg) \ do { \ - perror(msg); exit(EXIT_FAILURE); \ + perror(msg); \ + exit(EXIT_FAILURE); \ } while (0) #define TEMP_FAILURE_RETRY(var, expression) \ do { \ - long int __result; \ + ptrdiff_t __result; \ do { \ - __result = (long int) (expression); \ + __result = (expression); \ } while (__result == -1L && errno == EINTR); \ var = __result; \ } while (0) @@ -56,7 +57,8 @@ void do_write(int sd, const char *raw, size_t len) { int main(int argc, char *argv[]) { int sd = -1; - ptrdiff_t i; + int i; + ptrdiff_t read_size; struct sockaddr_un server; char address[ADDRESS_SIZE]; const char eof[2] = "\0\0"; @@ -67,7 +69,8 @@ int main(int argc, char *argv[]) { char **envp; if (argc < 2) { - printf("Must provide at least one argument.\n"); return EXIT_FAILURE; + printf("Must provide at least one argument.\n"); + return EXIT_FAILURE; } snprintf(address, ADDRESS_SIZE, ADDRESS_TEMPLATE, getuid()); @@ -113,20 +116,20 @@ int main(int argc, char *argv[]) { do_write(sd, eof, 2); - i = -1; - while (i != 0) { - TEMP_FAILURE_RETRY(i, read(sd, buf, BUF_SIZE)); - if (i == -1) { + read_size = -1; + while (read_size != 0) { + TEMP_FAILURE_RETRY(read_size, read(sd, buf, BUF_SIZE)); + if (read_size == -1) { close(sd); HANDLE_ERROR("read() failed"); - } else if (i > 0) { + } else if (read_size > 0) { ptrdiff_t written = 0; const char *bufp = &(buf[0]); - while (written < i) { - written = write(STDOUT_FILENO, buf, (size_t) i); + while (written < read_size) { + written = write(STDOUT_FILENO, buf, (size_t) read_size); if (written >= 0) { bufp += written; - i -= written; + read_size -= written; written = 0; } else { errno = 0; From 660925f0c2ca80abda0f3880cd93a762e458833c Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 6 Aug 2014 22:32:39 +0400 Subject: [PATCH 3/3] Use do_write function in place of self-written replacement --- client/powerline.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/client/powerline.c b/client/powerline.c index 6e8c8df1..0800f701 100644 --- a/client/powerline.c +++ b/client/powerline.c @@ -123,30 +123,7 @@ int main(int argc, char *argv[]) { close(sd); HANDLE_ERROR("read() failed"); } else if (read_size > 0) { - ptrdiff_t written = 0; - const char *bufp = &(buf[0]); - while (written < read_size) { - written = write(STDOUT_FILENO, buf, (size_t) read_size); - if (written >= 0) { - bufp += written; - read_size -= written; - written = 0; - } else { - errno = 0; - switch (errno) { - case EAGAIN: -#if EAGAIN != EWOULDBLOCK - case EWOULDBLOCK: -#endif - case EINTR: - break; - default: - (void) printf("Error while writing output: %s", strerror(errno)); - close(sd); - return 2; - } - } - } + do_write(STDOUT_FILENO, buf, (size_t) read_size); } }