]> git.saurik.com Git - apt.git/commitdiff
convert EDSP to be based on FileFd instead of FILE*
authorDavid Kalnischkies <david@kalnischkies.de>
Tue, 26 Apr 2016 10:26:12 +0000 (12:26 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Fri, 20 May 2016 12:18:36 +0000 (14:18 +0200)
I doubt there is any non-src:apt usage of these interfaces.

apt-pkg/contrib/fileutl.h
apt-pkg/edsp.cc
apt-pkg/edsp.h
cmdline/apt-dump-solver.cc
cmdline/apt-internal-solver.cc

index f33f7804b0d65f1574f462c7bbbb4bffd5fe3233..13e9c610fd6ab7eb8a3662846662ed84d19c6170 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <apt-pkg/macros.h>
 #include <apt-pkg/aptconfiguration.h>
+#ifdef APT_PKG_EXPOSE_STRING_VIEW
+#include <apt-pkg/string_view.h>
+#endif
 
 #include <string>
 #include <vector>
@@ -89,6 +92,9 @@ class FileFd
    char* ReadLine(char *To, unsigned long long const Size);
    bool Flush();
    bool Write(const void *From,unsigned long long Size);
+#ifdef APT_PKG_EXPOSE_STRING_VIEW
+   APT_HIDDEN bool Write(APT::StringView From) { return Write(From.data(), From.size()); }
+#endif
    bool static Write(int Fd, const void *From, unsigned long long Size);
    bool Seek(unsigned long long To);
    bool Skip(unsigned long long To);
index 8414c6a23058a17c6272fb07e99b2c6a86a6f43d..abe68065cfadbd84512ba6047fcde6205ee23510 100644 (file)
@@ -55,10 +55,12 @@ static void WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::Pkg
        (Cache[Pkg].Keep() == true && Cache[Pkg].Protect() == true))
       fprintf(output, "Hold: yes\n");
    fprintf(output, "APT-ID: %d\n", Ver->ID);
-   fprintf(output, "Priority: %s\n", PrioMap[Ver->Priority]);
+   if (PrioMap[Ver->Priority] != nullptr)
+      fprintf(output, "Priority: %s\n", PrioMap[Ver->Priority]);
    if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
       fprintf(output, "Essential: yes\n");
-   fprintf(output, "Section: %s\n", Ver.Section());
+   if (Ver->Section != 0)
+      fprintf(output, "Section: %s\n", Ver.Section());
    if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
       fprintf(output, "Multi-Arch: allowed\n");
    else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
@@ -84,6 +86,57 @@ static void WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::Pkg
       fprintf(output, "APT-Candidate: yes\n");
    if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
       fprintf(output, "APT-Automatic: yes\n");
