#include <string>
#include <utility>
#include <vector>
+#include <sstream>
+#include <numeric>
#include <apti18n.h>
/*}}}*/
using namespace std;
+APT_PURE static string
+AptHistoryRequestingUser()
+{
+ const char* EnvKeys[]{"SUDO_UID", "PKEXEC_UID", "PACKAGEKIT_CALLER_UID"};
+
+ for (const auto &Key: EnvKeys)
+ {
+ if (getenv(Key) != nullptr)
+ {
+ int uid = atoi(getenv(Key));
+ if (uid > 0) {
+ struct passwd pwd;
+ struct passwd *result;
+ char buf[255];
+ if (getpwuid_r(uid, &pwd, buf, sizeof(buf), &result) == 0 && result != NULL) {
+ std::string res;
+ strprintf(res, "%s (%d)", pwd.pw_name, uid);
+ return res;
+ }
+ }
+ }
+ }
+ return "";
+}
+
APT_PURE static unsigned int
EnvironmentSize()
{
}
if (_config->Exists("Commandline::AsString") == true)
WriteHistoryTag("Commandline", _config->Find("Commandline::AsString"));
+ std::string RequestingUser = AptHistoryRequestingUser();
+ if (RequestingUser != "")
+ WriteHistoryTag("Requested-By", RequestingUser);
WriteHistoryTag("Install", install);
WriteHistoryTag("Reinstall", reinstall);
WriteHistoryTag("Upgrade", upgrade);
_exit(100);
}
+ // if color support isn't enabled/disabled explicitly tell
+ // dpkg to use the same state apt is using for its color support
+ if (_config->FindB("APT::Color", false) == true)
+ setenv("DPKG_COLORS", "always", 0);
+ else
+ setenv("DPKG_COLORS", "never", 0);
+
execvp(Args[0], (char**) &Args[0]);
cerr << "Could not exec dpkg!" << endl;
_exit(100);
// the result of the waitpid call
int res;
int select_ret;
+ bool waitpid_failure = false;
while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
if(res < 0) {
- // FIXME: move this to a function or something, looks ugly here
// error handling, waitpid returned -1
if (errno == EINTR)
continue;
- RunScripts("DPkg::Post-Invoke");
-
- // Restore sig int/quit
- signal(SIGQUIT,old_SIGQUIT);
- signal(SIGINT,old_SIGINT);
-
- signal(SIGHUP,old_SIGHUP);
- return _error->Errno("waitpid","Couldn't wait for subprocess");
+ waitpid_failure = true;
+ break;
}
// wait for input or output here
// Restore sig int/quit
signal(SIGQUIT,old_SIGQUIT);
signal(SIGINT,old_SIGINT);
-
signal(SIGHUP,old_SIGHUP);
+
+ if (waitpid_failure == true)
+ {
+ strprintf(d->dpkg_error, "Sub-process %s couldn't be waited for.",Args[0]);
+ _error->Error("%s", d->dpkg_error.c_str());
+ break;
+ }
+
// Check for an error code.
if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
{
- // if it was set to "keep-dpkg-runing" then we won't return
+ // if it was set to "keep-dpkg-running" then we won't return
// here but keep the loop going and just report it as a error
// for later
bool const stopOnError = _config->FindB("Dpkg::StopOnError",true);
}
}
// dpkg is done at this point
- d->progress->Stop();
StopPtyMagic();
CloseLog();
if (pkgPackageManager::SigINTStop)
_error->Warning(_("Operation was interrupted before it could finish"));
- if (RunScripts("DPkg::Post-Invoke") == false)
- return false;
-
if (_config->FindB("Debug::pkgDPkgPM",false) == false)
{
std::string const oldpkgcache = _config->FindFile("Dir::cache::pkgcache");
}
Cache.writeStateFile(NULL);
+
+ d->progress->Stop();
+
+ if (RunScripts("DPkg::Post-Invoke") == false)
+ return false;
+
return d->dpkg_error.empty();
}