Changeset 2124

Show
Ignore:
Timestamp:
03/10/2008 07:20:27 PM (4 months ago)
Author:
jan
Message:

fixed handling of waitpid() == EINTR mod_ssi on solaris

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/lighttpd-1.4.x/NEWS

    r2123 r2124  
    5151  * workaround #1587: require userdir.path to be set to enable mod_userdir (empty string allowed) 
    5252  * make configure checks for --with-pcre, --with-zlib and --with-bzip2 failing if the headers aren't found 
     53  * fixed handling of waitpid() == EINTR mod_ssi on solaris  
    5354 
    5455- 1.4.18 - 2007-09-09 
  • branches/lighttpd-1.4.x/src/mod_ssi.c

    r2054 r2124  
    729729                        int status; 
    730730                        ssize_t r; 
     731                        int was_interrupted = 0; 
    731732 
    732733                        close(from_exec_fds[1]); 
     
    735736 
    736737                        /* 
    737                          * FIXME: if we get interrupted by a SIGCHILD we count this as error 
    738                          * 
    739                          * for now it only happened on OpenBSD. 
    740                          * 
    741                          * that leads to zombies and missing output 
     738                         * OpenBSD and Solaris send a EINTR on SIGCHILD even if we ignore it 
    742739                         */ 
    743                         if (-1 == waitpid(pid, &status, 0)) { 
    744                                 log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed:", strerror(errno)); 
    745                         } else if (WIFEXITED(status)) { 
    746                                 int toread; 
    747                                 /* read everything from client and paste it into the output */ 
    748  
    749                                 while(1) { 
    750                                         if (ioctl(from_exec_fds[0], FIONREAD, &toread)) { 
    751                                                 log_error_write(srv, __FILE__, __LINE__, "s", 
    752                                                         "unexpected end-of-file (perhaps the ssi-exec process died)"); 
    753                                                 return -1; 
     740                        do { 
     741                                if (-1 == waitpid(pid, &status, 0)) { 
     742                                        if (errno == EINTR) { 
     743                                                was_interrupted++; 
     744                                        } else { 
     745                                                was_interrupted = 0; 
     746                                                log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed:", strerror(errno)); 
    754747                                        } 
    755  
    756                                         if (toread > 0) { 
    757                                                 b = chunkqueue_get_append_buffer(con->write_queue); 
    758  
    759                                                 buffer_prepare_copy(b, toread + 1); 
    760  
    761                                                 if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) { 
    762                                                         /* read failed */ 
     748                                } else if (WIFEXITED(status)) { 
     749                                        int toread; 
     750                                        /* read everything from client and paste it into the output */ 
     751                                        was_interrupted = 0; 
     752         
     753                                        while(1) { 
     754                                                if (ioctl(from_exec_fds[0], FIONREAD, &toread)) { 
     755                                                        log_error_write(srv, __FILE__, __LINE__, "s", 
     756                                                                "unexpected end-of-file (perhaps the ssi-exec process died)"); 
     757                                                        return -1; 
     758                                                } 
     759         
     760                                                if (toread > 0) { 
     761                                                        b = chunkqueue_get_append_buffer(con->write_queue); 
     762         
     763                                                        buffer_prepare_copy(b, toread + 1); 
     764         
     765                                                        if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) { 
     766                                                                /* read failed */ 
     767                                                                break; 
     768                                                        } else { 
     769                                                                b->used = r; 
     770                                                                b->ptr[b->used++] = '\0'; 
     771                                                        } 
     772                                                } else { 
    763773                                                        break; 
    764                                                 } else { 
    765                                                         b->used = r; 
    766                                                         b->ptr[b->used++] = '\0'; 
    767774                                                } 
    768                                         } else { 
    769                                                 break; 
    770775                                        } 
     776                                } else { 
     777                                        was_interrupted = 0; 
     778                                        log_error_write(srv, __FILE__, __LINE__, "s", "process exited abnormally"); 
    771779                                } 
    772                         } else { 
    773                                 log_error_write(srv, __FILE__, __LINE__, "s", "process exited abnormally"); 
    774                         } 
     780                        } while (was_interrupted > 0 && was_interrupted < 4); /* if waitpid() gets interrupted, retry, but max 4 times */ 
     781 
    775782                        close(from_exec_fds[0]); 
    776783