+}
+static bool WriteScenarioVersion(pkgDepCache &Cache, FileFd &output, pkgCache::PkgIterator const &Pkg,
+                               pkgCache::VerIterator const &Ver)
+{
+   bool Okay = output.Write("Package: ") && output.Write(Pkg.Name());
+   Okay &= output.Write("\nSource: ") && output.Write(Ver.SourcePkgName());
+   Okay &= output.Write("\nArchitecture: ") && output.Write(Ver.Arch());
+   Okay &= output.Write("\nVersion: ") && output.Write(Ver.VerStr());
+   Okay &= output.Write("\nSource-Version: ") && output.Write(Ver.SourceVerStr());
+   if (Pkg.CurrentVer() == Ver)
+      Okay &= output.Write("\nInstalled: yes");
+   if (Pkg->SelectedState == pkgCache::State::Hold ||
+       (Cache[Pkg].Keep() == true && Cache[Pkg].Protect() == true))
+      Okay &= output.Write("\nHold: yes");
+   std::string aptid;
+   strprintf(aptid, "\nAPT-ID: %d", Ver->ID);
+   Okay &= output.Write(aptid);
+   if (PrioMap[Ver->Priority] != nullptr)
+      Okay &= output.Write("\nPriority: ") && output.Write(PrioMap[Ver->Priority]);
+   if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+      Okay &= output.Write("\nEssential: yes");
+   if (Ver->Section != 0)
+      Okay &= output.Write("\nSection: ") && output.Write(Ver.Section());
+   if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
+      Okay &= output.Write("\nMulti-Arch: allowed");
+   else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
+      Okay &= output.Write("\nMulti-Arch: foreign");
+   else if ((Ver->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
+      Okay &= output.Write("\nMulti-Arch: same");
+   std::set<string> Releases;
+   for (pkgCache::VerFileIterator I = Ver.FileList(); I.end() == false; ++I) {
+      pkgCache::PkgFileIterator File = I.File();
+      if (File.Flagged(pkgCache::Flag::NotSource) == false) {
+        string Release = File.RelStr();
+        if (!Release.empty())
+           Releases.insert(Release);
+      }
+   }
+   if (!Releases.empty()) {
+       Okay &= output.Write("\nAPT-Release:");
+       for (std::set<string>::iterator R = Releases.begin(); R != Releases.end(); ++R)
+          Okay &= output.Write("\n ") && output.Write(*R);
+   }
+   std::string aptpin;
+   strprintf(aptpin, "\nAPT-Pin: %d", Cache.GetPolicy().GetPriority(Ver));
+   Okay &= output.Write(aptpin);
+   if (Cache.GetCandidateVersion(Pkg) == Ver)
+      Okay &= output.Write("\nAPT-Candidate: yes");
+   if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
+      Okay &= output.Write("\nAPT-Automatic: yes");
+   return Okay;
 }
                                                                        /*}}}*/
 // WriteScenarioDependency                                             /*{{{*/
@@ -116,12 +169,54 @@ static void WriteScenarioDependency( FILE* output, pkgCache::VerIterator const &
    {
       if (Prv.IsMultiArchImplicit() == true)
         continue;
-      provides.append(", ").append(Prv.Name());
+      if (provides.empty() == false)
+        provides.append(", ");
+      provides.append(Prv.Name());
       if (Prv->ProvideVersion != 0)
         provides.append(" (= ").append(Prv.ProvideVersion()).append(")");
    }
    if (provides.empty() == false)
-      fprintf(output, "Provides: %s\n", provides.c_str()+2);
+      fprintf(output, "Provides: %s\n", provides.c_str());
+}
+static bool WriteScenarioDependency(FileFd &output, pkgCache::VerIterator const &Ver)
+{
+   std::string dependencies[pkgCache::Dep::Enhances + 1];
+   bool orGroup = false;
+   for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep)
+   {
+      if (Dep.IsImplicit() == true)
+        continue;
+      if (orGroup == false && dependencies[Dep->Type].empty() == false)
+        dependencies[Dep->Type].append(", ");
+      dependencies[Dep->Type].append(Dep.TargetPkg().Name());
+      if (Dep->Version != 0)
+        dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")");
+      if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
+      {
+        dependencies[Dep->Type].append(" | ");
+        orGroup = true;
+      }
+      else
+        orGroup = false;
+   }
+   bool Okay = true;
+   for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i)
+      if (dependencies[i].empty() == false)
+        Okay &= output.Write("\n") && output.Write(DepMap[i]) && output.Write(": ") && output.Write(dependencies[i]);
+   string provides;
+   for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv)
+   {
+      if (Prv.IsMultiArchImplicit() == true)
+        continue;
+      if (provides.empty() == false)
+        provides.append(", ");
+      provides.append(Prv.Name());
+      if (Prv->ProvideVersion != 0)
+        provides.append(" (= ").append(Prv.ProvideVersion()).append(")");
+   }
+   if (provides.empty() == false)
+      Okay &= output.Write("\nProvides: ") && output.Write(provides);
+   return Okay && output.Write("\n");
 }
                                                                        /*}}}*/
 // WriteScenarioLimitedDependency                                      /*{{{*/
