]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/fileutl.cc
Bug #807012 also involves package dependencies :/.
[apt.git] / apt-pkg / contrib / fileutl.cc
index 342f9830d78a4b0adec1f4e678666a03884348c0..dd36ffa790070a2cb3648aa5dd5411223a5cde24 100644 (file)
@@ -1908,11 +1908,12 @@ public:
               " but was forced to ignore it in favor of an external binary – which isn't installed.", compressor.Name.c_str());
 
       bool const Comp = (Mode & FileFd::WriteOnly) == FileFd::WriteOnly;
-      if (Comp == false)
+      if (Comp == false && filefd->iFd != -1)
       {
         // Handle 'decompression' of empty files
         struct stat Buf;
-        fstat(filefd->iFd, &Buf);
+        if (fstat(filefd->iFd, &Buf) != 0)
+           return filefd->FileFdErrno("fstat", "Could not stat fd %d for file %s", filefd->iFd, filefd->FileName.c_str());
         if (Buf.st_size == 0 && S_ISFIFO(Buf.st_mode) == false)
            return true;
 
@@ -1955,12 +1956,6 @@ public:
               dup2(compressed_fd,STDIN_FILENO);
            dup2(Pipe[1],STDOUT_FILENO);
         }
-        int const nullfd = open("/dev/null", O_WRONLY);
-        if (nullfd != -1)
-        {
-           dup2(nullfd,STDERR_FILENO);
-           close(nullfd);
-        }
 
         SetCloseExec(STDOUT_FILENO,false);
         SetCloseExec(STDIN_FILENO,false);
@@ -2443,6 +2438,37 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
    }
 
    return FileFdError(_("read, still have %llu to read but none left"), Size);
+}
+bool FileFd::Read(int const Fd, void *To, unsigned long long Size, unsigned long long * const Actual)
+{
+   ssize_t Res = 1;
+   errno = 0;
+   if (Actual != nullptr)
+      *Actual = 0;
+   *static_cast<char *>(To) = '\0';
+   while (Res > 0 && Size > 0)
+   {
+      Res = read(Fd, To, Size);
+      if (Res < 0)
+      {
+        if (errno == EINTR)
+        {
+           Res = 1;
+           errno = 0;
+           continue;
+        }
+        return _error->Errno("read", _("Read error"));
+      }
+      To = static_cast<char *>(To) + Res;
+      Size -= Res;
+      if (Actual != 0)
+        *Actual += Res;
+   }
+   if (Size == 0)
+      return true;
+   if (Actual != nullptr)
+      return true;
+   return _error->Error(_("read, still have %llu to read but none left"), Size);
 }
                                                                        /*}}}*/
 // FileFd::ReadLine - Read a complete line from the file               /*{{{*/
@@ -2746,9 +2772,9 @@ std::vector<std::string> Glob(std::string const &pattern, int flags)
    return result;
 }
                                                                        /*}}}*/
-std::string GetTempDir()                                               /*{{{*/
+static std::string APT_NONNULL(1) GetTempDirEnv(char const * const env)        /*{{{*/
 {
-   const char *tmpdir = getenv("TMPDIR");
+   const char *tmpdir = getenv(env);
 
 #ifdef P_tmpdir
    if (!tmpdir)
@@ -2764,6 +2790,11 @@ std::string GetTempDir()                                         /*{{{*/
       tmpdir = "/tmp";
 
    return string(tmpdir);
+}
+                                                                       /*}}}*/
+std::string GetTempDir()                                               /*{{{*/
+{
+   return GetTempDirEnv("TMPDIR");
 }
 std::string GetTempDir(std::string const &User)
 {
@@ -2828,6 +2859,11 @@ bool Rename(std::string From, std::string To)                            /*{{{*/
 }
                                                                        /*}}}*/
 bool Popen(const char* Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode)/*{{{*/
+{
+   return Popen(Args, Fd, Child, Mode, true);
+}
+                                                                       /*}}}*/
+bool Popen(const char* Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode, bool CaptureStderr)/*{{{*/
 {
    int fd;
    if (Mode != FileFd::ReadOnly && Mode != FileFd::WriteOnly)
@@ -2859,7 +2895,8 @@ bool Popen(const char* Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode)/
       if(Mode == FileFd::ReadOnly)
       {
          dup2(fd, 1);
-         dup2(fd, 2);
+        if (CaptureStderr == true)
+           dup2(fd, 2);
       } else if(Mode == FileFd::WriteOnly)
          dup2(fd, 0);
 
@@ -3013,6 +3050,32 @@ bool DropPrivileges()                                                    /*{{{*/
         return _error->Error("Could restore a uid to root, privilege dropping did not work");
    }
 
+   if (_config->FindB("APT::Sandbox::ResetEnvironment", true))
+   {
+      setenv("HOME", pw->pw_dir, 1);
+      setenv("USER", pw->pw_name, 1);
+      setenv("USERNAME", pw->pw_name, 1);
+      setenv("LOGNAME", pw->pw_name, 1);
+      auto const shell = flNotDir(pw->pw_shell);
+      if (shell == "false" || shell == "nologin")
+        setenv("SHELL", "/bin/sh", 1);
+      else
+        setenv("SHELL", pw->pw_shell, 1);
+      auto const apt_setenv_tmp = [](char const * const env) {
+        auto const tmpdir = getenv(env);
+        if (tmpdir != nullptr)
+        {
+           auto const ourtmpdir = GetTempDirEnv(env);
+           if (ourtmpdir != tmpdir)
+              setenv(env, ourtmpdir.c_str(), 1);
+        }
+      };
+      apt_setenv_tmp("TMPDIR");
+      apt_setenv_tmp("TEMPDIR");
+      apt_setenv_tmp("TMP");
+      apt_setenv_tmp("TEMP");
+   }
+
    return true;
 }
                                                                        /*}}}*/