summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2025-10-20 20:26:49 +0200
committerJulian Andres Klode <jak@debian.org>2025-10-20 20:26:49 +0200
commitbb1e6834e8a1cd6fd5b88b5a1962e9d813a080fc (patch)
tree4d7562b64206a52f6f7918be422b080f239a8d56
parent3dea3434bf2003b757d7ecdb5a8194c8a0c7023f (diff)
Correctly append or remove FD_CLOEXEC
Rather than just setting the flags to 0 or FD_CLOEXEC, read the current value and append or remove as needed.
-rw-r--r--apt-pkg/contrib/fileutl.cc8
-rw-r--r--apt-pkg/install-progress.cc6
2 files changed, 10 insertions, 4 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index fc4e047a5..69e6dc430 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -803,7 +803,8 @@ std::string flNormalize(std::string file) /*{{{*/
/* */
void SetCloseExec(int Fd,bool Close)
{
- if (fcntl(Fd,F_SETFD,(Close == false)?0:FD_CLOEXEC) != 0)
+ auto flags = fcntl(Fd, F_GETFD);
+ if (flags < 0 || fcntl(Fd, F_SETFD, Close ? flags | FD_CLOEXEC : flags & ~FD_CLOEXEC) != 0)
{
cerr << "FATAL -> Could not set close on exec " << strerror(errno) << endl;
exit(100);
@@ -922,7 +923,10 @@ pid_t ExecFork(std::set<int> KeepFDs)
signal(SIGTSTP,SIG_DFL);
auto safeSetCloseExec = [](int fd, bool close)
{
- if (fcntl(fd, F_SETFD, close ? FD_CLOEXEC : 0) == 0 || errno == EBADF)
+ auto flags = fcntl(fd, F_GETFD);
+ if (flags < 0 && errno == EBADF)
+ return;
+ if (flags >= 0 && fcntl(fd, F_SETFD, close ? flags | FD_CLOEXEC : flags & ~FD_CLOEXEC) == 0)
return;
cerr << "FATAL -> Could not set close on exec " << strerror(errno) << endl;
_Exit(100);
diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc
index fe3324426..6ff8c3140 100644
--- a/apt-pkg/install-progress.cc
+++ b/apt-pkg/install-progress.cc
@@ -98,7 +98,8 @@ void PackageManagerProgressFd::StartDpkg()
// FIXME: use SetCloseExec here once it taught about throwing
// exceptions instead of doing _exit(100) on failure
- fcntl(OutStatusFd,F_SETFD,FD_CLOEXEC);
+ if (auto flags = fcntl(OutStatusFd, F_GETFD); flags >= 0)
+ fcntl(OutStatusFd, F_SETFD, flags | FD_CLOEXEC);
// send status information that we are about to fork dpkg
WriteToStatusFd(GetProgressFdString("pmstatus", "dpkg-exec", StepsDone, StepsTotal, _("Running dpkg")));
@@ -180,7 +181,8 @@ void PackageManagerProgressDeb822Fd::StartDpkg()
{
// FIXME: use SetCloseExec here once it taught about throwing
// exceptions instead of doing _exit(100) on failure
- fcntl(OutStatusFd,F_SETFD,FD_CLOEXEC);
+ if (auto flags = fcntl(OutStatusFd, F_GETFD); flags >= 0)
+ fcntl(OutStatusFd, F_SETFD, flags | FD_CLOEXEC);
WriteToStatusFd(GetProgressDeb822String("progress", nullptr, StepsDone, StepsTotal, _("Running dpkg")));
}