@@ -139,7 +234,8 @@ static void WriteScenarioLimitedDependency(FILE* output,
       {
         if (pkgset.find(Dep.TargetPkg()) == pkgset.end())
            continue;
-        dependencies[Dep->Type].append(", ");
+        if (dependencies[Dep->Type].empty() == false)
+           dependencies[Dep->Type].append(", ");
       }
       else if (pkgset.find(Dep.TargetPkg()) == pkgset.end())
       {
@@ -162,7 +258,7 @@ static void WriteScenarioLimitedDependency(FILE* output,
    }
    for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i)
       if (dependencies[i].empty() == false)
-        fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str()+2);
+        fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str());
    string provides;
    for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv)
    {
@@ -170,10 +266,71 @@ static void WriteScenarioLimitedDependency(FILE* output,
         continue;
       if (pkgset.find(Prv.ParentPkg()) == pkgset.end())
         continue;
-      provides.append(", ").append(Prv.Name());
+      if (provides.empty() == false)
+        provides.append(", ");
+      provides.append(Prv.Name());
+      if (Prv->ProvideVersion != 0)
+        provides.append(" (= ").append(Prv.ProvideVersion()).append(")");
    }
    if (provides.empty() == false)
-      fprintf(output, "Provides: %s\n", provides.c_str()+2);
+      fprintf(output, "Provides: %s\n", provides.c_str());
+}
+static bool WriteScenarioLimitedDependency(FileFd &output,
+                                         pkgCache::VerIterator const &Ver,
+                                         APT::PackageSet const &pkgset)
+{
+   std::string dependencies[pkgCache::Dep::Enhances + 1];
+   bool orGroup = false;
+   for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep)
+   {
+      if (Dep.IsImplicit() == true)
+        continue;
+      if (orGroup == false)
+      {
+        if (pkgset.find(Dep.TargetPkg()) == pkgset.end())
+           continue;
+        if (dependencies[Dep->Type].empty() == false)
+           dependencies[Dep->Type].append(", ");
+      }
+      else if (pkgset.find(Dep.TargetPkg()) == pkgset.end())
+      {
+        if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
+           continue;
+        dependencies[Dep->Type].erase(dependencies[Dep->Type].end()-3, dependencies[Dep->Type].end());
+        orGroup = false;
+        continue;
+      }
+      dependencies[Dep->Type].append(Dep.TargetPkg().Name());
+      if (Dep->Version != 0)
+        dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")");
+      if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
+      {
+        dependencies[Dep->Type].append(" | ");
+        orGroup = true;
+      }
+      else
+        orGroup = false;
+   }
+   bool Okay = true;
+   for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i)
+      if (dependencies[i].empty() == false)
+        Okay &= output.Write("\n") && output.Write(DepMap[i]) && output.Write(": ") && output.Write(dependencies[i]);
+   string provides;
+   for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv)
+   {
+      if (Prv.IsMultiArchImplicit() == true)
+        continue;
+      if (pkgset.find(Prv.ParentPkg()) == pkgset.end())
+        continue;
+      if (provides.empty() == false)
+        provides.append(", ");
+      provides.append(Prv.Name());
+      if (Prv->ProvideVersion != 0)
+        provides.append(" (= ").append(Prv.ProvideVersion()).append(")");
+   }
+   if (provides.empty() == false)
+      Okay &= output.Write("\nProvides: ") && output.Write(provides);
+   return Okay && output.Write("\n");
 }
                                                                        /*}}}*/
 static bool SkipUnavailableVersions(pkgDepCache &Cache, pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver)/*{{{*/
@@ -218,6 +375,31 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress)
       }
    }
    return true;
