]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/deb/dpkgpm.cc
merged from lp:~donkult/apt/sid
[apt.git] / apt-pkg / deb / dpkgpm.cc
index 395c3fb1aed6da42338b556fa99688a31ef645bc..b37980b7ecbbdae96d210bb6ffca6a700c94d23b 100644 (file)
@@ -308,6 +308,15 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
         SetCloseExec(STDIN_FILENO,false);      
         SetCloseExec(STDERR_FILENO,false);
 
+        if (_config->FindDir("DPkg::Chroot-Directory","/") != "/") 
+        {
+           std::cerr << "Chrooting into " 
+                     << _config->FindDir("DPkg::Chroot-Directory") 
+                     << std::endl;
+           if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0)
+              _exit(100);
+        }
+
         const char *Args[4];
         Args[0] = "/bin/sh";
         Args[1] = "-c";
@@ -322,7 +331,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
         return _error->Errno("fdopen","Faild to open new FD");
       
       // Feed it the filenames.
-      bool Die = false;
       if (Version <= 1)
       {
         for (vector<Item>::iterator I = List.begin(); I != List.end(); I++)
@@ -339,14 +347,11 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
               into the pipe. */
            fprintf(F,"%s\n",I->File.c_str());
            if (ferror(F) != 0)
-           {
-              Die = true;
               break;
-           }
         }
       }
       else
-        Die = !SendV2Pkgs(F);
+        SendV2Pkgs(F);
 
       fclose(F);
       
@@ -386,8 +391,9 @@ void pkgDPkgPM::DoTerminalPty(int master)
    {
       // this happens when the child is about to exit, we
       // give it time to actually exit, otherwise we run
-      // into a race
-      usleep(500000);
+      // into a race so we sleep for half a second.
+      struct timespec sleepfor = { 0, 500000000 };
+      nanosleep(&sleepfor, NULL);
       return;
    }  
    if(len <= 0) 
@@ -660,6 +666,7 @@ bool pkgDPkgPM::OpenLog()
       if (term_out == NULL)
         return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
       setvbuf(term_out, NULL, _IONBF, 0);
+      SetCloseExec(fileno(term_out), true);
       chmod(logfile_name.c_str(), 0600);
       fprintf(term_out, "\nLog started: %s\n", timestr);
    }
@@ -884,7 +891,10 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 
       // Generate the argument list
       const char *Args[MaxArgs + 50];
-      
+      // keep track of allocated strings for multiarch package names
+      char *Packages[MaxArgs + 50];
+      unsigned int pkgcount = 0;
+
       // Now check if we are within the MaxArgs limit
       //
       // this code below is problematic, because it may happen that
@@ -992,16 +1002,27 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       }      
       else
       {
+        string const nativeArch = _config->Find("APT::Architecture");
+        unsigned long const oldSize = I->Op == Item::Configure ? Size : 0;
         for (;I != J && Size < MaxArgBytes; I++)
         {
            if((*I).Pkg.end() == true)
               continue;
            if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end())
               continue;
-           Args[n++] = I->Pkg.Name();
+           if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))
+              Args[n++] = I->Pkg.Name();
+           else
+           {
+              Packages[pkgcount] = strdup(I->Pkg.FullName(false).c_str());
+              Args[n++] = Packages[pkgcount++];
+           }
            Size += strlen(Args[n-1]);
-        }       
-      }      
+        }
+        // skip configure action if all sheduled packages disappeared
+        if (oldSize == Size)
+           continue;
+      }
       Args[n] = 0;
       J = I;
       
@@ -1148,6 +1169,11 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       sigemptyset(&sigmask);
       sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
 
+      /* clean up the temporary allocation for multiarch package names in
+         the parent, so we don't leak memory when we return. */
+      for (unsigned int i = 0; i < pkgcount; i++)
+        free(Packages[i]);
+
       // the result of the waitpid call
       int res;
       int select_ret;
@@ -1229,7 +1255,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
            strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
 
         if(dpkg_error.size() > 0)
-           _error->Error(dpkg_error.c_str());
+           _error->Error("%s", dpkg_error.c_str());
 
         if(stopOnError) 
         {
@@ -1414,7 +1440,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
       {
         while( fgets(buf, sizeof(buf), log) != NULL)
            fprintf(report, " %s", buf);
-        fclose(log);
+        pclose(log);
       }
    }
 
@@ -1430,7 +1456,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
       {
         while( fgets(buf, sizeof(buf), log) != NULL)
            fprintf(report, " %s", buf);
-        fclose(log);
+        pclose(log);
       }
    }