Refactor the FD_CLOEXEC/O_NONBLOCK code.

This commit is contained in:
Gunnar Beutner 2013-02-13 13:03:21 +01:00
parent fac2304ae5
commit 26e2da7a7d
5 changed files with 62 additions and 61 deletions

View File

@ -456,23 +456,7 @@ void Application::UpdatePidFile(const String& filename)
BOOST_THROW_EXCEPTION(runtime_error("Could not open PID file '" + filename + "'"));
#ifndef _WIN32
int flags;
flags = fcntl(fileno(m_PidFile), F_GETFD, 0);
if (flags < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
if (fcntl(fileno(m_PidFile), F_SETFD, flags | FD_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
if (flock(fileno(m_PidFile), LOCK_EX | LOCK_NB) < 0) {
ClosePidFile();
Logger::Write(LogCritical, "base",
"Another instance of the application is "
"already running. Remove the '" + filename + "' file if "
"you're certain that this is not the case.");
Terminate(EXIT_FAILURE);
}
Utility::SetCloExec(fileno(m_PidFile));
#endif /* _WIN32 */
fprintf(m_PidFile, "%d", Utility::GetPid());

View File

@ -30,34 +30,30 @@ void Process::CreateWorkers(void)
{
int fds[2];
#ifdef HAVE_PIPE2
if (pipe2(fds, O_NONBLOCK | O_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("pipe2() failed.", errno));
#else /* HAVE_PIPE2 */
if (pipe(fds) < 0)
BOOST_THROW_EXCEPTION(PosixException("pipe() failed.", errno));
/* Don't bother setting fds[1] to non-blocking/clo-exec as we'll only
* use it in the following dup() call. */
Utility::SetNonBlocking(fds[1]);
Utility::SetCloExec(fds[1]);
#endif /* HAVE_PIPE2 */
m_TaskFd = fds[1];
int flags;
flags = fcntl(fds[1], F_GETFD, 0);
if (flags < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
if (fcntl(fds[1], F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
for (int i = 0; i < thread::hardware_concurrency(); i++) {
int childTaskFd;
childTaskFd = dup(fds[0]);
int childTaskFd = dup(fds[0]);
if (childTaskFd < 0)
BOOST_THROW_EXCEPTION(PosixException("dup() failed.", errno));
int flags;
flags = fcntl(childTaskFd, F_GETFD, 0);
if (flags < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
if (fcntl(childTaskFd, F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
Utility::SetNonBlocking(childTaskFd);
Utility::SetCloExec(childTaskFd);
thread t(&Process::WorkerThreadProc, childTaskFd);
t.detach();
@ -179,26 +175,16 @@ void Process::InitTask(void)
#ifdef HAVE_PIPE2
if (pipe2(fds, O_NONBLOCK | O_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("pipe2() failed.", errno));
#else /* HAVE_PIPE2 */
if (pipe(fds) < 0)
#endif /* HAVE_PIPE2 */
BOOST_THROW_EXCEPTION(PosixException("pipe() failed.", errno));
#ifndef HAVE_PIPE2
int flags;
flags = fcntl(fds[0], F_GETFD, 0);
if (flags < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
Utility::SetNonBlocking(fds[0]);
Utility::SetCloExec(fds[0]);
if (fcntl(fds[0], F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
flags = fcntl(fds[1], F_GETFD, 0);
if (flags < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
if (fcntl(fds[1], F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
Utility::SetNonBlocking(fds[1]);
Utility::SetCloExec(fds[1]);
#endif /* HAVE_PIPE2 */
// build argv

View File

@ -70,17 +70,9 @@ void Socket::SetFD(SOCKET fd)
{
/* mark the socket as non-blocking and close-on-exec */
if (fd != INVALID_SOCKET) {
Utility::SetNonBlockingSocket(fd);
#ifndef _WIN32
int flags;
flags = fcntl(fd, F_GETFD, 0);
if (flags < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
if (fcntl(fd, F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
#else /* _WIN32 */
unsigned long lTrue = 1;
ioctlsocket(fd, FIONBIO, &lTrue);
Utility::SetCloExec(fd);
#endif /* _WIN32 */
}
@ -219,7 +211,7 @@ String Socket::GetPeerAddress(void)
* @param message The error message.
* @param errorCode The error code.
*/
SocketException::SocketException(const String& message, int errorCode)
SocketException::SocketException(const String& message, int errorCode)
{
#ifdef _WIN32
String details = Win32Exception::FormatErrorCode(errorCode);

View File

@ -526,3 +526,35 @@ void Utility::WaitUntil(const function<bool (void)>& predicate)
Application::ProcessEvents();
}
void Utility::SetNonBlocking(int fd)
{
int flags;
flags = fcntl(fd, F_GETFL, 0);
if (flags < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
}
void Utility::SetCloExec(int fd)
{
int flags;
flags = fcntl(fd, F_GETFD, 0);
if (flags < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
}
void Utility::SetNonBlockingSocket(SOCKET s)
{
#ifndef _WIN32
SetNonBlocking(s);
#else /* _WIN32 */
unsigned long lTrue = 1;
ioctlsocket(s, FIONBIO, &lTrue);
#endif /* _WIN32 */
}

View File

@ -68,6 +68,13 @@ public:
#endif /* _WIN32 */
LoadIcingaLibrary(const String& library, bool module);
#ifndef _WIN32
static void SetNonBlocking(int fd);
static void SetCloExec(int fd);
#endif /* _WIN32 */
static void SetNonBlockingSocket(SOCKET s);
private:
static bool m_SSLInitialized;