summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Fleury <emmanuel.fleury@gmail.com>2022-08-01 19:05:14 +0200
committerEmmanuel Fleury <emmanuel.fleury@gmail.com>2022-09-14 08:50:40 +0200
commitd9ba6150909818beb05573f54f26232063492c5b (patch)
tree27d5dd95c99e843061983f8bd9a93cc25146cda9
parent985ffc3b4e05a1093c6a729e7eff34bcca67819e (diff)
downloadglib-d9ba6150909818beb05573f54f26232063492c5b.tar.gz
Handling collision between standard i/o file descriptors and newly created ones
Though unlikely to happen, it may happen that newly created file descriptor take the value 0 (stdin), 1 (stdout) or 2 (stderr) if one of the standard ones have been dismissed in between. So, it may confuse the program if it is unaware of this change. The point of this patch is to avoid a reasign of standard file descriptors on newly created ones. Closes issue #16
-rw-r--r--glib/glib-unix.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/glib/glib-unix.c b/glib/glib-unix.c
index d2dea10ef..d67b8a357 100644
--- a/glib/glib-unix.c
+++ b/glib/glib-unix.c
@@ -108,6 +108,17 @@ g_unix_open_pipe (int *fds,
ecode = pipe2 (fds, pipe2_flags);
if (ecode == -1 && errno != ENOSYS)
return g_unix_set_error_from_errno (error, errno);
+ /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
+ else if (fds[0] < 3 || fds[1] < 3)
+ {
+ int old_fds[2] = { fds[0], fds[1] };
+ gboolean result = g_unix_open_pipe (fds, flags, error);
+ close (old_fds[0]);
+ close (old_fds[1]);
+
+ if (!result)
+ g_unix_set_error_from_errno (error, errno);
+ }
else if (ecode == 0)
return TRUE;
/* Fall through on -ENOSYS, we must be running on an old kernel */
@@ -116,6 +127,19 @@ g_unix_open_pipe (int *fds,
ecode = pipe (fds);
if (ecode == -1)
return g_unix_set_error_from_errno (error, errno);
+ /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
+ else if (fds[0] < 3 || fds[1] < 3)
+ {
+ int old_fds[2] = { fds[0], fds[1] };
+ gboolean result = g_unix_open_pipe (fds, flags, error);
+ close (old_fds[0]);
+ close (old_fds[1]);
+
+ if (!result)
+ g_unix_set_error_from_errno (error, errno);
+
+ return result;
+ }
if (flags == 0)
return TRUE;