Quellcode durchsuchen

apt-pkg/deb/dpkgpm.cc:
- use pselect() instead of select()
- on EIO error on pty master read, usleep(0.5s) to give up timeslice
so that the child can properly exit

Michael Vogt vor 18 Jahren
Ursprung
Commit
7052511ef6
1 geänderte Dateien mit 18 neuen und 4 gelöschten Zeilen
  1. 18 4
      apt-pkg/deb/dpkgpm.cc

+ 18 - 4
apt-pkg/deb/dpkgpm.cc

@@ -357,7 +357,15 @@ void pkgDPkgPM::DoTerminalPty(int master)
    char term_buf[1024] = {0,};
 
    int len=read(master, term_buf, sizeof(term_buf));
-   if(len <= 0)
+   if(len == -1 && errno == EIO)
+   {
+      // this happens when the child is about to exit, we
+      // give it time to actually exit, otherwise we run
+      // into a race
+      usleep(500000);
+      return;
+   }  
+   if(len <= 0) 
       return;
    write(1, term_buf, len);
    if(term_out)
@@ -793,7 +801,12 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 
       // setups fds
       fd_set rfds;
-      struct timeval tv;
+      struct timespec tv;
+      sigset_t sigmask;
+      sigset_t original_sigmask;
+      sigemptyset(&sigmask);
+      sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
+
       int select_ret;
       while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
 	 if(res < 0) {
@@ -816,8 +829,9 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 if(master >= 0)
 	    FD_SET(master, &rfds);
 	 tv.tv_sec = 1;
-	 tv.tv_usec = 0;
-	 select_ret = select(max(master, _dpkgin)+1, &rfds, NULL, NULL, &tv);
+	 tv.tv_nsec = 0;
+	 select_ret = pselect(max(master, _dpkgin)+1, &rfds, NULL, NULL, 
+			      &tv, &original_sigmask);
 	 if (select_ret == 0) 
   	    continue;
   	 else if (select_ret < 0 && errno == EINTR)