]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/deb/dpkgpm.cc
fix memory leaks reported by -fsanitize
[apt.git] / apt-pkg / deb / dpkgpm.cc
index 3fbda05522ef5dccf7dcc2691597a253ce5facc3..3594a6efe989980f5cc95062ae4e123334c7496e 100644 (file)
@@ -73,7 +73,8 @@ public:
    pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0),
                        term_out(NULL), history_out(NULL),
                        progress(NULL), tt_is_valid(false), master(-1),
-                       slave(NULL), protect_slave_from_dying(-1)
+                       slave(NULL), protect_slave_from_dying(-1),
+                       direct_stdin(false)
    {
       dpkgbuf[0] = '\0';
    }
@@ -100,6 +101,7 @@ public:
    sigset_t sigmask;
    sigset_t original_sigmask;
 
+   bool direct_stdin;
 };
 
 namespace
@@ -203,8 +205,10 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg)
    for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
       for (pkgCache::VerFileIterator Vf = Ver.FileList(); Vf.end() == false; ++Vf)
         for (pkgCache::PkgFileIterator F = Vf.File(); F.end() == false; ++F)
-           if (F->Archive != 0 && strcmp(F.Archive(), "now") == 0)
+        {
+           if (F.Archive() != 0 && strcmp(F.Archive(), "now") == 0)
               return Ver;
+        }
    return Ver;
 }
                                                                        /*}}}*/
@@ -212,10 +216,9 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg)
 // DPkgPM::pkgDPkgPM - Constructor                                     /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
-   : pkgPackageManager(Cache), pkgFailures(0), PackagesDone(0), PackagesTotal(0)
+pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache)
+   : pkgPackageManager(Cache),d(new pkgDPkgPMPrivate()), pkgFailures(0), PackagesDone(0), PackagesTotal(0)
 {
-   d = new pkgDPkgPMPrivate();
 }
                                                                        /*}}}*/
 // DPkgPM::pkgDPkgPM - Destructor                                      /*{{{*/
@@ -1039,6 +1042,12 @@ void pkgDPkgPM::BuildPackagesProgressMap()
         PackagesTotal++;
       }
    }
+   /* one extra: We don't want the progress bar to reach 100%, especially not
+      if we call dpkg --configure --pending and process a bunch of triggers
+      while showing 100%. Also, spindown takes a while, so never reaching 100%
+      is way more correct than reaching 100% while still doing stuff even if
+      doing it this way is slightly bending the rules */
+   ++PackagesTotal;
 }
                                                                         /*}}}*/
 bool pkgDPkgPM::Go(int StatusFd)
@@ -1063,6 +1072,9 @@ void pkgDPkgPM::StartPtyMagic()
       return;
    }
 
+   if (isatty(STDIN_FILENO) == 0)
+      d->direct_stdin = true;
+
    _error->PushToStack();
 
    d->master = posix_openpt(O_RDWR | O_NOCTTY);
@@ -1121,7 +1133,7 @@ void pkgDPkgPM::StartPtyMagic()
               on kfreebsd we get an incorrect ("step like") output then while it has
               no problem with closing all references… so to avoid platform specific
               code here we combine both and be happy once more */
-           d->protect_slave_from_dying = open(d->slave, O_RDWR | O_CLOEXEC);
+           d->protect_slave_from_dying = open(d->slave, O_RDWR | O_CLOEXEC | O_NOCTTY);
         }
       }
    }
@@ -1153,14 +1165,17 @@ void pkgDPkgPM::SetupSlavePtyMagic()
    if (setsid() == -1)
       _error->FatalE("setsid", "Starting a new session for child failed!");
 
-   int const slaveFd = open(d->slave, O_RDWR);
+   int const slaveFd = open(d->slave, O_RDWR | O_NOCTTY);
    if (slaveFd == -1)
       _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
    else if (ioctl(slaveFd, TIOCSCTTY, 0) < 0)
       _error->FatalE("ioctl", "Setting TIOCSCTTY for slave fd %d failed!", slaveFd);
    else
    {
-      for (unsigned short i = 0; i < 3; ++i)
+      unsigned short i = 0;
+      if (d->direct_stdin == true)
+        ++i;
+      for (; i < 3; ++i)
         if (dup2(slaveFd, i) == -1)
            _error->FatalE("dup2", "Dupping %d to %d in child failed!", slaveFd, i);
 
@@ -1266,9 +1281,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
 
    // support subpressing of triggers processing for special
    // cases like d-i that runs the triggers handling manually
-   bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all");
    bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false);
-   if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true)
+   if (_config->FindB("DPkg::ConfigurePending", true) == true)
       List.push_back(Item(Item::ConfigurePending, PkgIterator()));
 
    // for the progress
@@ -1470,6 +1484,10 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
              a != Args.end(); ++a)
            clog << *a << ' ';
         clog << endl;
+        for (std::vector<char *>::const_iterator p = Packages.begin();
+              p != Packages.end(); ++p)
+           free(*p);
+        Packages.clear();
         continue;
       }
       Args.push_back(NULL);
@@ -1577,8 +1595,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
 
         // wait for input or output here
         FD_ZERO(&rfds);
-        if (d->master >= 0 && !d->stdin_is_dev_null)
-           FD_SET(0, &rfds); 
+        if (d->master >= 0 && d->direct_stdin == false && d->stdin_is_dev_null == false)
+           FD_SET(STDIN_FILENO, &rfds);
         FD_SET(_dpkgin, &rfds);
         if(d->master >= 0)
            FD_SET(d->master, &rfds);
@@ -1877,8 +1895,15 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
       }
    }
 
-   // log the ordering 
-   const char *ops_str[] = {"Install", "Configure","Remove","Purge"};
+   // log the ordering, see dpkgpm.h and the "Ops" enum there
+   const char *ops_str[] = {
+      "Install",
+      "Configure",
+      "Remove",
+      "Purge",
+      "ConfigurePending",
+      "TriggersPending",
+   };
    fprintf(report, "AptOrdering:\n");
    for (vector<Item>::iterator I = List.begin(); I != List.end(); ++I)
       if ((*I).Pkg != NULL)