diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build index 06685702e..114de49da 100644 --- a/docs/reference/glib/meson.build +++ b/docs/reference/glib/meson.build @@ -38,6 +38,7 @@ if get_option('gtk_doc') 'gutilsprivate.h', 'gvalgrind.h', 'dirent.h', + 'glib-unixprivate.h', 'glib-visibility.h', 'gmodule-visibility.h', ] diff --git a/glib/glib-unix.c b/glib/glib-unix.c index bc152d766..1c9f12599 100644 --- a/glib/glib-unix.c +++ b/glib/glib-unix.c @@ -23,12 +23,8 @@ #include "config.h" -/* To make bionic export pipe2() */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif - #include "glib-unix.h" +#include "glib-unixprivate.h" #include "gmain-internal.h" #include @@ -94,48 +90,13 @@ g_unix_open_pipe (int *fds, int flags, GError **error) { - int ecode; - /* We only support FD_CLOEXEC */ g_return_val_if_fail ((flags & (FD_CLOEXEC)) == flags, FALSE); -#ifdef HAVE_PIPE2 - { - int pipe2_flags = 0; - if (flags & FD_CLOEXEC) - pipe2_flags |= O_CLOEXEC; - /* Atomic */ - ecode = pipe2 (fds, pipe2_flags); - if (ecode == -1 && errno != ENOSYS) - return 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 */ - } -#endif - ecode = pipe (fds); - if (ecode == -1) + if (!g_unix_open_pipe_internal (fds, + (flags & FD_CLOEXEC) != 0)) return g_unix_set_error_from_errno (error, errno); - if (flags == 0) - return TRUE; - - ecode = fcntl (fds[0], F_SETFD, flags); - if (ecode == -1) - { - int saved_errno = errno; - close (fds[0]); - close (fds[1]); - return g_unix_set_error_from_errno (error, saved_errno); - } - ecode = fcntl (fds[1], F_SETFD, flags); - if (ecode == -1) - { - int saved_errno = errno; - close (fds[0]); - close (fds[1]); - return g_unix_set_error_from_errno (error, saved_errno); - } return TRUE; } diff --git a/glib/glib-unixprivate.h b/glib/glib-unixprivate.h new file mode 100644 index 000000000..d4c64bd1e --- /dev/null +++ b/glib/glib-unixprivate.h @@ -0,0 +1,87 @@ +/* glib-unixprivate.h - Unix specific integration private functions + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef __G_UNIXPRIVATE_H__ +#define __G_UNIXPRIVATE_H__ + +#include "config.h" + +#ifndef G_OS_UNIX +#error "This header may only be used on UNIX" +#endif + +/* To make bionic export pipe2() */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include "gmacros.h" +#include "gtypes.h" + +#include +#include +#include + +G_BEGIN_DECLS + +static inline gboolean +g_unix_open_pipe_internal (int *fds, + gboolean close_on_exec) + { +#ifdef HAVE_PIPE2 + do + { + int ecode; + + /* Atomic */ + ecode = pipe2 (fds, close_on_exec ? O_CLOEXEC : 0); + if (ecode == -1 && errno != ENOSYS) + return FALSE; + else if (ecode == 0) + return TRUE; + /* Fall through on -ENOSYS, we must be running on an old kernel */ + } + while (FALSE); +#endif + + if (pipe (fds) == -1) + return FALSE; + + if (!close_on_exec) + return TRUE; + + if (fcntl (fds[0], F_SETFD, FD_CLOEXEC) == -1 || + fcntl (fds[1], F_SETFD, FD_CLOEXEC) == -1) + { + int saved_errno = errno; + + close (fds[0]); + close (fds[1]); + fds[0] = -1; + fds[1] = -1; + + errno = saved_errno; + return FALSE; + } + + return TRUE; +} + +G_END_DECLS + +#endif /* __G_UNIXPRIVATE_H__ */ diff --git a/glib/meson.build b/glib/meson.build index 75b3b4018..da76fc005 100644 --- a/glib/meson.build +++ b/glib/meson.build @@ -365,7 +365,7 @@ if host_system == 'windows' glib_sources += files('dirent/wdirent.c') endif else - glib_sources += files('glib-unix.c', 'gspawn.c', 'giounix.c') + glib_sources += files('glib-unix.c', 'glib-unixprivate.h', 'gspawn.c', 'giounix.c') platform_deps = [] endif