From 88593886a42025d51d76051da5929b044e42efee Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 11 May 2015 15:08:08 +0200 Subject: rewrite all TFRewrite instances to use the new pkgTagSection::Write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While it is mostly busywork to rewrite all instances it actually fixes bugs as the data storage used by the new method is std::string rather than a char*, the later mostly created by c_str() from a std::string which the caller has to ensure keeps in scope – something apt-ftparchive actually didn't ensure and relied on copy-on-write behavior instead which c++11 forbids and hence the new default gcc abi doesn't use it. --- apt-pkg/depcache.cc | 50 +++++++++------------ apt-pkg/indexcopy.cc | 125 ++++++++++++++++++++------------------------------- apt-pkg/indexcopy.h | 7 +-- 3 files changed, 73 insertions(+), 109 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 73c5bb320..b73c336db 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -252,17 +251,14 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ return _error->Error(_("Failed to open StateFile %s"), state.c_str()); - FILE *OutFile; - string const outfile = state + ".tmp"; - if((OutFile = fopen(outfile.c_str(),"w")) == NULL) - return _error->Error(_("Failed to write temporary StateFile %s"), - outfile.c_str()); + FileFd OutFile(state, FileFd::ReadWrite | FileFd::Atomic); + if (OutFile.IsOpen() == false || OutFile.Failed() == true) + return _error->Error(_("Failed to write temporary StateFile %s"), state.c_str()); // first merge with the existing sections pkgTagFile tagfile(&StateFile); pkgTagSection section; std::set pkgs_seen; - const char *nullreorderlist[] = {0}; while(tagfile.Step(section)) { string const pkgname = section.FindS("Package"); string pkgarch = section.FindS("Architecture"); @@ -271,7 +267,7 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ // Silently ignore unknown packages and packages with no actual // version. pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch); - if(pkg.end() || pkg.VersionList().end()) + if(pkg.end() || pkg.VersionList().end()) continue; StateCache const &P = PkgState[pkg->ID]; bool newAuto = (P.Flags & Flag::Auto); @@ -292,21 +288,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ if(_config->FindB("Debug::pkgAutoRemove",false)) std::clog << "Update existing AutoInstall info: " << pkg.FullName() << std::endl; - TFRewriteData rewrite[3]; - rewrite[0].Tag = "Architecture"; - rewrite[0].Rewrite = pkg.Arch(); - rewrite[0].NewTag = 0; - rewrite[1].Tag = "Auto-Installed"; - rewrite[1].Rewrite = newAuto ? "1" : "0"; - rewrite[1].NewTag = 0; - rewrite[2].Tag = 0; - TFRewrite(OutFile, section, nullreorderlist, rewrite); - fprintf(OutFile,"\n"); + + std::vector rewrite; + rewrite.push_back(pkgTagSection::Tag::Rewrite("Architecture", pkg.Arch())); + rewrite.push_back(pkgTagSection::Tag::Rewrite("Auto-Installed", newAuto ? "1" : "0")); + section.Write(OutFile, NULL, rewrite); + if (OutFile.Write("\n", 1) == false) + return false; pkgs_seen.insert(pkg.FullName()); } - + // then write the ones we have not seen yet - std::ostringstream ostr; for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); ++pkg) { StateCache const &P = PkgState[pkg->ID]; if(P.Flags & Flag::Auto) { @@ -325,19 +317,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ continue; if(debug_autoremove) std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl; - ostr.str(string("")); - ostr << "Package: " << pkg.Name() - << "\nArchitecture: " << pkgarch - << "\nAuto-Installed: 1\n\n"; - fprintf(OutFile,"%s",ostr.str().c_str()); + std::string stanza = "Package: "; + stanza.append(pkg.Name()) + .append("\nArchitecture: ").append(pkgarch) + .append("\nAuto-Installed: 1\n\n"); + if (OutFile.Write(stanza.c_str(), stanza.length()) == false) + return false; } } - fclose(OutFile); - - // move the outfile over the real file and set permissions - rename(outfile.c_str(), state.c_str()); + if (OutFile.Close() == false) + return false; chmod(state.c_str(), 0644); - return true; } /*}}}*/ diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 144c508be..461aa4217 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -108,10 +108,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, } if (_error->PendingError() == true) return false; - FILE *TargetFl = fdopen(dup(Target.Fd()),"w"); - if (TargetFl == 0) - return _error->Errno("fdopen","Failed to reopen fd"); - + // Setup the progress meter if(Progress) Progress->OverallProgress(CurrentSize,TotalSize,FileSize, @@ -132,14 +129,11 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, string File; unsigned long long Size; if (GetFile(File,Size) == false) - { - fclose(TargetFl); return false; - } - + if (Chop != 0) File = OrigPath + ChopDirs(File,Chop); - + // See if the file exists if (NoStat == false || Hits < 10) { @@ -157,10 +151,10 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, if (Chop != 0) File = OrigPath + ChopDirs(File,Chop); } - + // Get the size struct stat Buf; - if (stat((CDROM + Prefix + File).c_str(),&Buf) != 0 || + if (stat((CDROM + Prefix + File).c_str(),&Buf) != 0 || Buf.st_size == 0) { bool Mangled = false; @@ -173,7 +167,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, File.replace(Start,End-Start,"binary-all"); Mangled = true; } - + if (Mangled == false || stat((CDROM + Prefix + File).c_str(),&Buf) != 0) { @@ -181,9 +175,9 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, clog << "Missed(2): " << OrigFile << endl; NotFound++; continue; - } - } - + } + } + // Size match if ((unsigned long long)Buf.st_size != Size) { @@ -193,21 +187,17 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, continue; } } - + Packages++; Hits++; - - if (RewriteEntry(TargetFl,File) == false) - { - fclose(TargetFl); + + if (RewriteEntry(Target, File) == false) return false; - } } - fclose(TargetFl); if (Debug == true) cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl; - + if (_config->FindB("APT::CDROM::NoAct",false) == false) { // Move out of the partial directory @@ -218,39 +208,38 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, return _error->Errno("rename","Failed to rename"); ChangeOwnerAndPermissionOfFile("CopyPackages", FinalF.c_str(), "root", "root", 0644); } - + /* Mangle the source to be in the proper notation with - prefix dist [component] */ + prefix dist [component] */ *I = string(*I,Prefix.length()); ConvertToSourceList(CDROM,*I); *I = Prefix + ' ' + *I; - + CurrentSize += FileSize; - } + } if(Progress) Progress->Done(); - + // Some stats if(log) { stringstream msg; if(NotFound == 0 && WrongSize == 0) ioprintf(msg, _("Wrote %i records.\n"), Packages); else if (NotFound != 0 && WrongSize == 0) - ioprintf(msg, _("Wrote %i records with %i missing files.\n"), + ioprintf(msg, _("Wrote %i records with %i missing files.\n"), Packages, NotFound); else if (NotFound == 0 && WrongSize != 0) - ioprintf(msg, _("Wrote %i records with %i mismatched files\n"), + ioprintf(msg, _("Wrote %i records with %i mismatched files\n"), Packages, WrongSize); if (NotFound != 0 && WrongSize != 0) ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize); } - + if (Packages == 0) _error->Warning("No valid records were found."); if (NotFound + WrongSize > 10) _error->Warning("A lot of entries were discarded, something may be wrong.\n"); - return true; } @@ -267,10 +256,10 @@ string IndexCopy::ChopDirs(string Path,unsigned int Depth) Depth--; } while (I != string::npos && Depth != 0); - + if (I == string::npos) return string(); - + return string(Path,I+1); } /*}}}*/ @@ -433,17 +422,15 @@ bool PackageCopy::GetFile(string &File,unsigned long long &Size) } /*}}}*/ // PackageCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool PackageCopy::RewriteEntry(FILE *Target,string File) +bool PackageCopy::RewriteEntry(FileFd &Target,string const &File) { - TFRewriteData Changes[] = {{ "Filename", File.c_str(), NULL }, - { NULL, NULL, NULL }}; - - if (TFRewrite(Target,*Section,TFRewritePackageOrder,Changes) == false) + string const Dir(File,0,File.rfind('/')); + std::vector Changes; + Changes.push_back(pkgTagSection::Tag::Rewrite("Filename", File)); + + if (Section->Write(Target, TFRewritePackageOrder, Changes) == false) return false; - fputc('\n',Target); - return true; + return Target.Write("\n", 1); } /*}}}*/ // SourceCopy::GetFile - Get the file information from the section /*{{{*/ @@ -478,23 +465,18 @@ bool SourceCopy::GetFile(string &File,unsigned long long &Size) } /*}}}*/ // SourceCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool SourceCopy::RewriteEntry(FILE *Target,string File) +bool SourceCopy::RewriteEntry(FileFd &Target, std::string const &File) { - string Dir(File,0,File.rfind('/')); - TFRewriteData Changes[] = {{ "Directory", Dir.c_str(), NULL }, - { NULL, NULL, NULL }}; - - if (TFRewrite(Target,*Section,TFRewriteSourceOrder,Changes) == false) + string const Dir(File,0,File.rfind('/')); + std::vector Changes; + Changes.push_back(pkgTagSection::Tag::Rewrite("Directory", Dir)); + + if (Section->Write(Target, TFRewriteSourceOrder, Changes) == false) return false; - fputc('\n',Target); - return true; + return Target.Write("\n", 1); } /*}}}*/ -// SigVerify::Verify - Verify a files md5sum against its metaindex /*{{{*/ -// --------------------------------------------------------------------- -/* */ +// SigVerify::Verify - Verify a files md5sum against its metaindex /*{{{*/ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex) { const indexRecords::checkSum *Record = MetaIndex->Lookup(file); @@ -702,7 +684,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ pkgTagFile Parser(&Pkg); if (_error->PendingError() == true) return false; - + // Open the output file char S[400]; snprintf(S,sizeof(S),"cdrom:[%s]/%s",Name.c_str(), @@ -719,10 +701,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ } if (_error->PendingError() == true) return false; - FILE *TargetFl = fdopen(dup(Target.Fd()),"w"); - if (TargetFl == 0) - return _error->Errno("fdopen","Failed to reopen fd"); - + // Setup the progress meter if(Progress) Progress->OverallProgress(CurrentSize,TotalSize,FileSize, @@ -740,20 +719,16 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ if(Progress) Progress->Progress(Parser.Offset()); - const char *Start; - const char *Stop; - Section.GetSection(Start,Stop); - fwrite(Start,Stop-Start, 1, TargetFl); - fputc('\n',TargetFl); + if (Section.Write(Target) == false || Target.Write("\n", 1) == false) + return false; Packages++; Hits++; } - fclose(TargetFl); if (Debug == true) cout << " Processed by using Prefix '" << Prefix << "' and chop " << endl; - + if (_config->FindB("APT::CDROM::NoAct",false) == false) { // Move out of the partial directory @@ -764,34 +739,32 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ return _error->Errno("rename","Failed to rename"); ChangeOwnerAndPermissionOfFile("CopyTranslations", FinalF.c_str(), "root", "root", 0644); } - - + CurrentSize += FileSize; - } + } if(Progress) Progress->Done(); - + // Some stats if(log) { stringstream msg; if(NotFound == 0 && WrongSize == 0) ioprintf(msg, _("Wrote %i records.\n"), Packages); else if (NotFound != 0 && WrongSize == 0) - ioprintf(msg, _("Wrote %i records with %i missing files.\n"), + ioprintf(msg, _("Wrote %i records with %i missing files.\n"), Packages, NotFound); else if (NotFound == 0 && WrongSize != 0) - ioprintf(msg, _("Wrote %i records with %i mismatched files\n"), + ioprintf(msg, _("Wrote %i records with %i mismatched files\n"), Packages, WrongSize); if (NotFound != 0 && WrongSize != 0) ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize); } - + if (Packages == 0) _error->Warning("No valid records were found."); if (NotFound + WrongSize > 10) _error->Warning("A lot of entries were discarded, something may be wrong.\n"); - return true; } diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h index 701beb075..729b0c8cb 100644 --- a/apt-pkg/indexcopy.h +++ b/apt-pkg/indexcopy.h @@ -28,6 +28,7 @@ using std::vector; class pkgTagSection; class indexRecords; class pkgCdromStatus; +class FileFd; class IndexCopy /*{{{*/ { @@ -45,7 +46,7 @@ class IndexCopy /*{{{*/ void ConvertToSourceList(std::string CD,std::string &Path); bool GrabFirst(std::string Path,std::string &To,unsigned int Depth); virtual bool GetFile(std::string &Filename,unsigned long long &Size) = 0; - virtual bool RewriteEntry(FILE *Target,std::string File) = 0; + virtual bool RewriteEntry(FileFd &Target, std::string const &File) = 0; virtual const char *GetFileName() = 0; virtual const char *Type() = 0; @@ -61,7 +62,7 @@ class PackageCopy : public IndexCopy /*{{{*/ protected: virtual bool GetFile(std::string &Filename,unsigned long long &Size); - virtual bool RewriteEntry(FILE *Target,std::string File); + virtual bool RewriteEntry(FileFd &Target, std::string const &File); virtual const char *GetFileName() {return "Packages";}; virtual const char *Type() {return "Package";}; @@ -72,7 +73,7 @@ class SourceCopy : public IndexCopy /*{{{*/ protected: virtual bool GetFile(std::string &Filename,unsigned long long &Size); - virtual bool RewriteEntry(FILE *Target,std::string File); + virtual bool RewriteEntry(FileFd &Target, std::string const &File); virtual const char *GetFileName() {return "Sources";}; virtual const char *Type() {return "Source";}; -- cgit v1.2.3-70-g09d2