]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/fileutl.cc
move fd duplication closer to the gz/bz2 open calls
[apt.git] / apt-pkg / contrib / fileutl.cc
index ffb8b4b53cc628a6caba0dc36b3d3f6121094d6a..2188f616a43485871ca8e7549beabedd4cfa2358 100644 (file)
 #include <apt-pkg/sptr.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/configuration.h>
-
+#include <apt-pkg/macros.h>
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <sys/select.h>
+#include <time.h>
+#include <string>
+#include <vector>
 #include <cstdlib>
 #include <cstring>
 #include <cstdio>
-
 #include <iostream>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <dirent.h>
@@ -222,7 +228,7 @@ int GetLock(string File,bool Errors)
    int FD = open(File.c_str(),O_RDWR | O_CREAT | O_NOFOLLOW,0640);
    if (FD < 0)
    {
-      // Read only .. cant have locking problems there.
+      // Read only .. can't have locking problems there.
       if (errno == EROFS)
       {
         _error->Warning(_("Not using locking for read only lock file %s"),File.c_str());
@@ -238,7 +244,7 @@ int GetLock(string File,bool Errors)
    }
    SetCloseExec(FD,true);
       
-   // Aquire a write lock
+   // Acquire a write lock
    struct flock fl;
    fl.l_type = F_WRLCK;
    fl.l_whence = SEEK_SET;
@@ -319,7 +325,7 @@ bool CreateDirectory(string const &Parent, string const &Path)
       return false;
 
    // we are not going to create directories "into the blue"
-   if (Path.find(Parent, 0) != 0)
+   if (Path.compare(0, Parent.length(), Parent) != 0)
       return false;
 
    vector<string> const dirs = VectorizeString(Path.substr(Parent.size()), '/');
@@ -891,7 +897,7 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress,
    {
       for (; compressor != compressors.end(); ++compressor)
       {
-        std::string file = std::string(FileName).append(compressor->Extension);
+        std::string file = FileName + compressor->Extension;
         if (FileExists(file) == false)
            continue;
         FileName = file;
@@ -1061,30 +1067,12 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration:
 {
    Close();
    Flags = (AutoClose) ? FileFd::AutoClose : 0;
-   if (AutoClose == false && (
-#ifdef HAVE_ZLIB
-       compressor.Name == "gzip" ||
-#endif
-#ifdef HAVE_BZ2
-       compressor.Name == "bzip2" ||
-#endif
-       false))
-   {
-      // Need to duplicate fd here or gzclose for cleanup will close the fd as well
-      iFd = dup(Fd);
-   }
-   else
-      iFd = Fd;
+   iFd = Fd;
    this->FileName = "";
-   if (Fd == -1 || OpenInternDescriptor(Mode, compressor) == false)
+   if (OpenInternDescriptor(Mode, compressor) == false)
    {
       if (iFd != -1 && (
-#ifdef HAVE_ZLIB
-       compressor.Name == "gzip" ||
-#endif
-#ifdef HAVE_BZ2
-       compressor.Name == "bzip2" ||
-#endif
+       (Flags & Compressed) == Compressed ||
        AutoClose == true))
       {
         close (iFd);
@@ -1096,6 +1084,8 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration:
 }
 bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor)
 {
+   if (iFd == -1)
+      return false;
    if (compressor.Name == "." || compressor.Binary.empty() == true)
       return true;
 
@@ -1104,6 +1094,21 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
       d = new FileFdPrivate();
       d->openmode = Mode;
       d->compressor = compressor;
+      if (AutoClose == false && (
+#ifdef HAVE_ZLIB
+              compressor.Name == "gzip" ||
+#endif
+#ifdef HAVE_BZ2
+              compressor.Name == "bzip2" ||
+#endif
+              false))
+      {
+        // Need to duplicate fd here or gz/bz2 close for cleanup will close the fd as well
+        int const internFd = dup(iFd);
+        if (internFd == -1)
+           return FileFdErrno("OpenInternDescriptor", _("Could not open file descriptor %d"), iFd);
+        iFd = internFd;
+      }
    }
 
 #ifdef HAVE_ZLIB
@@ -1256,7 +1261,7 @@ FileFd::~FileFd()
                                                                        /*}}}*/
 // FileFd::Read - Read a bit of the file                               /*{{{*/
 // ---------------------------------------------------------------------
-/* We are carefull to handle interruption by a signal while reading 
+/* We are careful to handle interruption by a signal while reading
    gracefully. */
 bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
 {
@@ -1400,7 +1405,7 @@ bool FileFd::Write(const void *From,unsigned long long Size)
         return FileFdErrno("write",_("Write error"));
       }
       
-      From = (char *)From + Res;
+      From = (char const *)From + Res;
       Size -= Res;
       if (d != NULL)
         d->seekpos += Res;
@@ -1424,7 +1429,7 @@ bool FileFd::Write(int Fd, const void *From, unsigned long long Size)
       if (Res < 0)
         return _error->Errno("write",_("Write error"));
 
-      From = (char *)From + Res;
+      From = (char const *)From + Res;
       Size -= Res;
    }
    while (Res > 0 && Size > 0);
@@ -1588,29 +1593,55 @@ unsigned long long FileFd::Tell()
    return Res;
 }
                                                                        /*}}}*/
-// FileFd::FileSize - Return the size of the file                      /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-unsigned long long FileFd::FileSize()
+static bool StatFileFd(char const * const msg, int const iFd, std::string const &FileName, struct stat &Buf, FileFdPrivate * const d) /*{{{*/
 {
-   struct stat Buf;
-   if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
-      return FileFdErrno("fstat","Unable to determine the file size");
+   bool ispipe = (d != NULL && d->pipe == true);
+   if (ispipe == false)
+   {
+      if (fstat(iFd,&Buf) != 0)
+        // higher-level code will generate more meaningful messages,
+        // even translated this would be meaningless for users
+        return _error->Errno("fstat", "Unable to determine %s for fd %i", msg, iFd);
+      ispipe = S_ISFIFO(Buf.st_mode);
+   }
 
    // for compressor pipes st_size is undefined and at 'best' zero
-   if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode))
+   if (ispipe == true)
    {
       // we set it here, too, as we get the info here for free
       // in theory the Open-methods should take care of it already
       if (d != NULL)
         d->pipe = true;
       if (stat(FileName.c_str(), &Buf) != 0)
-        return FileFdErrno("stat","Unable to determine the file size");
+        return _error->Errno("fstat", "Unable to determine %s for file %s", msg, FileName.c_str());
+   }
+   return true;
+}
+                                                                       /*}}}*/
+// FileFd::FileSize - Return the size of the file                      /*{{{*/
+unsigned long long FileFd::FileSize()
+{
+   struct stat Buf;
+   if (StatFileFd("file size", iFd, FileName, Buf, d) == false)
+   {
+      Flags |= Fail;
+      return 0;
    }
-
    return Buf.st_size;
 }
                                                                        /*}}}*/
