diff options
author | David Kalnischkies <kalnischkies@gmail.com> | 2011-12-14 22:11:43 +0100 |
---|---|---|
committer | David Kalnischkies <kalnischkies@gmail.com> | 2011-12-14 22:11:43 +0100 |
commit | 52b47296f61ec3ca1075bbfb44982f5caa541e7c (patch) | |
tree | 78d7d8cee526fb7a7d56874375fdaf6091f571c7 | |
parent | aee1aac6f75906ec73dacffc55e7026002201f98 (diff) |
use FileFd instead of forking the compression childs by hand
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 90 | ||||
-rw-r--r-- | apt-pkg/contrib/fileutl.h | 20 | ||||
-rw-r--r-- | ftparchive/multicompress.cc | 30 | ||||
-rw-r--r-- | ftparchive/multicompress.h | 1 |
4 files changed, 83 insertions, 58 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index c2b684089..60396fc3d 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -50,6 +50,8 @@ #define APT_USE_ZLIB 1 #if APT_USE_ZLIB #include <zlib.h> +#else +#warning "Usage of zlib is DISABLED!" #endif #ifdef WORDS_BIGENDIAN @@ -71,7 +73,7 @@ class FileFdPrivate { pid_t compressor_pid; bool pipe; APT::Configuration::Compressor compressor; - FileFd::OpenMode openmode; + unsigned int openmode; FileFdPrivate() : gz(NULL), compressor_pid(-1), pipe(false) {}; }; @@ -858,8 +860,13 @@ bool ExecCompressor(APT::Configuration::Compressor const &Prog, for (int J = 0; J != 2; J++) SetCloseExec(Pipe[J],true); + int FileFd = -1; if (Comp == true) + { OutFd = Pipe[1]; + // FIXME: we should handle openmode and permission from Open() here + FileFd = open(FileName.c_str(), O_WRONLY, 0666); + } else OutFd = Pipe[0]; @@ -872,13 +879,14 @@ bool ExecCompressor(APT::Configuration::Compressor const &Prog, if (Comp == true) { dup2(Pipe[0],STDIN_FILENO); + dup2(FileFd,STDOUT_FILENO); SetCloseExec(STDIN_FILENO,false); } else { dup2(Pipe[1],STDOUT_FILENO); - SetCloseExec(STDOUT_FILENO,false); } + SetCloseExec(STDOUT_FILENO,false); std::vector<char const*> Args; Args.push_back(Prog.Binary.c_str()); @@ -887,8 +895,11 @@ bool ExecCompressor(APT::Configuration::Compressor const &Prog, for (std::vector<std::string>::const_iterator a = addArgs->begin(); a != addArgs->end(); ++a) Args.push_back(a->c_str()); - Args.push_back("--stdout"); - Args.push_back(FileName.c_str()); + if (Comp == false) + { + Args.push_back("--stdout"); + Args.push_back(FileName.c_str()); + } Args.push_back(NULL); execvp(Args[0],(char **)&Args[0]); @@ -896,7 +907,10 @@ bool ExecCompressor(APT::Configuration::Compressor const &Prog, _exit(100); } if (Comp == true) + { close(Pipe[0]); + close(FileFd); + } else close(Pipe[1]); @@ -910,7 +924,7 @@ bool ExecCompressor(APT::Configuration::Compressor const &Prog, // FileFd::Open - Open a file /*{{{*/ // --------------------------------------------------------------------- /* The most commonly used open mode combinations are given with Mode */ -bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned long const Perms) +bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, unsigned long const Perms) { if (Mode == ReadOnlyGzip) return Open(FileName, ReadOnly, Gzip, Perms); @@ -934,11 +948,20 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned } else if (Compress == Extension) { - std::string ext = flExtension(FileName); - if (ext == FileName) - ext.clear(); - else - ext = "." + ext; + std::string::size_type const found = FileName.find_last_of('.'); + std::string ext; + if (found != std::string::npos) + { + ext = FileName.substr(found); + if (ext == ".new" || ext == ".bak") + { + std::string::size_type const found2 = FileName.find_last_of('.', found - 1); + if (found2 != std::string::npos) + ext = FileName.substr(found2, found - found2); + else + ext.clear(); + } + } for (; compressor != compressors.end(); ++compressor) if (ext == compressor->Extension) break; @@ -960,8 +983,8 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned case Xz: name = "xz"; break; case Auto: case Extension: - // Unreachable - return _error->Error("Opening File %s in None, Auto or Extension should be already handled?!?", FileName.c_str()); + // Unreachable + return _error->Error("Opening File %s in None, Auto or Extension should be already handled?!?", FileName.c_str()); } for (; compressor != compressors.end(); ++compressor) if (compressor->Name == name) @@ -974,7 +997,7 @@ bool FileFd::Open(string FileName,OpenMode Mode,CompressMode Compress, unsigned return _error->Error("Can't find a match for specified compressor mode for file %s", FileName.c_str()); return Open(FileName, Mode, *compressor, Perms); } -bool FileFd::Open(string FileName,OpenMode Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms) +bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms) { Close(); d = new FileFdPrivate; @@ -1015,8 +1038,35 @@ bool FileFd::Open(string FileName,OpenMode Mode,APT::Configuration::Compressor c if ((Mode & ReadWrite) == ReadWrite) return _error->Error("External compressors like %s do not support readwrite mode for file %s", compressor.Name.c_str(), FileName.c_str()); - if (ExecCompressor(compressor, NULL /*d->compressor_pid*/, FileName, iFd, ((Mode & ReadOnly) != ReadOnly)) == false) - return _error->Error("Forking external compressor %s is not implemented for %s", compressor.Name.c_str(), FileName.c_str()); + if ((Mode & (WriteOnly | Create)) == (WriteOnly | Create)) + { + if (TemporaryFileName.empty() == false) + { + if (RealFileExists(TemporaryFileName) == false) + { + iFd = open(TemporaryFileName.c_str(), O_WRONLY | O_CREAT, Perms); + close(iFd); + iFd = -1; + } + } + else if (RealFileExists(FileName) == false) + { + iFd = open(FileName.c_str(), O_WRONLY | O_CREAT, Perms); + close(iFd); + iFd = -1; + } + } + + if (TemporaryFileName.empty() == false) + { + if (ExecCompressor(compressor, &(d->compressor_pid), TemporaryFileName, iFd, ((Mode & ReadOnly) != ReadOnly)) == false) + return _error->Error("Forking external compressor %s is not implemented for %s", compressor.Name.c_str(), TemporaryFileName.c_str()); + } + else + { + if (ExecCompressor(compressor, &(d->compressor_pid), FileName, iFd, ((Mode & ReadOnly) != ReadOnly)) == false) + return _error->Error("Forking external compressor %s is not implemented for %s", compressor.Name.c_str(), FileName.c_str()); + } d->pipe = true; d->compressor = compressor; } @@ -1060,7 +1110,7 @@ bool FileFd::Open(string FileName,OpenMode Mode,APT::Configuration::Compressor c // FileFd::OpenDescriptor - Open a filedescriptor /*{{{*/ // --------------------------------------------------------------------- /* */ -bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool AutoClose) +bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose) { std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors(); std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin(); @@ -1084,7 +1134,7 @@ bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool A return OpenDescriptor(Fd, Mode, *compressor, AutoClose); } -bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, APT::Configuration::Compressor const &compressor, bool AutoClose) +bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose) { Close(); d = new FileFdPrivate; @@ -1100,7 +1150,7 @@ bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, APT::Configuration::Compresso this->FileName = ""; return true; } -bool FileFd::OpenInternDescriptor(OpenMode Mode, APT::Configuration::Compressor const &compressor) +bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor) { if (compressor.Name == ".") return true; @@ -1471,8 +1521,8 @@ bool FileFd::Close() if (d != NULL) { -// if (d->compressor_pid != -1) -// ExecWait(d->compressor_pid, "FileFdCompressor", true); + if (d->compressor_pid != -1) + ExecWait(d->compressor_pid, "FileFdCompressor", true); delete d; d = NULL; } diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 51277290e..f14f97b69 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -100,14 +100,14 @@ class FileFd return T; } - bool Open(std::string FileName,OpenMode Mode,CompressMode Compress,unsigned long const Perms = 0666); - bool Open(std::string FileName,OpenMode Mode,APT::Configuration::Compressor const &compressor,unsigned long const Perms = 0666); - inline bool Open(std::string const &FileName,OpenMode Mode, unsigned long const Perms = 0666) { + bool Open(std::string FileName,unsigned int const Mode,CompressMode Compress,unsigned long const Perms = 0666); + bool Open(std::string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor,unsigned long const Perms = 0666); + inline bool Open(std::string const &FileName,unsigned int const Mode, unsigned long const Perms = 0666) { return Open(FileName, Mode, None, Perms); }; - bool OpenDescriptor(int Fd, OpenMode Mode, CompressMode Compress, bool AutoClose=false); - bool OpenDescriptor(int Fd, OpenMode Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false); - inline bool OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose=false) { + bool OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose=false); + bool OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false); + inline bool OpenDescriptor(int Fd, unsigned int const Mode, bool AutoClose=false) { return OpenDescriptor(Fd, Mode, None, AutoClose); }; bool Close(); @@ -126,16 +126,16 @@ class FileFd inline bool IsCompressed() {return (Flags & Compressed) == Compressed;}; inline std::string &Name() {return FileName;}; - FileFd(std::string FileName,OpenMode Mode,unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL) + FileFd(std::string FileName,unsigned int const Mode,unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL) { Open(FileName,Mode, None, Perms); }; - FileFd(std::string FileName,OpenMode Mode, CompressMode Compress, unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL) + FileFd(std::string FileName,unsigned int const Mode, CompressMode Compress, unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL) { Open(FileName,Mode, Compress, Perms); }; FileFd() : iFd(-1), Flags(AutoClose), d(NULL) {}; - FileFd(int const Fd, OpenMode Mode = ReadWrite, CompressMode Compress = None) : iFd(-1), Flags(0), d(NULL) + FileFd(int const Fd, unsigned int const Mode = ReadWrite, CompressMode Compress = None) : iFd(-1), Flags(0), d(NULL) { OpenDescriptor(Fd, Mode, Compress); }; @@ -147,7 +147,7 @@ class FileFd private: FileFdPrivate* d; - bool OpenInternDescriptor(OpenMode Mode, APT::Configuration::Compressor const &compressor); + bool OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor); }; bool RunScripts(const char *Cnf); diff --git a/ftparchive/multicompress.cc b/ftparchive/multicompress.cc index 37a713efd..2a930ca6b 100644 --- a/ftparchive/multicompress.cc +++ b/ftparchive/multicompress.cc @@ -91,7 +91,7 @@ MultiCompress::MultiCompress(string const &Output,string const &Compress, /* Open all the temp files now so we can report any errors. File is made unreable to prevent people from touching it during creating. */ for (Files *I = Outputs; I != 0; I = I->Next) - I->TmpFile.Open(I->Output + ".new",FileFd::WriteEmpty,0600); + I->TmpFile.Open(I->Output + ".new", FileFd::WriteOnly | FileFd::Create | FileFd::Empty, FileFd::Extension, 0600); if (_error->PendingError() == true) return; @@ -183,11 +183,6 @@ bool MultiCompress::Start() _exit(0); }; - /* Tidy up the temp files, we open them in the constructor so as to - get proper error reporting. Close them now. */ - for (Files *I = Outputs; I != 0; I = I->Next) - I->TmpFile.Close(); - close(Pipe[0]); Input = fdopen(Pipe[1],"w"); if (Input == 0) @@ -305,14 +300,6 @@ bool MultiCompress::CloseOld(int Fd,pid_t Proc) is new then the temp files are renamed, otherwise they are erased. */ bool MultiCompress::Child(int const &FD) { - // Start the compression children. - for (Files *I = Outputs; I != 0; I = I->Next) - { - if (ExecCompressor(I->CompressProg,&(I->CompressProc),I->TmpFile.Fd(), - I->Fd,true) == false) - return false; - } - /* Okay, now we just feed data from FD to all the other FDs. Also stash a hash of the data to use later. */ SetNonBlock(FD,false); @@ -332,25 +319,14 @@ bool MultiCompress::Child(int const &FD) FileSize += Res; for (Files *I = Outputs; I != 0; I = I->Next) { - if (write(I->Fd,Buffer,Res) != Res) + if (I->TmpFile.Write(Buffer, Res) == false) { _error->Errno("write",_("IO to subprocess/file failed")); break; } } } - - // Close all the writers - for (Files *I = Outputs; I != 0; I = I->Next) - close(I->Fd); - - // Wait for the compressors to exit - for (Files *I = Outputs; I != 0; I = I->Next) - { - if (I->CompressProc != -1) - ExecWait(I->CompressProc, I->CompressProg.Binary.c_str(), false); - } - + if (_error->PendingError() == true) return false; diff --git a/ftparchive/multicompress.h b/ftparchive/multicompress.h index ac8bd0746..2dc7095d7 100644 --- a/ftparchive/multicompress.h +++ b/ftparchive/multicompress.h @@ -34,7 +34,6 @@ class MultiCompress FileFd TmpFile; pid_t CompressProc; time_t OldMTime; - int Fd; }; Files *Outputs; |