diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/db/update/InotifySource.cxx | 10 | ||||
-rw-r--r-- | src/db/update/InotifySource.hxx | 4 | ||||
-rw-r--r-- | src/fs/io/FileReader.cxx | 19 | ||||
-rw-r--r-- | src/fs/io/FileReader.hxx | 8 | ||||
-rw-r--r-- | src/input/plugins/FileInputPlugin.cxx | 26 | ||||
-rw-r--r-- | src/system/EventFD.cxx | 21 | ||||
-rw-r--r-- | src/system/EventFD.hxx | 9 | ||||
-rw-r--r-- | src/system/FileDescriptor.cxx | 219 | ||||
-rw-r--r-- | src/system/FileDescriptor.hxx | 171 | ||||
-rw-r--r-- | src/system/SignalFD.cxx | 14 | ||||
-rw-r--r-- | src/system/SignalFD.hxx | 5 | ||||
-rw-r--r-- | src/system/fd_util.c | 36 | ||||
-rw-r--r-- | src/system/fd_util.h | 22 |
13 files changed, 441 insertions, 123 deletions
diff --git a/src/db/update/InotifySource.cxx b/src/db/update/InotifySource.cxx index d0ac5b779..b084dd60a 100644 --- a/src/db/update/InotifySource.cxx +++ b/src/db/update/InotifySource.cxx @@ -21,7 +21,7 @@ #include "InotifySource.hxx" #include "InotifyDomain.hxx" #include "util/Error.hxx" -#include "system/fd_util.h" +#include "system/FileDescriptor.hxx" #include "system/FatalError.hxx" #include "Log.hxx" @@ -72,8 +72,8 @@ InotifySource::OnSocketReady(gcc_unused unsigned flags) inline InotifySource::InotifySource(EventLoop &_loop, mpd_inotify_callback_t _callback, void *_ctx, - int _fd) - :SocketMonitor(_fd, _loop), + FileDescriptor _fd) + :SocketMonitor(_fd.Get(), _loop), callback(_callback), callback_ctx(_ctx) { ScheduleRead(); @@ -85,8 +85,8 @@ InotifySource::Create(EventLoop &loop, mpd_inotify_callback_t callback, void *callback_ctx, Error &error) { - int fd = inotify_init_cloexec(); - if (fd < 0) { + FileDescriptor fd; + if (!fd.CreateInotify()) { error.SetErrno("inotify_init() has failed"); return nullptr; } diff --git a/src/db/update/InotifySource.hxx b/src/db/update/InotifySource.hxx index 0eb69719b..e662e5a04 100644 --- a/src/db/update/InotifySource.hxx +++ b/src/db/update/InotifySource.hxx @@ -24,6 +24,7 @@ #include "Compiler.h" class Error; +class FileDescriptor; typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask, const char *name, void *ctx); @@ -33,7 +34,8 @@ class InotifySource final : private SocketMonitor { void *callback_ctx; InotifySource(EventLoop &_loop, - mpd_inotify_callback_t callback, void *ctx, int fd); + mpd_inotify_callback_t callback, void *ctx, + FileDescriptor fd); public: ~InotifySource() { diff --git a/src/fs/io/FileReader.cxx b/src/fs/io/FileReader.cxx index e4198b71a..474431ef8 100644 --- a/src/fs/io/FileReader.cxx +++ b/src/fs/io/FileReader.cxx @@ -75,17 +75,11 @@ FileReader::Close() #else -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> - FileReader::FileReader(Path _path, Error &error) - :path(_path), - fd(OpenFile(path, - O_RDONLY, - 0)) + :path(_path) { - if (fd < 0) + fd.OpenReadOnly(path.c_str()); + if (!fd.IsDefined()) error.FormatErrno("Failed to open %s", path.c_str()); } @@ -94,7 +88,7 @@ FileReader::Read(void *data, size_t size, Error &error) { assert(IsDefined()); - ssize_t nbytes = read(fd, data, size); + ssize_t nbytes = fd.Read(data, size); if (nbytes < 0) { error.FormatErrno("Failed to read from %s", path.c_str()); nbytes = 0; @@ -108,7 +102,7 @@ FileReader::Seek(off_t offset, Error &error) { assert(IsDefined()); - auto result = lseek(fd, offset, SEEK_SET); + auto result = fd.Seek(offset); const bool success = result >= 0; if (!success) error.SetErrno("Failed to seek"); @@ -121,8 +115,7 @@ FileReader::Close() { assert(IsDefined()); - close(fd); - fd = -1; + fd.Close(); } #endif diff --git a/src/fs/io/FileReader.hxx b/src/fs/io/FileReader.hxx index 9a1c17c6b..eb0646015 100644 --- a/src/fs/io/FileReader.hxx +++ b/src/fs/io/FileReader.hxx @@ -25,6 +25,10 @@ #include "fs/AllocatedPath.hxx" #include "Compiler.h" +#ifndef WIN32 +#include "system/FileDescriptor.hxx" +#endif + #include <assert.h> #ifdef WIN32 @@ -39,7 +43,7 @@ class FileReader final : public Reader { #ifdef WIN32 HANDLE handle; #else - int fd; + FileDescriptor fd; #endif public: @@ -55,7 +59,7 @@ public: #ifdef WIN32 return handle != INVALID_HANDLE_VALUE; #else - return fd >= 0; + return fd.IsDefined(); #endif } diff --git a/src/input/plugins/FileInputPlugin.cxx b/src/input/plugins/FileInputPlugin.cxx index bfee71cce..5f5c85c09 100644 --- a/src/input/plugins/FileInputPlugin.cxx +++ b/src/input/plugins/FileInputPlugin.cxx @@ -23,10 +23,8 @@ #include "../InputPlugin.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" -#include "fs/FileSystem.hxx" #include "fs/Path.hxx" -#include "system/fd_util.h" -#include "open.h" +#include "system/FileDescriptor.hxx" #include <sys/stat.h> #include <unistd.h> @@ -35,10 +33,10 @@ static constexpr Domain file_domain("file"); class FileInputStream final : public InputStream { - const int fd; + FileDescriptor fd; public: - FileInputStream(const char *path, int _fd, off_t _size, + FileInputStream(const char *path, FileDescriptor _fd, off_t _size, Mutex &_mutex, Cond &_cond) :InputStream(path, _mutex, _cond), fd(_fd) { @@ -48,7 +46,7 @@ public: } ~FileInputStream() { - close(fd); + fd.Close(); } /* virtual methods from InputStream */ @@ -66,29 +64,29 @@ OpenFileInputStream(Path path, Mutex &mutex, Cond &cond, Error &error) { - const int fd = OpenFile(path, O_RDONLY|O_BINARY, 0); - if (fd < 0) { + FileDescriptor fd; + if (!fd.OpenReadOnly(path.c_str())) { error.FormatErrno("Failed to open \"%s\"", path.c_str()); return nullptr; } struct stat st; - if (fstat(fd, &st) < 0) { + if (fstat(fd.Get(), &st) < 0) { error.FormatErrno("Failed to stat \"%s\"", path.c_str()); - close(fd); + fd.Close(); return nullptr; } if (!S_ISREG(st.st_mode)) { error.Format(file_domain, "Not a regular file: %s", path.c_str()); - close(fd); + fd.Close(); return nullptr; } #ifdef POSIX_FADV_SEQUENTIAL - posix_fadvise(fd, (off_t)0, st.st_size, POSIX_FADV_SEQUENTIAL); + posix_fadvise(fd.Get(), (off_t)0, st.st_size, POSIX_FADV_SEQUENTIAL); #endif return new FileInputStream(path.c_str(), fd, st.st_size, mutex, cond); @@ -107,7 +105,7 @@ input_file_open(gcc_unused const char *filename, bool FileInputStream::Seek(offset_type new_offset, Error &error) { - auto result = lseek(fd, (off_t)new_offset, SEEK_SET); + auto result = fd.Seek((off_t)new_offset); if (result < 0) { error.SetErrno("Failed to seek"); return false; @@ -120,7 +118,7 @@ FileInputStream::Seek(offset_type new_offset, Error &error) size_t FileInputStream::Read(void *ptr, size_t read_size, Error &error) { - ssize_t nbytes = read(fd, ptr, read_size); + ssize_t nbytes = fd.Read(ptr, read_size); if (nbytes < 0) { error.SetErrno("Failed to read"); return 0; diff --git a/src/system/EventFD.cxx b/src/system/EventFD.cxx index 2c1cef040..016dd372c 100644 --- a/src/system/EventFD.cxx +++ b/src/system/EventFD.cxx @@ -20,46 +20,35 @@ #include "config.h" #ifdef USE_EVENTFD #include "EventFD.hxx" -#include "system/fd_util.h" #include "system/FatalError.hxx" #include "Compiler.h" #include <assert.h> -#include <unistd.h> - #include <sys/eventfd.h> EventFD::EventFD() - :fd(eventfd_cloexec_nonblock(0, 0)) { - if (fd < 0) + if (!fd.CreateEventFD(0)) FatalSystemError("eventfd() failed"); } -EventFD::~EventFD() -{ - assert(fd >= 0); - - close(fd); -} - bool EventFD::Read() { - assert(fd >= 0); + assert(fd.IsDefined()); eventfd_t value; - return read(fd, &value, sizeof(value)) == (ssize_t)sizeof(value); + return fd.Read(&value, sizeof(value)) == (ssize_t)sizeof(value); } void EventFD::Write() { - assert(fd >= 0); + assert(fd.IsDefined()); static constexpr eventfd_t value = 1; gcc_unused ssize_t nbytes = - write(fd, &value, sizeof(value)); + fd.Write(&value, sizeof(value)); } #endif /* USE_EVENTFD */ diff --git a/src/system/EventFD.hxx b/src/system/EventFD.hxx index 654547078..616877f4a 100644 --- a/src/system/EventFD.hxx +++ b/src/system/EventFD.hxx @@ -21,6 +21,7 @@ #define MPD_EVENT_FD_HXX #include "check.h" +#include "FileDescriptor.hxx" /** * A class that wraps eventfd(). @@ -28,17 +29,19 @@ * Errors in the constructor are fatal. */ class EventFD { - int fd; + FileDescriptor fd; public: EventFD(); - ~EventFD(); + ~EventFD() { + fd.Close(); + } EventFD(const EventFD &other) = delete; EventFD &operator=(const EventFD &other) = delete; int Get() const { - return fd; + return fd.Get(); } /** diff --git a/src/system/FileDescriptor.cxx b/src/system/FileDescriptor.cxx new file mode 100644 index 000000000..946493329 --- /dev/null +++ b/src/system/FileDescriptor.cxx @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2012-2015 Max Kellermann <max@duempel.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FileDescriptor.hxx" + +#include <sys/stat.h> +#include <fcntl.h> + +#ifdef HAVE_POSIX +#include <poll.h> +#endif + +#ifdef USE_EVENTFD +#include <sys/eventfd.h> +#endif + +#ifdef USE_SIGNALFD +#include <sys/signalfd.h> +#endif + +#ifdef HAVE_INOTIFY_INIT +#include <sys/inotify.h> +#endif + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif + +bool +FileDescriptor::Open(const char *pathname, int flags) +{ + assert(!IsDefined()); + + fd = ::open(pathname, flags); + return IsDefined(); +} + +bool +FileDescriptor::OpenReadOnly(const char *pathname) +{ + return Open(pathname, O_RDONLY | O_NOCTTY | O_CLOEXEC); +} + +#ifdef HAVE_POSIX + +bool +FileDescriptor::OpenNonBlocking(const char *pathname) +{ + return Open(pathname, O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK); +} + +bool +FileDescriptor::CreatePipe(FileDescriptor &r, FileDescriptor &w) +{ + int fds[2]; + +#ifdef HAVE_PIPE2 + const int flags = O_CLOEXEC; + const int result = pipe2(fds, flags); +#else + const int result = pipe(fds); +#endif + + if (result < 0) + return false; + + r = FileDescriptor(fds[0]); + w = FileDescriptor(fds[1]); + return true; +} + +void +FileDescriptor::SetNonBlocking() +{ + assert(IsDefined()); + + int flags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); +} + +void +FileDescriptor::SetBlocking() +{ + assert(IsDefined()); + + int flags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); +} + +#endif + +#ifdef USE_EVENTFD + +bool +FileDescriptor::CreateEventFD(unsigned initval) +{ + assert(!IsDefined()); + + fd = ::eventfd(initval, EFD_NONBLOCK|EFD_CLOEXEC); + return fd >= 0; +} + +#endif + +#ifdef USE_SIGNALFD + +bool +FileDescriptor::CreateSignalFD(const sigset_t *mask) +{ + int new_fd = ::signalfd(fd, mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (new_fd < 0) + return false; + + fd = new_fd; + return true; +} + +#endif + +#ifdef HAVE_INOTIFY_INIT + +bool +FileDescriptor::CreateInotify() +{ +#ifdef HAVE_INOTIFY_INIT1 + int new_fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK); +#else + int new_fd = inotify_init(); +#endif + if (new_fd < 0) + return false; + +#ifndef HAVE_INOTIFY_INIT1 + SetNonBlocking(); +#endif + + fd = new_fd; + return true; +} + +#endif + +bool +FileDescriptor::Rewind() +{ + assert(IsDefined()); + + return lseek(fd, 0, SEEK_SET) == 0; +} + +off_t +FileDescriptor::GetSize() const +{ + struct stat st; + return ::fstat(fd, &st) >= 0 + ? (long)st.st_size + : -1; +} + +#ifdef HAVE_POSIX + +int +FileDescriptor::Poll(short events, int timeout) const +{ + assert(IsDefined()); + + struct pollfd pfd; + pfd.fd = fd; + pfd.events = events; + int result = poll(&pfd, 1, timeout); + return result > 0 + ? pfd.revents + : result; +} + +int +FileDescriptor::WaitReadable(int timeout) const +{ + return Poll(POLLIN, timeout); +} + +int +FileDescriptor::WaitWritable(int timeout) const +{ + return Poll(POLLOUT, timeout); +} + +#endif diff --git a/src/system/FileDescriptor.hxx b/src/system/FileDescriptor.hxx new file mode 100644 index 000000000..8db0dffdd --- /dev/null +++ b/src/system/FileDescriptor.hxx @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2012-2015 Max Kellermann <max@duempel.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FILE_DESCRIPTOR_HXX +#define FILE_DESCRIPTOR_HXX + +#include "check.h" +#include "Compiler.h" + +#include <assert.h> +#include <unistd.h> +#include <sys/types.h> + +#ifdef USE_SIGNALFD +#include <signal.h> +#endif + +/** + * An OO wrapper for a UNIX file descriptor. + * + * This class is unmanaged and trivial. + */ +class FileDescriptor { +protected: + int fd; + +public: + FileDescriptor() = default; + explicit constexpr FileDescriptor(int _fd):fd(_fd) {} + + constexpr bool operator==(FileDescriptor other) const { + return fd == other.fd; + } + + constexpr bool IsDefined() const { + return fd >= 0; + } + + /** + * Returns the file descriptor. This may only be called if + * IsDefined() returns true. + */ + constexpr int Get() const { + return fd; + } + + void Set(int _fd) { + fd = _fd; + } + + int Steal() { + assert(IsDefined()); + + int _fd = fd; + fd = -1; + return _fd; + } + + void SetUndefined() { + fd = -1; + } + + static constexpr FileDescriptor Undefined() { + return FileDescriptor(-1); + } + + bool Open(const char *pathname, int flags); + bool OpenReadOnly(const char *pathname); + +#ifdef HAVE_POSIX + bool OpenNonBlocking(const char *pathname); + + static bool CreatePipe(FileDescriptor &r, FileDescriptor &w); + + /** + * Enable non-blocking mode on this file descriptor. + */ + void SetNonBlocking(); + + /** + * Enable blocking mode on this file descriptor. + */ + void SetBlocking(); + + /** + * Duplicate the file descriptor onto the given file descriptor. + */ + bool Duplicate(int new_fd) const { + return ::dup2(Get(), new_fd) == 0; + } +#endif + +#ifdef USE_EVENTFD + bool CreateEventFD(unsigned initval=0); +#endif + +#ifdef USE_SIGNALFD + bool CreateSignalFD(const sigset_t *mask); +#endif + +#ifdef HAVE_INOTIFY_INIT + bool CreateInotify(); +#endif + + /** + * Close the file descriptor. It is legal to call it on an + * "undefined" object. After this call, IsDefined() is guaranteed + * to return false, and this object may be reused. + */ + void Close() { + ::close(Steal()); + } + + /** + * Rewind the pointer to the beginning of the file. + */ + bool Rewind(); + + off_t Seek(off_t offset) { + return lseek(Get(), offset, SEEK_SET); + } + + /** + * Returns the size of the file in bytes, or -1 on error. + */ + gcc_pure + off_t GetSize() const; + + ssize_t Read(void *buffer, size_t length) { + return ::read(fd, buffer, length); + } + + ssize_t Write(const void *buffer, size_t length) { + return ::write(fd, buffer, length); + } + +#ifdef HAVE_POSIX + int Poll(short events, int timeout) const; + + int WaitReadable(int timeout) const; + int WaitWritable(int timeout) const; +#endif +}; + +#endif diff --git a/src/system/SignalFD.cxx b/src/system/SignalFD.cxx index 92d2eec01..14193c893 100644 --- a/src/system/SignalFD.cxx +++ b/src/system/SignalFD.cxx @@ -23,33 +23,29 @@ #include "FatalError.hxx" #include <assert.h> -#include <unistd.h> #include <sys/signalfd.h> void SignalFD::Create(const sigset_t &mask) { - fd = ::signalfd(fd, &mask, SFD_NONBLOCK|SFD_CLOEXEC); - if (fd < 0) + if (!fd.CreateSignalFD(&mask)) FatalSystemError("signalfd() failed"); } void SignalFD::Close() { - if (fd >= 0) { - ::close(fd); - fd = -1; - } + if (fd.IsDefined()) + fd.Close(); } int SignalFD::Read() { - assert(fd >= 0); + assert(fd.IsDefined()); signalfd_siginfo info; - return read(fd, &info, sizeof(info)) > 0 + return fd.Read(&info, sizeof(info)) > 0 ? info.ssi_signo : -1; } diff --git a/src/system/SignalFD.hxx b/src/system/SignalFD.hxx index d376c6b59..dae150fea 100644 --- a/src/system/SignalFD.hxx +++ b/src/system/SignalFD.hxx @@ -21,6 +21,7 @@ #define MPD_SIGNAL_FD_HXX #include "check.h" +#include "FileDescriptor.hxx" #include <signal.h> @@ -28,7 +29,7 @@ * A class that wraps signalfd(). */ class SignalFD { - int fd; + FileDescriptor fd; public: SignalFD():fd(-1) {} @@ -48,7 +49,7 @@ public: void Close(); int Get() const { - return fd; + return fd.Get(); } /** diff --git a/src/system/fd_util.c b/src/system/fd_util.c index 440d5b142..5763ede90 100644 --- a/src/system/fd_util.c +++ b/src/system/fd_util.c @@ -41,10 +41,6 @@ #include <sys/socket.h> #endif -#ifdef HAVE_INOTIFY_INIT -#include <sys/inotify.h> -#endif - #ifdef USE_EVENTFD #include <sys/eventfd.h> #endif @@ -200,38 +196,6 @@ accept_cloexec_nonblock(int fd, struct sockaddr *address, return ret; } -#ifdef HAVE_INOTIFY_INIT - -int -inotify_init_cloexec(void) -{ - int fd; - -#ifdef HAVE_INOTIFY_INIT1 - fd = inotify_init1(IN_CLOEXEC); - if (fd >= 0 || errno != ENOSYS) - return fd; -#endif - - fd = inotify_init(); - if (fd >= 0) - fd_set_cloexec(fd, true); - - return fd; -} - -#endif - -#ifdef USE_EVENTFD - -int -eventfd_cloexec_nonblock(unsigned initval, int flags) -{ - return eventfd(initval, flags | EFD_CLOEXEC | EFD_NONBLOCK); -} - -#endif - int close_socket(int fd) { diff --git a/src/system/fd_util.h b/src/system/fd_util.h index 02e959a8e..172b1ade3 100644 --- a/src/system/fd_util.h +++ b/src/system/fd_util.h @@ -91,28 +91,6 @@ int accept_cloexec_nonblock(int fd, struct sockaddr *address, size_t *address_length_r); -#ifdef HAVE_INOTIFY_INIT - -/** - * Wrapper for inotify_init(), which sets the CLOEXEC flag (atomically - * if supported by the OS). - */ -int -inotify_init_cloexec(void); - -#endif - -#ifdef USE_EVENTFD - -/** - * Wrapper for eventfd() which sets the flags CLOEXEC and NONBLOCK - * flag (atomically if supported by the OS). - */ -int -eventfd_cloexec_nonblock(unsigned initval, int flags); - -#endif - /** * Portable wrapper for close(); use closesocket() on WIN32/WinSock. */ |