mirror of https://github.com/aria2/aria2
Don't inherit file descriptor to child process
For non-Mingw32 build, set FD_CLOEXEC to file descriptors which live beyond function scope. For Mingw32 build, just pass false to bInheritHandles parameter of CreateProcessW.pull/565/head
parent
ab40ee58b8
commit
5e48e01bf9
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
22
src/util.cc
22
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue