]> git.saurik.com Git - apt.git/commitdiff
Merge branch 'feature/abspath' into feature/apt-install-deb
authorMichael Vogt <mvo@ubuntu.com>
Mon, 28 Apr 2014 15:25:28 +0000 (17:25 +0200)
committerMichael Vogt <mvo@ubuntu.com>
Mon, 28 Apr 2014 15:25:28 +0000 (17:25 +0200)
Conflicts:
test/libapt/fileutl_test.cc

1  2 
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h
test/libapt/fileutl_test.cc

index dc21d10eb0fd2d53a8ab3e73b49e491d32b55ab8,abc0a5fb2294e826e48f5c648392a43c8beab7cf..c7c60e00eca6c70ccd0864d9d27da4ac0ece4923
@@@ -659,6 -659,22 +659,22 @@@ string flCombine(string Dir,string File
     return Dir + '/' + File;
  }
                                                                        /*}}}*/
+ // flAbsPath - Return the absolute path of the filename                       /*{{{*/
+ // ---------------------------------------------------------------------
+ /* */
+ string flAbsPath(string File)
+ {
+    char *p = realpath(File.c_str(), NULL);
+    if (p == NULL)
+    {
+       _error->Errno("realpath", "flAbsPath failed");
+       return "";
+    }
+    std::string AbsPath(p);
+    free(p);
+    return AbsPath;
+ }
+                                                                       /*}}}*/
  // SetCloseExec - Set the close on exec flag                          /*{{{*/
  // ---------------------------------------------------------------------
  /* */
@@@ -1920,6 -1936,7 +1936,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 -2063,6 +2062,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 489cee13a94d40521702ab9e78bfca1c26953a03,ab944071ac7fafa294ebc967bf47b119ff1f86b4..452e5fcc281e30905d417bc01c795b7b44c96602
@@@ -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
   *
@@@ -200,19 -198,11 +200,23 @@@ std::string flNoLink(std::string File)
  std::string flExtension(std::string File);
  std::string flCombine(std::string Dir,std::string File);
  
+ /** \brief Takes a file path and returns the absolute path
+  */
+ std::string flAbsPath(std::string File);
  // 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
index c2a43eda7d1db6a395242c1e587e6c96d0578a8b,9c7e1630a3d22d8f8d1decceb58fdccb01acf390..16ea6cf2bdb9c0de6b48cf2e56101dc412652e01
@@@ -224,51 -224,10 +224,57 @@@ TEST(FileUtlTest, GetTempDir
     if (old_tmpdir.empty() == false)
        setenv("TMPDIR", old_tmpdir.c_str(), 1);
  }
 +TEST(FileUtlTest, Popen)
 +{
 +   FileFd Fd;
 +   pid_t Child;
 +   char buf[1024];
 +   std::string s;
 +   unsigned long long n = 0;
 +   std::vector<std::string> OpenFds;
 +
 +   // count Fds to ensure we don't have a resource leak
 +   if(FileExists("/proc/self/fd"))
 +      OpenFds = Glob("/proc/self/fd/*");
 +
 +   // output something
 +   const char* Args[10] = {"/bin/echo", "meepmeep", NULL};
 +   bool res = Popen(Args, Fd, Child, FileFd::ReadOnly);
 +   Fd.Read(buf, sizeof(buf)-1, &n);
 +   buf[n] = 0;
 +   EXPECT_NE(n, 0);
 +   EXPECT_EQ(res, true);
 +   EXPECT_STREQ(buf, "meepmeep\n");
 +
 +   // wait for the child to exit and cleanup
 +   ExecWait(Child, "PopenRead");
 +   Fd.Close();
 +
 +   // ensure that after a close all is good again
 +   if(FileExists("/proc/self/fd"))
 +      EXPECT_EQ(Glob("/proc/self/fd/*").size(), OpenFds.size());
 +
 +
 +   // ReadWrite is not supported
 +   res = Popen(Args, Fd, Child, FileFd::ReadWrite);
 +   EXPECT_EQ(res, false);
 +   _error->Discard();
 +
 +   // write something
 +   Args[0] = "/bin/bash";
 +   Args[1] = "-c";
 +   Args[2] = "read";
 +   Args[3] = NULL;
 +   res = Popen(Args, Fd, Child, FileFd::WriteOnly);
 +   s = "\n";
 +   Fd.Write(s.c_str(), s.size());
 +   Fd.Close();
 +   ExecWait(Child, "PopenWrite");
 +}
+ TEST(FileUtlTest, flAbsPath)
+ {
+    int res = chdir("/bin/");
+    EXPECT_EQ(res, 0);
+    std::string p = flAbsPath("ls");
+    EXPECT_EQ(p, "/bin/ls");
+ }