aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/spawn.c
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-10-24 23:17:37 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-10-24 23:40:31 +0300
commit0f740ee2f3d750fc5c25e20492f381a21ed53fa4 (patch)
tree0dff81f794cc47ab3b83ba419157764f4a055388 /src/spawn.c
parente69e7c95bc68a90eadfbd963359737dce43d65f2 (diff)
downloadsciteco-0f740ee2f3d750fc5c25e20492f381a21ed53fa4.tar.gz
<EC>: fixed hangs on UNIX
* detected under FreeBSD * It turns out that it's unsafe to make the GIOChannel blocking even though the application has already terminated and the channel should be closed automatically. The channel does not report EOF, but instead we have to look for zero reads - in complete contrast to the behavior on Windows. Apparently, it's very tricky to use this API correctly (ie. it sucks). * fixup to e9bef20a8ad89d304fe3e8fafa00056d22de2326
Diffstat (limited to 'src/spawn.c')
-rw-r--r--src/spawn.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/spawn.c b/src/spawn.c
index 99eb6e3..06fdf95 100644
--- a/src/spawn.c
+++ b/src/spawn.c
@@ -641,16 +641,26 @@ teco_spawn_child_watch_cb(GPid pid, gint status, gpointer data)
/*
* There might still be data to read from stdout,
* but we cannot count on the stdout watcher to be ever called again.
- * Moreover, reads may return 0 even if the socket is blocking.
- *
+ */
+#ifdef G_OS_WIN32
+ /*
* FIXME: This is not done after interruptions since it will hang at least on Windows.
- * This shouldn't happen since the IO channel is non-blocking.
+ * This shouldn't happen at least if the IO channel is non-blocking.
+ * Moreover, reads may return 0 even if the socket is blocking.
*/
if (!teco_spawn_ctx.interrupted) {
g_io_channel_set_flags(teco_spawn_ctx.stdout_reader.gio.channel, 0, NULL);
teco_spawn_stdout_watch_cb(teco_spawn_ctx.stdout_reader.gio.channel,
G_IO_IN, GINT_TO_POINTER(TRUE));
}
+#else /* !G_OS_WIN32 */
+ /*
+ * On UNIX on the other hand, we apparently never receive G_IO_STATUS_EOF
+ * and MUST react to a read length of 0.
+ */
+ teco_spawn_stdout_watch_cb(teco_spawn_ctx.stdout_reader.gio.channel,
+ G_IO_IN, GINT_TO_POINTER(FALSE));
+#endif
/*
* teco_spawn_stdout_watch_cb() might have set the error.