diff --git a/tools/config.h.in b/tools/config.h.in index 0bb2fe08a1..50ad60fcb0 100644 --- a/tools/config.h.in +++ b/tools/config.h.in @@ -39,6 +39,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `pipe2' function. */ +#undef HAVE_PIPE2 + /* pygrub enabled */ #undef HAVE_PYGRUB diff --git a/tools/configure b/tools/configure index 459bfb5652..a6b43bfc60 100755 --- a/tools/configure +++ b/tools/configure @@ -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 diff --git a/tools/configure.ac b/tools/configure.ac index 851887080c..ac0fdc4314 100644 --- a/tools/configure.ac +++ b/tools/configure.ac @@ -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() diff --git a/tools/libs/store/xs.c b/tools/libs/store/xs.c index 11a766c508..c8845b69e2 100644 --- a/tools/libs/store/xs.c +++ b/tools/libs/store/xs.c @@ -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)