]> git.saurik.com Git - apt.git/commitdiff
Merge branch 'feature/popen' into feature/apt-install-deb
authorMichael Vogt <mvo@ubuntu.com>
Mon, 28 Apr 2014 15:01:58 +0000 (17:01 +0200)
committerMichael Vogt <mvo@ubuntu.com>
Mon, 28 Apr 2014 15:01:58 +0000 (17:01 +0200)
1  2 
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h

index 655dcdac774c168dea45eeae4c0b26f55c44826f,8d15baad2eb6f0af6ddf67ea21743cfca4aa0047..dc21d10eb0fd2d53a8ab3e73b49e491d32b55ab8
@@@ -1920,6 -1920,7 +1920,6 @@@ bool FileFd::Close(
     {
        if ((Flags & Compressed) != Compressed && iFd > 0 && close(iFd) != 0)
         Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());
 -
        if (d != NULL)
        {
         Res &= d->CloseDown(FileName);
@@@ -2046,31 -2047,6 +2046,31 @@@ std::string GetTempDir(
     return string(tmpdir);
  }
  
 +FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink)
 +{
 +   char fn[512];
 +   FileFd *Fd = new FileFd();
 +
 +   std::string tempdir = GetTempDir();
 +   snprintf(fn, sizeof(fn), "%s/%s.XXXXXX", 
 +            tempdir.c_str(), Prefix.c_str());
 +   int fd = mkstemp(fn);
 +   if(ImmediateUnlink)
 +      unlink(fn);
 +   if (fd < 0) 
 +   {
 +      _error->Errno("GetTempFile",_("Unable to mkstemp %s"), fn);
 +      return NULL;
 +   }
 +   if (!Fd->OpenDescriptor(fd, FileFd::WriteOnly, FileFd::None, true))
 +   {
 +      _error->Errno("GetTempFile",_("Unable to write to %s"),fn);
 +      return NULL;
 +   }
 +
 +   return Fd;
 +}
 +
  bool Rename(std::string From, std::string To)
  {
     if (rename(From.c_str(),To.c_str()) != 0)
     }   
     return true;
  }
+ bool Popen(const char* Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode)
+ {
+    int fd;
+    if (Mode != FileFd::ReadOnly && Mode != FileFd::WriteOnly)
+       return _error->Error("Popen supports ReadOnly (x)or WriteOnly mode only");
+    int Pipe[2] = {-1, -1};
+    if(pipe(Pipe) != 0)
+    {
+       return _error->Errno("pipe", _("Failed to create subprocess IPC"));
+       return NULL;
+    }
+    std::set<int> keep_fds;
+    keep_fds.insert(Pipe[0]);
+    keep_fds.insert(Pipe[1]);
+    Child = ExecFork(keep_fds);
+    if(Child < 0)
+       return _error->Errno("fork", "Failed to fork");
+    if(Child == 0)
+    {
+       if(Mode == FileFd::ReadOnly)
+       {
+          close(Pipe[0]);
+          fd = Pipe[1];
+       }
+       else if(Mode == FileFd::WriteOnly)
+       {
+          close(Pipe[1]);
+          fd = Pipe[0];
+       }
+       if(Mode == FileFd::ReadOnly)
+       {
+          dup2(fd, 1);
+          dup2(fd, 2);
+       } else if(Mode == FileFd::WriteOnly)
+          dup2(fd, 0);
+       execv(Args[0], (char**)Args);
+       _exit(100);
+    }
+    if(Mode == FileFd::ReadOnly)
+    {
+       close(Pipe[1]);
+       fd = Pipe[0];
+    } else if(Mode == FileFd::WriteOnly)
+    {
+       close(Pipe[0]);
+       fd = Pipe[1];
+    }
+    Fd.OpenDescriptor(fd, Mode, FileFd::None, true);
+    return true;
+ }
index fb01531fd6704c517801c432ddd48304abae14f3,b7812ac5677e770e9f30546632a17a9939888542..489cee13a94d40521702ab9e78bfca1c26953a03
@@@ -168,8 -168,6 +168,8 @@@ time_t GetModificationTime(std::string 
  bool Rename(std::string From, std::string To);
  
  std::string GetTempDir();
 +FileFd* GetTempFile(std::string const &Prefix = "", 
 +                    bool ImmediateUnlink = true);
  
  /** \brief Ensure the existence of the given Path
   *
@@@ -203,4 -201,16 +203,16 @@@ std::string flCombine(std::string Dir,s
  // simple c++ glob
  std::vector<std::string> Glob(std::string const &pattern, int flags=0);
  
+ /** \brief Popen() implementation that execv() instead of using a shell
+  *
+  * \param Args the execv style command to run
+  * \param FileFd is a referenz to the FileFd to use for input or output
+  * \param Child a reference to the integer that stores the child pid
+  *        Note that you must call ExecWait() or similar to cleanup
+  * \param Mode is either FileFd::ReadOnly or FileFd::WriteOnly
+  * \return true on success, false on failure with _error set
+  */
+ bool Popen(const char* Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode);
  #endif