]> git.sur5r.net Git - i3/i3/commitdiff
Add a safe wrapper for write and fix some warnings 1575/head
authorhwangcc <hwangcc@csie.nctu.edu.tw>
Tue, 24 Mar 2015 12:57:06 +0000 (20:57 +0800)
committerhwangcc <hwangcc@csie.nctu.edu.tw>
Sun, 29 Mar 2015 02:22:34 +0000 (10:22 +0800)
1. Add a function writeall and make swrite wrap that function. Use either writeall or swrite, depending on whether we want to exit on errors or not.
2. Fix warnings when compiling with a higher optimisation level.
(CFLAGS ?= -pipe -O3 -march=native -mtune=native -freorder-blocks-and-partition)

Signed-off-by: hwangcc <hwangcc@csie.nctu.edu.tw>
12 files changed:
i3-dump-log/main.c
i3-nagbar/main.c
i3bar/src/child.c
i3bar/src/ipc.c
include/libi3.h
libi3/ipc_send_message.c
libi3/safewrappers.c
src/click.c
src/config_parser.c
src/load_layout.c
src/sighandler.c
src/util.c

index 86b39338eae682f927bf93236658719bb03899cc..1b0d593c5e1c7322c11c210e739adfade5f50030 100644 (file)
@@ -43,8 +43,7 @@ static int check_for_wrap(void) {
      * of the log. */
     wrap_count = header->wrap_count;
     const int len = (logbuffer + header->offset_last_wrap) - walk;
-    if (write(STDOUT_FILENO, walk, len) != len)
-        err(EXIT_FAILURE, "write()");
+    swrite(STDOUT_FILENO, walk, len);
     walk = logbuffer + sizeof(i3_shmlog_header);
     return 1;
 }
