diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc index 2420b6a8..4d62bf97 100644 --- a/src/AbstractDiskWriter.cc +++ b/src/AbstractDiskWriter.cc @@ -221,6 +221,7 @@ int openFileWithFlags(const std::string& filename, int flags, util::safeStrerror(errNum).c_str()), errCode); } + util::make_fd_cloexec(fd); #if defined(__APPLE__) && defined(__MACH__) // This may reduce memory consumption on Mac OS X. fcntl(fd, F_NOCACHE, 1); diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 3f04ee54..e73f5dcd 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -202,6 +202,7 @@ void SocketCore::create(int family, int protocol) throw DL_ABORT_EX( fmt("Failed to create socket. Cause:%s", errorMsg(errNum).c_str())); } + util::make_fd_cloexec(fd); int sockopt = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (a2_sockopt_t)&sockopt, sizeof(sockopt)) < 0) { @@ -227,6 +228,7 @@ static sock_t bindInternal(int family, int socktype, int protocol, error = errorMsg(errNum); return -1; } + util::make_fd_cloexec(fd); int sockopt = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (a2_sockopt_t)&sockopt, sizeof(sockopt)) < 0) { @@ -445,6 +447,7 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port, error = errorMsg(errNum); continue; } + util::make_fd_cloexec(fd); int sockopt = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (a2_sockopt_t)&sockopt, sizeof(sockopt)) < 0) { diff --git a/src/util.cc b/src/util.cc index 7cfbf237..1d9d8bbf 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1900,7 +1900,7 @@ void executeHook(const std::string& command, a2_gid_t gid, size_t numFiles, assert(cmdlineLen > 0); A2_LOG_INFO(fmt("Executing user command: %s", cmdline.c_str())); DWORD rc = CreateProcessW(batch ? utf8ToWChar(cmdexe).c_str() : nullptr, - wcharCmdline.get(), nullptr, nullptr, true, 0, + wcharCmdline.get(), nullptr, nullptr, false, 0, nullptr, 0, &si, &pi); if (!rc) { @@ -2087,7 +2087,6 @@ TLSVersion toTLSVersion(const std::string& ver) } #endif // ENABLE_SSL - #ifdef __MINGW32__ std::string formatLastError(int errNum) { @@ -2105,6 +2104,25 @@ std::string formatLastError(int errNum) } #endif // __MINGW32__ +void make_fd_cloexec(int fd) +{ +#ifndef __MINGW32__ + int flags; + + // TODO from linux man page, fcntl() with F_GETFD or F_SETFD does + // not return -1 with errno == EINTR. Historically, aria2 code base + // checks this case. Probably, it is not needed. + while ((flags = fcntl(fd, F_GETFD)) == -1 && errno == EINTR) + ; + if (flags == -1) { + return; + } + + while (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1 && errno == EINTR) + ; +#endif // !__MINGW32__ +} + } // namespace util } // namespace aria2 diff --git a/src/util.h b/src/util.h index fe802af4..14b5d146 100644 --- a/src/util.h +++ b/src/util.h @@ -862,6 +862,11 @@ TLSVersion toTLSVersion(const std::string& ver); std::string formatLastError(int errNum); #endif // __MINGW32__ +// Sets file descriptor file FD_CLOEXEC to |fd|. This function is +// noop for Mingw32 build, since we disable inheritance in +// CreateProcess call. +void make_fd_cloexec(int fd); + } // namespace util } // namespace aria2