+}
+bool EDSP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress *Progress)
+{
+   if (Progress != NULL)
+      Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver"));
+   unsigned long p = 0;
+   bool Okay = true;
+   std::vector<std::string> archs = APT::Configuration::getArchitectures();
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
+   {
+      std::string const arch = Pkg.Arch();
+      if (std::find(archs.begin(), archs.end(), arch) == archs.end())
+        continue;
+      for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p)
+      {
+        if (SkipUnavailableVersions(Cache, Pkg, Ver))
+           continue;
+        Okay &= WriteScenarioVersion(Cache, output, Pkg, Ver);
+        Okay &= WriteScenarioDependency(output, Ver);
+        Okay &= output.Write("\n");
+        if (Progress != NULL && p % 100 == 0)
+           Progress->Progress(p);
+      }
+   }
+   return true;
 }
                                                                        /*}}}*/
 // EDSP::WriteLimitedScenario - to the given file descriptor           /*{{{*/
@@ -242,6 +424,29 @@ bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
    if (Progress != NULL)
       Progress->Done();
    return true;
+}
+bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FileFd &output,
+                               APT::PackageSet const &pkgset,
+                               OpProgress *Progress)
+{
+   if (Progress != NULL)
+      Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver"));
+   unsigned long p  = 0;
+   bool Okay = true;
+   for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg, ++p)
+      for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
+      {
+        if (SkipUnavailableVersions(Cache, Pkg, Ver))
+           continue;
+        Okay &= WriteScenarioVersion(Cache, output, Pkg, Ver);
+        Okay &= WriteScenarioLimitedDependency(output, Ver, pkgset);
+        Okay &= output.Write("\n");
+        if (Progress != NULL && p % 100 == 0)
+           Progress->Progress(p);
+      }
+   if (Progress != NULL)
+      Progress->Done();
+   return Okay;
 }
                                                                        /*}}}*/
 // EDSP::WriteRequest - to the given file descriptor                   /*{{{*/
@@ -298,6 +503,57 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
       fprintf(output, "Preferences: %s\n", solverpref.c_str());
    fprintf(output, "\n");
    return true;
+}
+bool EDSP::WriteRequest(pkgDepCache &Cache, FileFd &output, bool const Upgrade,
+                       bool const DistUpgrade, bool const AutoRemove,
+                       OpProgress *Progress)
+{
+   if (Progress != NULL)
+      Progress->SubProgress(Cache.Head().PackageCount, _("Send request to solver"));
+   unsigned long p = 0;
+   string del, inst;
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg, ++p)
+   {
+      if (Progress != NULL && p % 100 == 0)
+         Progress->Progress(p);
+      string* req;
+      pkgDepCache::StateCache &P = Cache[Pkg];
+      if (P.Delete() == true)
+        req = &del;
+      else if (P.NewInstall() == true || P.Upgrade() == true || P.ReInstall() == true ||
+              (P.Mode == pkgDepCache::ModeKeep && (P.iFlags & pkgDepCache::Protected) == pkgDepCache::Protected))
+        req = &inst;
+      else
+        continue;
+      req->append(" ").append(Pkg.FullName());
+   }
+   bool Okay = output.Write("Request: EDSP 0.5\n");
+
+   const char *arch = _config->Find("APT::Architecture").c_str();
+   std::vector<string> archs = APT::Configuration::getArchitectures();
+   Okay &= output.Write("Architecture: ") && output.Write(arch) && output.Write("\n");
+   Okay &= output.Write("Architectures:");
+   for (std::vector<string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
+       Okay &= output.Write(" ") && output.Write(*a);
+   Okay &= output.Write("\n");
+
+   if (del.empty() == false)
+      Okay &= output.Write("Remove:") && output.Write(del) && output.Write("\n");
+   if (inst.empty() == false)
+      Okay &= output.Write("Install:") && output.Write(inst) && output.Write("\n");
+   if (Upgrade == true)
+      Okay &= output.Write("Upgrade: yes\n");
+   if (DistUpgrade == true)
+      Okay &= output.Write("Dist-Upgrade: yes\n");
+   if (AutoRemove == true)
+      Okay &= output.Write("Autoremove: yes\n");
+   if (_config->FindB("APT::Solver::Strict-Pinning", true) == false)
+      Okay &= output.Write("Strict-Pinning: no\n");
+   string solverpref("APT::Solver::");
+   solverpref.append(_config->Find("APT::Solver", "internal")).append("::Preferences");
+   if (_config->Exists(solverpref) == true)
+      Okay &= output.Write("Preferences: ") && output.Write(_config->Find(solverpref,"")) && output.Write("\n");
+   return Okay && output.Write("\n");
 }
                                                                        /*}}}*/
 // EDSP::ReadResponse - from the given file descriptor                 /*{{{*/