@@ -52,12 +51,8 @@ static int check_for_wrap(void) {
 static void print_till_end(void) {
     check_for_wrap();
     const int len = (logbuffer + header->offset_next_write) - walk;
-    const int n = write(STDOUT_FILENO, walk, len);
-    if (len != n)
-        err(EXIT_FAILURE, "write()");
-    if (n > 0) {
-        walk += n;
-    }
+    swrite(STDOUT_FILENO, walk, len);
+    walk += len;
 }
 
 int main(int argc, char *argv[]) {
index b501ff6a304536437e02525d9f4846bd860922a8..91de317fb67084e8b9dfa3dae2de2f2b4238ccd3 100644 (file)
@@ -164,7 +164,9 @@ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_eve
     char *link_path;
     char *exe_path = get_exe_path(argv0);
     sasprintf(&link_path, "%s.nagbar_cmd", script_path);
-    symlink(exe_path, link_path);
+    if (symlink(exe_path, link_path) == -1) {
+        err(EXIT_FAILURE, "Failed to symlink %s to %s", link_path, exe_path);
+    }
 
     char *terminal_cmd;
     sasprintf(&terminal_cmd, "i3-sensible-terminal -e %s", link_path);
index 402e6351bd3fd085134278c066b4a50d7ddf9307..818ce7841e88969d3a58b34ef97c1fb55e2d95fb 100644 (file)
@@ -103,7 +103,7 @@ __attribute__((format(printf, 1, 2))) static void set_statusline_error(const cha
     char *message;
     va_list args;
     va_start(args, format);
-    vasprintf(&message, format, args);
+    (void)vasprintf(&message, format, args);
 
     struct status_block *err_block = scalloc(sizeof(struct status_block));
     err_block->full_text = i3string_from_utf8("Error: ");
@@ -455,11 +455,22 @@ void child_write_output(void) {
     if (child.click_events) {
         const unsigned char *output;
         size_t size;
+        ssize_t n;
 
         yajl_gen_get_buf(gen, &output, &size);
-        write(child_stdin, output, size);
-        write(child_stdin, "\n", 1);
+
+        n = writeall(child_stdin, output, size);
+        if (n != -1)
+            n = writeall(child_stdin, "\n", 1);
+
         yajl_gen_clear(gen);
+
+        if (n == -1) {
+            child.click_events = false;
+            kill_child();
+            set_statusline_error("child_write_output failed");
+            draw_bars(false);
+        }
     }
 }
 
index c6e67eb600dedc8a8e710b7475b4b2a4400cc9e8..edc9d73f0bf7e9719d1836e82cb31daa51607c3c 100644 (file)
@@ -296,18 +296,7 @@ int i3_send_msg(uint32_t type, const char *payload) {
     if (payload != NULL)
         strncpy(walk, payload, len);
 
-    uint32_t written = 0;
-
-    while (to_write > 0) {
-        int n = write(i3_connection->fd, buffer + written, to_write);
-        if (n == -1) {
-            ELOG("write() failed: %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-
-        to_write -= n;
-        written += n;
-    }
+    swrite(i3_connection->fd, buffer, to_write);
 
     FREE(buffer);
 
index c8d2e9561ad7b334cf421e70eef5fc1ce9cd3203..3a1258273b912847ccc429adafbaba28b86cbd82 100644 (file)
@@ -134,6 +134,20 @@ char *sstrdup(const char *str);
  */
 int sasprintf(char **strp, const char *fmt, ...);
 
+/**
+ * Wrapper around correct write which returns -1 (meaning that
+ * write failed) or count (meaning that all bytes were written)
+ *
+ */
+ssize_t writeall(int fd, const void *buf, size_t count);
+
+/**
+ * Safe-wrapper around writeall which exits if it returns -1 (meaning that
+ * write failed)
+ *
+ */
+ssize_t swrite(int fd, const void *buf, size_t count);
+
 /**
  * Build an i3String from an UTF-8 encoded string.
  * Returns the newly-allocated i3String.
index 28cb8359207e128b648a664824b6dcc59950e07e..80709ed3b255c638933e0644841accecc7eb4318 100644 (file)
@@ -32,33 +32,11 @@ int ipc_send_message(int sockfd, const uint32_t message_size,
         .size = message_size,
         .type = message_type};
 
-    size_t sent_bytes = 0;
-    int n = 0;
+    if (writeall(sockfd, ((void *)&header), sizeof(i3_ipc_header_t)) == -1)
+        return -1;
 
-    /* This first loop is basically unnecessary. No operating system has
-     * buffers which cannot fit 14 bytes into them, so the write() will only be
-     * called once. */
-    while (sent_bytes < sizeof(i3_ipc_header_t)) {
-        if ((n = write(sockfd, ((void *)&header) + sent_bytes, sizeof(i3_ipc_header_t) - sent_bytes)) == -1) {
-            if (errno == EAGAIN)
-                continue;
-            return -1;
-        }
-
-        sent_bytes += n;
-    }
-
-    sent_bytes = 0;
-
-    while (sent_bytes < message_size) {
-        if ((n = write(sockfd, payload + sent_bytes, message_size - sent_bytes)) == -1) {
-            if (errno == EAGAIN)
-                continue;
-            return -1;
-        }
-
-        sent_bytes += n;
-    }
+    if (writeall(sockfd, payload, message_size) == -1)
+        return -1;
 
     return 0;
 }
index cf634ad43b8d0f9248f60f351f506908b3507d59..6acf3109c553876e1fb7782bb011b0b435ace49a 100644 (file)
@@ -8,8 +8,10 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <unistd.h>
 #include <stdio.h>
 #include <err.h>
+#include <errno.h>
 
 #include "libi3.h"
 
@@ -56,3 +58,30 @@ int sasprintf(char **strp, const char *fmt, ...) {
     va_end(args);
     return result;
 }
+
+ssize_t writeall(int fd, const void *buf, size_t count) {
+    int written = 0;
+    ssize_t n = 0;
+
+    while (written < count) {
+        n = write(fd, buf + written, count - written);
+        if (n == -1) {
+            if (errno == EINTR || errno == EAGAIN)
+                continue;
+            return n;
+        }
+        written += n;
+    }
+
+    return written;
+}
+
+ssize_t swrite(int fd, const void *buf, size_t count) {
+    ssize_t n;
+
+    n = writeall(fd, buf, count);
+    if (n == -1)
+        err(EXIT_FAILURE, "Failed to write %d", fd);
+    else
+        return n;
+}
index 55e7147c557237c6cef5d7a1ff10978c86bc154b..10abc0570c3140201a1d46cae53421f3f243d16d 100644 (file)
@@ -46,6 +46,9 @@ static bool tiling_resize_for_border(Con *con, border_t border, xcb_button_press
         case BORDER_BOTTOM:
             search_direction = D_DOWN;
             break;
+        default:
+            assert(false);
+            break;
     }
 
     bool res = resize_find_tiling_participants(&first, &second, search_direction);
index b229b445ba24ae71358cfcc891e4fafa06d40490..eef03cae238e0cf7455fd64ca1b18658e47d977f 100644 (file)
@@ -778,14 +778,9 @@ static char *migrate_config(char *input, off_t size) {
 
     /* write the whole config file to the pipe, the script will read everything
      * immediately */
-    int written = 0;
-    int ret;
-    while (written < size) {
-        if ((ret = write(writepipe[1], input + written, size - written)) < 0) {
-            warn("Could not write to pipe");
-            return NULL;
-        }
-        written += ret;
+    if (writeall(writepipe[1], input, size) == -1) {
+        warn("Could not write to pipe");
+        return NULL;
     }
     close(writepipe[1]);
 
@@ -795,7 +790,7 @@ static char *migrate_config(char *input, off_t size) {
     /* read the script’s output */
     int conv_size = 65535;
     char *converted = malloc(conv_size);
-    int read_bytes = 0;
+    int read_bytes = 0, ret;
     do {
         if (read_bytes == conv_size) {
             conv_size += 65535;
index ccd71c3736db139623305628fdc40694847ba4b1..c4d39fcee57fa569be1ac07fced152b57b56b55f 100644 (file)
@@ -105,7 +105,7 @@ static int json_end_map(void *ctx) {
             int cnt = 1;
             while (workspace != NULL) {
                 FREE(json_node->name);
-                asprintf(&(json_node->name), "%s_%d", base, cnt++);
+                sasprintf(&(json_node->name), "%s_%d", base, cnt++);
                 workspace = NULL;
                 TAILQ_FOREACH(output, &(croot->nodes_head), nodes)
                 GREP_FIRST(workspace, output_get_content(output), !strcasecmp(child->name, json_node->name));
index 546b73d91104d2e19941b0f1f370ecc616dd8054..e971f6bdd18c8f8f3b2e38b0aeb165d50a6bb574 100644 (file)
@@ -70,8 +70,14 @@ static int backtrace(void) {
         int stdin_pipe[2],
             stdout_pipe[2];
 
-        pipe(stdin_pipe);
-        pipe(stdout_pipe);
+        if (pipe(stdin_pipe) == -1) {
+            ELOG("Failed to init stdin_pipe\n");
+            return -1;
+        }
+        if (pipe(stdout_pipe) == -1) {
+            ELOG("Failed to init stdout_pipe\n");
+            return -1;
+        }
 
         /* close standard streams in case i3 is started from a terminal; gdb
          * needs to run without controlling terminal for it to work properly in
index c5c22ba8c8c1f68351350d39db1a543cab6cd3f9..5760ae72588f52afc5cd6caf617a4b184e344ab9 100644 (file)
@@ -265,25 +265,13 @@ char *store_restart_layout(void) {
         return NULL;
     }
 
-    size_t written = 0;
-    while (written < length) {
-        int n = write(fd, payload + written, length - written);
-        /* TODO: correct error-handling */
-        if (n == -1) {
-            perror("write()");
-            free(filename);
-            close(fd);
-            return NULL;
-        }
-        if (n == 0) {
-            DLOG("write == 0?\n");
-            free(filename);
-            close(fd);
-            return NULL;
-        }
-        written += n;
-        DLOG("written: %zd of %zd\n", written, length);
+    if (writeall(fd, payload, length) == -1) {
+        ELOG("Could not write restart layout to \"%s\", layout will be lost: %s\n", filename, strerror(errno));
+        free(filename);
+        close(fd);
+        return NULL;
     }
+
     close(fd);
 
     if (length > 0) {