aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2015-03-03 17:03:21 +0100
committerMax Kellermann <max@duempel.org>2015-03-03 17:14:30 +0100
commit40a587bbaff38bb0b60313c24b94e2ecd53b181c (patch)
treed72c9db82e0db482ebe054119460b506433e9d05
parent818d729d8b60a682e267ac408c710f5851389d79 (diff)
downloadmpd-40a587bbaff38bb0b60313c24b94e2ecd53b181c.tar.gz
mpd-40a587bbaff38bb0b60313c24b94e2ecd53b181c.tar.xz
mpd-40a587bbaff38bb0b60313c24b94e2ecd53b181c.zip
system/FileDescriptor: new wrapper class for a file descriptor
-rw-r--r--Makefile.am3
-rw-r--r--src/db/update/InotifySource.cxx10
-rw-r--r--src/db/update/InotifySource.hxx4
-rw-r--r--src/fs/io/FileReader.cxx19
-rw-r--r--src/fs/io/FileReader.hxx8
-rw-r--r--src/input/plugins/FileInputPlugin.cxx26
-rw-r--r--src/system/EventFD.cxx21
-rw-r--r--src/system/EventFD.hxx9
-rw-r--r--src/system/FileDescriptor.cxx219
-rw-r--r--src/system/FileDescriptor.hxx171
-rw-r--r--src/system/SignalFD.cxx14
-rw-r--r--src/system/SignalFD.hxx5
-rw-r--r--src/system/fd_util.c36
-rw-r--r--src/system/fd_util.h22
14 files changed, 443 insertions, 124 deletions
diff --git a/Makefile.am b/Makefile.am
index 10b646726..11718e86f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -57,9 +57,9 @@ src_mpd_LDADD = \
libevent.a \
libthread.a \
libnet.a \
+ $(FS_LIBS) \
libsystem.a \
libutil.a \
- $(FS_LIBS) \
$(ICU_LDADD) \
$(SYSTEMD_DAEMON_LIBS) \
$(GLIB_LIBS)
@@ -431,6 +431,7 @@ libnet_a_SOURCES = \
libsystem_a_SOURCES = \
src/system/ByteOrder.hxx \
src/system/FatalError.cxx src/system/FatalError.hxx \
+ src/system/FileDescriptor.cxx src/system/FileDescriptor.hxx \
src/system/fd_util.c src/system/fd_util.h \
src/system/EventPipe.cxx src/system/EventPipe.hxx \
src/system/EventFD.cxx src/system/EventFD.hxx \
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.
*/