@@ -562,6 +818,39 @@ bool EDSP::WriteSolution(pkgDepCache &Cache, FILE* output)
    }
 
    return true;
+}
+bool EDSP::WriteSolution(pkgDepCache &Cache, FileFd &output)
+{
+   bool const Debug = _config->FindB("Debug::EDSP::WriteSolution", false);
+   bool Okay = true;
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
+   {
+      std::string action;
+      if (Cache[Pkg].Delete() == true)
+        strprintf(action, "Remove: %d\n", Pkg.CurrentVer()->ID);
+      else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true)
+        strprintf(action, "Install: %d\n", Cache.GetCandidateVersion(Pkg)->ID);
+      else if (Cache[Pkg].Garbage == true)
+        strprintf(action, "Autoremove: %d\n", Pkg.CurrentVer()->ID);
+      else
+        continue;
+
+      Okay &= output.Write(action);
+
+      if (Debug)
+      {
+        Okay &= output.Write("Package: ") && output.Write(Pkg.FullName()) && output.Write("\nVersion: ");
+        if (Cache[Pkg].Delete() == true || Cache[Pkg].Garbage == true)
+           Okay &= output.Write(Pkg.CurrentVer().VerStr());
+        else
+           Okay &= output.Write(Cache.GetCandidateVersion(Pkg).VerStr());
+        Okay &= output.Write("\n\n");
+      }
+      else
+        Okay &= output.Write("\n");
+   }
+
+   return Okay;
 }
                                                                        /*}}}*/
 // EDSP::WriteProgess - pulse to the given file descriptor             /*{{{*/
@@ -571,6 +860,14 @@ bool EDSP::WriteProgress(unsigned short const percent, const char* const message
        fprintf(output, "Message: %s\n\n", message);
        fflush(output);
        return true;
+}
+bool EDSP::WriteProgress(unsigned short const percent, const char* const message, FileFd &output) {
+       std::string strpercent;
+       strprintf(strpercent, "Percentage: %d\n", percent);
+       return output.Write("Progress: ") && output.Write(TimeRFC1123(time(NULL))) && output.Write("\n") &&
+          output.Write(strpercent) && output.Write("Message: ") && output.Write(message) && output.Write("\n\n") &&
+          output.Flush();
+
 }
                                                                        /*}}}*/
 // EDSP::WriteError - format an error message to be send to file descriptor /*{{{*/
@@ -578,6 +875,11 @@ bool EDSP::WriteError(char const * const uuid, std::string const &message, FILE*
        fprintf(output, "Error: %s\n", uuid);
        fprintf(output, "Message: %s\n\n", SubstVar(SubstVar(message, "\n\n", "\n.\n"), "\n", "\n ").c_str());
        return true;
+}
+bool EDSP::WriteError(char const * const uuid, std::string const &message, FileFd &output) {
+   return output.Write("Error: ") && output.Write(uuid) && output.Write("\n") &&
+      output.Write("Message: ") && output.Write(SubstVar(SubstVar(message, "\n\n", "\n.\n"), "\n", "\n ")) &&
+      output.Write("\n\n");
 }
                                                                        /*}}}*/
 // EDSP::ExecuteSolver - fork requested solver and setup ipc pipes     {{{*/
@@ -643,9 +945,9 @@ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache,
        if (solver_pid == 0)
                return false;
 
