about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorDmitry Podgorny <pasis.ua@gmail.com>2019-09-12 08:49:30 +0000
committerDmitry Podgorny <pasis.ua@gmail.com>2019-09-13 11:48:31 +0000
commit3ecb5424ae417ff3b2b6fa379e76b85b5f68e94b (patch)
tree5e4f0170c2db5e8787c44e2871d0928413eac269 /src
parent000650a9084487cfc818219e54f2a793a2ad0774 (diff)
downloadprofani-tty-3ecb5424ae417ff3b2b6fa379e76b85b5f68e94b.tar.gz
log: set nonblocking mode for stderr
Glib can print error messages to stderr and blocking write freezes
Profanity if the buffer is full. Move stderr to nonblocking mode
in hope that glib will skip printing on EWOULDBLOCK error. In this
case we lose some error messages, but Profanity continues working.
Diffstat (limited to 'src')
-rw-r--r--src/log.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/log.c b/src/log.c
index c1c46a75..932c402d 100644
--- a/src/log.c
+++ b/src/log.c
@@ -790,26 +790,36 @@ log_stderr_handler(void)
     }
 }
 
+static int log_stderr_nonblock_set(int fd)
+{
+    int rc;
+
+    rc = fcntl(fd, F_GETFL);
+    if (rc >= 0)
+        rc = fcntl(fd, F_SETFL, rc | O_NONBLOCK);
+
+    return rc;
+}
+
 void
 log_stderr_init(log_level_t level)
 {
     int rc;
-    int flags;
 
     rc = pipe(stderr_pipe);
     if (rc != 0)
         goto err;
 
-    flags = fcntl(stderr_pipe[0], F_GETFL);
-    rc = fcntl(stderr_pipe[0], F_SETFL, flags | O_NONBLOCK);
-    if (rc != 0)
-        goto err_close;
-
     close(STDERR_FILENO);
     rc = dup2(stderr_pipe[1], STDERR_FILENO);
     if (rc < 0)
         goto err_close;
 
+    rc = log_stderr_nonblock_set(stderr_pipe[0])
+      ?: log_stderr_nonblock_set(stderr_pipe[1]);
+    if (rc != 0)
+        goto err_close;
+
     stderr_buf = malloc(STDERR_BUFSIZE);
     stderr_msg = g_string_sized_new(STDERR_BUFSIZE);
     stderr_level = level;