Просмотр исходного кода

split up the OpenMode into OpenMode and CompressionMode and
provide ReadOnly, WriteOnly and ReadWrite as flags alongside
the additional flags as decompression will be one-way later,
but certain parts really depend on Write* openmodes being
ReadWrite opens, so we will have to fail for those.

David Kalnischkies лет назад: 14
Родитель
Сommit
257e8d668c
2 измененных файлов с 79 добавлено и 53 удалено
  1. 53 49
      apt-pkg/contrib/fileutl.cc
  2. 26 4
      apt-pkg/contrib/fileutl.h

+ 53 - 49
apt-pkg/contrib/fileutl.cc

@@ -718,69 +718,72 @@ bool ExecWait(pid_t Pid,const char *Name,bool Reap)
 // FileFd::Open - Open a file						/*{{{*/
 // ---------------------------------------------------------------------
 /* The most commonly used open mode combinations are given with Mode */
-bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms)
+bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned long Perms)
 {
+   if (Mode == ReadOnlyGzip)
+      return Open(FileName, ReadOnly, Gzip, Perms);
    Close();
    Flags = AutoClose;
-   switch (Mode)
+
+   int fileflags = 0;
+#define if_FLAGGED_SET(FLAG, MODE) if ((Mode & FLAG) == FLAG) fileflags |= MODE
+   if_FLAGGED_SET(ReadWrite, O_RDWR);
+   else if_FLAGGED_SET(ReadOnly, O_RDONLY);
+   else if_FLAGGED_SET(WriteOnly, O_WRONLY);
+   else return _error->Error("No openmode provided in FileFd::Open for %s", FileName.c_str());
+
+   if_FLAGGED_SET(Create, O_CREAT);
+   if_FLAGGED_SET(Exclusive, O_EXCL);
+   else if_FLAGGED_SET(Atomic, O_EXCL);
+   if_FLAGGED_SET(Empty, O_TRUNC);
+#undef if_FLAGGED_SET
+
+   if ((Mode & Atomic) == Atomic)
+   {
+      Flags |= Replace;
+      char *name = strdup((FileName + ".XXXXXX").c_str());
+      TemporaryFileName = string(mktemp(name));
+      free(name);
+   }
+   else if ((Mode & (Exclusive | Create)) == (Exclusive | Create))
+   {
+      // for atomic, this will be done by rename in Close()
+      unlink(FileName.c_str());
+   }
+   if ((Mode & Empty) == Empty)
    {
-      case ReadOnly:
-      iFd = open(FileName.c_str(),O_RDONLY);
-      break;
+      struct stat Buf;
+      if (lstat(FileName.c_str(),&Buf) == 0 && S_ISLNK(Buf.st_mode))
+	 unlink(FileName.c_str());
+   }
 
-      case ReadOnlyGzip:
-      iFd = open(FileName.c_str(),O_RDONLY);
-      if (iFd > 0) {
-	 gz = gzdopen (iFd, "r");
-	 if (gz == NULL) {
-	     close (iFd);
-	     iFd = -1;
-	 }
-      }
-      break;
-      
-      case WriteAtomic:
-      {
-	 Flags |= Replace;
-	 char *name = strdup((FileName + ".XXXXXX").c_str());
-	 TemporaryFileName = string(mktemp(name));
-	 iFd = open(TemporaryFileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
-	 free(name);
-	 break;
-      }
+   if (TemporaryFileName.empty() == false)
+      iFd = open(TemporaryFileName.c_str(), fileflags, Perms);
+   else
+      iFd = open(FileName.c_str(), fileflags, Perms);
 
-      case WriteEmpty:
+   if (iFd != -1 && Compress == Gzip)
+   {
+      gz = gzdopen (iFd, "r");
+      if (gz == NULL)
       {
-      	 struct stat Buf;
-	 if (lstat(FileName.c_str(),&Buf) == 0 && S_ISLNK(Buf.st_mode))
-	    unlink(FileName.c_str());
-	 iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_TRUNC,Perms);
-	 break;
+	 close (iFd);
+	 iFd = -1;
       }
-      
-      case WriteExists:
-      iFd = open(FileName.c_str(),O_RDWR);
-      break;
-
-      case WriteAny:
-      iFd = open(FileName.c_str(),O_RDWR | O_CREAT,Perms);
-      break;      
-
-      case WriteTemp:
-      unlink(FileName.c_str());
-      iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
-      break;
-   }  
+   }
 
-   if (iFd < 0)
+   if (iFd == -1)
       return _error->Errno("open",_("Could not open file %s"),FileName.c_str());
-   
+
    this->FileName = FileName;
    SetCloseExec(iFd,true);
    return true;
 }
-
-bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose)
+									/*}}}*/
+// FileFd::OpenDescriptor - Open a filedescriptor			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool AutoClose)
 {
    Close();
    Flags = (AutoClose) ? FileFd::AutoClose : 0;
@@ -1031,6 +1034,7 @@ bool FileFd::Close()
 	 Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str());
 
       FileName = TemporaryFileName; // for the unlink() below.
+      TemporaryFileName.clear();
    }
 
    iFd = -1;

+ 26 - 4
apt-pkg/contrib/fileutl.h

@@ -44,8 +44,24 @@ class FileFd
    gzFile gz;
 
    public:
-   enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,WriteTemp,ReadOnlyGzip,
-                  WriteAtomic};
+   enum OpenMode {
+	ReadOnly = (1 << 0),
+	WriteOnly = (1 << 1),
+	ReadWrite = ReadOnly | WriteOnly,
+
+	Create = (1 << 2),
+	Exclusive = (1 << 3),
+	Atomic = Exclusive | (1 << 4),
+	Empty = (1 << 5),
+
+	WriteEmpty = ReadWrite | Create | Empty,
+	WriteExists = ReadWrite,
+	WriteAny = ReadWrite | Create,
+	WriteTemp = ReadWrite | Create | Exclusive,
+	ReadOnlyGzip,
+	WriteAtomic = ReadWrite | Create | Atomic
+   };
+   enum CompressMode { Auto, None, Gzip, Bzip2, Lzma, Xz };
    
    inline bool Read(void *To,unsigned long long Size,bool AllowEof)
    {
@@ -77,8 +93,14 @@ class FileFd
 	return T;
    }
 
-   bool Open(std::string FileName,OpenMode Mode,unsigned long Perms = 0666);
-   bool OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose=false);
+   bool Open(std::string FileName,OpenMode Mode,CompressMode Compress,unsigned long Perms = 0666);
+   inline bool Open(std::string const &FileName,OpenMode Mode,unsigned long Perms = 0666) {
+      return Open(FileName, Mode, None, Perms);
+   };
+   bool OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool AutoClose=false);
+   inline bool OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose=false) {
+      return OpenDescriptor(Fd, Mode, None, AutoClose);
+   };
    bool Close();
    bool Sync();