-       FILE* output = fdopen(solver_in, "w");
-       if (output == NULL)
-               return _error->Errno("Resolve", "fdopen on solver stdin failed");
+       FileFd output;
+       if (output.OpenDescriptor(solver_in, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
+               return _error->Errno("ResolveExternal", "Opening solver %s stdin on fd %d for writing failed", solver, solver_in);
 
        if (Progress != NULL)
                Progress->OverallProgress(0, 100, 5, _("Execute external solver"));
@@ -653,7 +955,7 @@ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache,
        if (Progress != NULL)
                Progress->OverallProgress(5, 100, 20, _("Execute external solver"));
        EDSP::WriteScenario(Cache, output, Progress);
-       fclose(output);
+       output.Close();
 
        if (Progress != NULL)
                Progress->OverallProgress(25, 100, 75, _("Execute external solver"));
index 2053e14e10478a335bc7e1d7e95fe8635275f052..433600bcdab5e7ca655ed7100b55d981c1c01189 100644 (file)
@@ -45,11 +45,16 @@ namespace EDSP                                                              /*{{{*/
         *
         *  \return true if request was composed successfully, otherwise false
         */
-       bool WriteRequest(pkgDepCache &Cache, FILE* output,
+       bool WriteRequest(pkgDepCache &Cache, FileFd &output,
                                 bool const upgrade = false,
                                 bool const distUpgrade = false,
                                 bool const autoRemove = false,
                                OpProgress *Progress = NULL);
+       bool WriteRequest(pkgDepCache &Cache, FILE* output,
+                                bool const upgrade = false,
+                                bool const distUpgrade = false,
+                                bool const autoRemove = false,
+                               OpProgress *Progress = NULL) APT_DEPRECATED_MSG("Use FileFd-based interface instead");
 
        /** \brief creates the scenario representing the package universe
         *
@@ -68,7 +73,8 @@ namespace EDSP                                                                /*{{{*/
         *
         *  \return true if universe was composed successfully, otherwise false
         */
-       bool WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress = NULL);
+       bool WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress *Progress = NULL);
+       bool WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress = NULL) APT_DEPRECATED_MSG("Use FileFd-based interface instead");
 
        /** \brief creates a limited scenario representing the package universe
         *
@@ -85,9 +91,12 @@ namespace EDSP                                                               /*{{{*/
         *
         *  \return true if universe was composed successfully, otherwise false
         */
-       bool WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
+       bool WriteLimitedScenario(pkgDepCache &Cache, FileFd &output,
                                         APT::PackageSet const &pkgset,
                                         OpProgress *Progress = NULL);
+       bool WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
+                                        APT::PackageSet const &pkgset,
+                                        OpProgress *Progress = NULL) APT_DEPRECATED_MSG("Use FileFd-based interface instead");
 
        /** \brief waits and acts on the information returned from the solver
         *
@@ -152,7 +161,8 @@ namespace EDSP                                                              /*{{{*/
         *
         *  \return true if solution could be written, otherwise false
         */
-       bool WriteSolution(pkgDepCache &Cache, FILE* output);
+       bool WriteSolution(pkgDepCache &Cache, FileFd &output);
+       bool WriteSolution(pkgDepCache &Cache, FILE* output) APT_DEPRECATED_MSG("Use FileFd-based interface instead");
 
        /** \brief sends a progress report
         *
@@ -160,7 +170,8 @@ namespace EDSP                                                              /*{{{*/
         *  \param message the solver wants the user to see
         *  \param output the front-end listens for progress report
         */
-       bool WriteProgress(unsigned short const percent, const char* const message, FILE* output);
+       bool WriteProgress(unsigned short const percent, const char* const message, FileFd &output);
+       bool WriteProgress(unsigned short const percent, const char* const message, FILE* output) APT_DEPRECATED_MSG("Use FileFd-based interface instead");
 
        /** \brief sends an error report
         *
@@ -177,7 +188,8 @@ namespace EDSP                                                              /*{{{*/
         *  \param message is free form text to describe the error
         *  \param output the front-end listens for error messages
         */
