Michael Vogt лет назад: 18
Родитель
Сommit
cad7d95770
1 измененных файлов с 28 добавлено и 14 удалено
  1. 28 14
      apt-pkg/deb/dpkgpm.cc

+ 28 - 14
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)
@@ -816,7 +824,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) {
@@ -839,18 +852,19 @@ 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);
- 	 if (select_ret == 0) 
- 	    continue;
- 	 else if (select_ret < 0 && errno == EINTR)
- 	    continue;
- 	 else if (select_ret < 0) 
-	 {
- 	    perror("select() returned error");
- 	    continue;
- 	 } 
-
+	 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)
+  	    continue;
+  	 else if (select_ret < 0) 
+ 	 {
+  	    perror("select() returned error");
+  	    continue;
+  	 } 
+	 
 	 if(master >= 0 && FD_ISSET(master, &rfds))
 	    DoTerminalPty(master);
 	 if(master >= 0 && FD_ISSET(0, &rfds))