mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
tools/libxs: Fix CLOEXEC handling in xs_fileno()
xs_fileno() opens a pipe on first use to communicate between the watch thread and the main thread. Nothing ever sets CLOEXEC on the file descriptors. Check for the availability of the pipe2() function with configure. Despite starting life as Linux-only, FreeBSD and NetBSD have gained it. When pipe2() isn't available, try our best with pipe() and set_cloexec(). Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Juergen Gross <jgross@suse.com> Acked-by: Anthony PERARD <anthony.perard@vates.tech>
This commit is contained in:
1 parent
1957dd6aff
commit
a2ff677852
4 files changed
+32
-1
No files matched your search
@@ -39,6 +39,9 @@
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `pipe2' function. */
|
||||
#undef HAVE_PIPE2
|
||||
|
||||
/* pygrub enabled */
|
||||
#undef HAVE_PYGRUB
|
||||
|
||||
|
||||
Vendored
+12
@@ -9751,6 +9751,18 @@ if test "$ax_found" = "0"; then :
|
||||
fi
|
||||
|
||||
|
||||
for ac_func in pipe2
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
|
||||
if test "x$ac_cv_func_pipe2" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_PIPE2 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
# tests run on this system so they can be shared between configure
|
||||
|
||||
@@ -543,4 +543,6 @@ AS_IF([test "x$pvshim" = "xy"], [
|
||||
|
||||
AX_FIND_HEADER([INCLUDE_ENDIAN_H], [endian.h sys/endian.h])
|
||||
|
||||
AC_CHECK_FUNCS([pipe2])
|
||||
|
||||
AC_OUTPUT()
|
||||
+15
-1
@@ -190,13 +190,27 @@ static bool set_cloexec(int fd)
|
||||
return fcntl(fd, flags | FD_CLOEXEC) >= 0;
|
||||
}
|
||||
|
||||
static int pipe_cloexec(int fds[2])
|
||||
{
|
||||
#if HAVE_PIPE2
|
||||
return pipe2(fds, O_CLOEXEC);
|
||||
#else
|
||||
if (pipe(fds) < 0)
|
||||
return -1;
|
||||
/* Best effort to set CLOEXEC. Racy. */
|
||||
set_cloexec(fds[0]);
|
||||
set_cloexec(fds[1]);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int xs_fileno(struct xs_handle *h)
|
||||
{
|
||||
char c = 0;
|
||||
|
||||
mutex_lock(&h->watch_mutex);
|
||||
|
||||
if ((h->watch_pipe[0] == -1) && (pipe(h->watch_pipe) != -1)) {
|
||||
if ((h->watch_pipe[0] == -1) && (pipe_cloexec(h->watch_pipe) != -1)) {
|
||||
/* Kick things off if the watch list is already non-empty. */
|
||||
if (!XEN_TAILQ_EMPTY(&h->watch_list))
|
||||
while (write(h->watch_pipe[1], &c, 1) != 1)
|
||||
|
||||