-       bool WriteError(char const * const uuid, std::string const &message, FILE* output);
+       bool WriteError(char const * const uuid, std::string const &message, FileFd &output);
+       bool WriteError(char const * const uuid, std::string const &message, FILE* output) APT_DEPRECATED_MSG("Use FileFd-based interface instead");
 
 
        /** \brief executes the given solver and returns the pipe ends
index 27592f22eb5f3e5258785f27cd9fd3300735f53d..cb72330590c464bfccc2674fbf5c6eae2f9fb237 100644 (file)
@@ -36,20 +36,25 @@ static bool ShowHelp() {
                                                                        /*}}}*/
 int main(int argc,const char *argv[])                                  /*{{{*/
 {
+       // we really don't need anything
+       DropPrivileges();
+
        if (argc > 1 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1],"-h") == 0 ||
            strcmp(argv[1],"-v") == 0 || strcmp(argv[1],"--version") == 0)) {
                ShowHelp();
                return 0;
        }
 
-       // we really don't need anything
-       DropPrivileges();
+       FileFd stdoutfd;
+       if (stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
+          return 1;
+
        char const * const filename = getenv("APT_EDSP_DUMP_FILENAME");
        if (filename == NULL || strlen(filename) == 0)
        {
           EDSP::WriteError("ERR_NO_FILENAME", "You have to set the environment variable APT_EDSP_DUMP_FILENAME\n"
                 "to a valid filename to store the dump of EDSP solver input in.\n"
-                "For example with: export APT_EDSP_DUMP_FILENAME=/tmp/dump.edsp", stdout);
+                "For example with: export APT_EDSP_DUMP_FILENAME=/tmp/dump.edsp", stdoutfd);
           return 0;
        }
 
@@ -62,10 +67,10 @@ int main(int argc,const char *argv[])                                       /*{{{*/
           std::ostringstream out;
           out << "Writing EDSP solver input to file '" << filename << "' failed!\n";
           _error->DumpErrors(out);
-          EDSP::WriteError("ERR_WRITE_ERROR", out.str(), stdout);
+          EDSP::WriteError("ERR_WRITE_ERROR", out.str(), stdoutfd);
           return 0;
        }
 
-       EDSP::WriteError("ERR_JUST_DUMPING", "I am too dumb, i can just dump!\nPlease use one of my friends instead!", stdout);
+       EDSP::WriteError("ERR_JUST_DUMPING", "I am too dumb, i can just dump!\nPlease use one of my friends instead!", stdoutfd);
        return 0;
 }
index b88d745c46e6cfbb02e029cad95f809317528d8a..2df1d3bef32efa9632490fec979a96999b42600f 100644 (file)
@@ -82,12 +82,14 @@ int main(int argc,const char *argv[])                                       /*{{{*/
                pkgCacheFile CacheFile;
                CacheFile.Open(NULL, false);
                APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1);
-               FILE* output = stdout;
+               FileFd output;
+               if (output.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
+                       return 2;
                if (pkgset.empty() == true)
                        EDSP::WriteScenario(CacheFile, output);
                else
                        EDSP::WriteLimitedScenario(CacheFile, output, pkgset);
-               fclose(output);
+               output.Close();
                _error->DumpErrors(std::cerr);
                return 0;
        }
@@ -102,8 +104,10 @@ int main(int argc,const char *argv[])                                      /*{{{*/
        _config->Set("APT::System", "Debian APT solver interface");
        _config->Set("APT::Solver", "internal");
        _config->Set("edsp::scenario", "/nonexistent/stdin");
-       int input = STDIN_FILENO;
-       FILE* output = stdout;
+       FileFd output;
+       if (output.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
+          DIE("stdout couldn't be opened");
+       int const input = STDIN_FILENO;
        SetNonBlock(input, false);
 
        EDSP::WriteProgress(0, "Start up solver…", output);