+// FileFd::ModificationTime - Return the time of last touch            /*{{{*/
+time_t FileFd::ModificationTime()
+{
+   struct stat Buf;
+   if (StatFileFd("modification time", iFd, FileName, Buf, d) == false)
+   {
+      Flags |= Fail;
+      return 0;
+   }
+   return Buf.st_mtime;
+}
+                                                                       /*}}}*/
 // FileFd::Size - Return the size of the content in the file           /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -1682,35 +1713,6 @@ unsigned long long FileFd::Size()
    return size;
 }
                                                                        /*}}}*/
-// FileFd::ModificationTime - Return the time of last touch            /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-time_t FileFd::ModificationTime()
-{
-   struct stat Buf;
-   if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
-   {
-      FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
-      return 0;
-   }
-
-   // for compressor pipes st_size is undefined and at 'best' zero
-   if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode))
-   {
-      // we set it here, too, as we get the info here for free
-      // in theory the Open-methods should take care of it already
-      if (d != NULL)
-        d->pipe = true;
-      if (stat(FileName.c_str(), &Buf) != 0)
-      {
-        FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
-        return 0;
-      }
-   }
-
-   return Buf.st_mtime;
-}
-                                                                       /*}}}*/
 // FileFd::Close - Close the file if the close flag is set             /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -1796,7 +1798,7 @@ bool FileFd::FileFdError(const char *Description,...) {
 }
                                                                        /*}}}*/
 
-gzFile FileFd::gzFd() { return (gzFile) d->gz; }
+gzFile FileFd::gzFd() { return d->gz; }
 
 
 // Glob - wrapper around "glob()"                                      /*{{{*/