]> 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 5747f11643cbc6ec335e1cedfedac843ca2602bb..b37980b7ecbbdae96d210bb6ffca6a700c94d23b 100644 (file)
@@ -391,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) 
@@ -890,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
@@ -998,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;
       
@@ -1154,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;