From 0493ba853c8fa2b9790cf728c6677c49a417c494 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Sat, 1 Oct 2011 22:18:25 +0200 Subject: [PATCH] Emulate O_CLOEXEC on systems that don't support it --- cmake/ConkyPlatformChecks.cmake | 3 +++ cmake/config.h.in | 3 +++ src/c++wrap.cc | 34 ++++++++++++++++++++++++++++++++- src/c++wrap.hh | 4 ++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/cmake/ConkyPlatformChecks.cmake b/cmake/ConkyPlatformChecks.cmake index 959555fd..5dd220e4 100644 --- a/cmake/ConkyPlatformChecks.cmake +++ b/cmake/ConkyPlatformChecks.cmake @@ -34,6 +34,9 @@ check_include_files(dirent.h HAVE_DIRENT_H) # Check for some functions check_function_exists(strndup HAVE_STRNDUP) +check_symbol_exists(pipe2 "unistd.h" HAVE_PIPE2) +check_symbol_exists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC) + AC_SEARCH_LIBS(clock_gettime "time.h" CLOCK_GETTIME_LIB "rt") if(NOT CLOCK_GETTIME_LIB) message(FATAL_ERROR "clock_gettime not found.") diff --git a/cmake/config.h.in b/cmake/config.h.in index f946aecf..9a91a860 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -33,6 +33,9 @@ #cmakedefine HAVE_FOPENCOOKIE 1 #cmakedefine HAVE_FUNOPEN 1 +#cmakedefine HAVE_PIPE2 1 +#cmakedefine HAVE_O_CLOEXEC 1 + #cmakedefine BUILD_X11 1 #cmakedefine OWN_WINDOW 1 diff --git a/src/c++wrap.cc b/src/c++wrap.cc index 6e777392..b8de2910 100644 --- a/src/c++wrap.cc +++ b/src/c++wrap.cc @@ -27,6 +27,38 @@ #include +#if !defined(HAVE_PIPE2) || !defined(HAVE_O_CLOEXEC) +#include + +namespace { + int pipe2_emulate(int pipefd[2], int flags) + { + if(pipe(pipefd) == -1) + return -1; + + if(flags & O_CLOEXEC) { + // we emulate O_CLOEXEC if the system does not have it + // not very thread-safe, but at least it works + + for(int i = 0; i < 2; ++i) { + int r = fcntl(pipefd[i], F_GETFD); + if(r == -1) + return -1; + + if(fcntl(pipefd[i], F_SETFD, r | FD_CLOEXEC) == -1) + return -1; + } + } + + return 0; + } + + int (* const pipe2_ptr)(int[2], int) = &pipe2_emulate; +} +#else + int (* const pipe2_ptr)(int[2], int) = &pipe2; +#endif + std::string strerror_r(int errnum) { char buf[100]; @@ -36,7 +68,7 @@ std::string strerror_r(int errnum) std::pair pipe2(int flags) { int fd[2]; - if(pipe2(fd, flags) == -1) + if(pipe2_ptr(fd, flags) == -1) throw errno_error("pipe2"); else return std::pair(fd[0], fd[1]); diff --git a/src/c++wrap.hh b/src/c++wrap.hh index 6b93c1a6..fc4c9e76 100644 --- a/src/c++wrap.hh +++ b/src/c++wrap.hh @@ -24,7 +24,11 @@ #ifndef CPPWRAP_HH #define CPPWRAP_HH +#ifdef HAVE_O_CLOEXEC #include +#else +enum { O_CLOEXEC = 02000000 }; +#endif #include #include