diff options
| author | Glenn Morris | 2013-02-15 09:31:12 -0800 |
|---|---|---|
| committer | Glenn Morris | 2013-02-15 09:31:12 -0800 |
| commit | d64d97e537301a9787a569982d67eed8ecdabe8b (patch) | |
| tree | 9eb69f45f65e4b8b3ac605e8df0aa5f8729b00a3 | |
| parent | 0063fdb148db6352a06448053227c0924110cdda (diff) | |
| parent | a7727d05be4047b4ab6c8218ad2de5e2ad8624da (diff) | |
| download | emacs-d64d97e537301a9787a569982d67eed8ecdabe8b.tar.gz emacs-d64d97e537301a9787a569982d67eed8ecdabe8b.zip | |
Merge from emacs-24; up to 2012-12-19T19:51:40Z!monnier@iro.umontreal.ca
| -rw-r--r-- | doc/lispref/ChangeLog | 2 | ||||
| -rw-r--r-- | src/ChangeLog | 24 | ||||
| -rw-r--r-- | src/w32.c | 74 | ||||
| -rw-r--r-- | src/w32proc.c | 44 |
4 files changed, 107 insertions, 37 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index ffda87384b5..d8a08ee5d3e 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | 2013-02-14 Glenn Morris <rgm@gnu.org> | 1 | 2013-02-15 Glenn Morris <rgm@gnu.org> |
| 2 | 2 | ||
| 3 | * modes.texi (Basic Major Modes): 'z' no longer bound in special-mode. | 3 | * modes.texi (Basic Major Modes): 'z' no longer bound in special-mode. |
| 4 | 4 | ||
diff --git a/src/ChangeLog b/src/ChangeLog index 448f1e1ca0f..1e1fe641ee5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,27 @@ | |||
| 1 | 2013-02-15 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * w32proc.c (new_child): Free up to 2 slots of dead processes at a | ||
| 4 | time. Improve diagnostics in DebPrint. | ||
| 5 | (reader_thread): If cp->char_avail is NULL, set the FILE_AT_EOF | ||
| 6 | flag, so that sys_select could have a chance of noticing that this | ||
| 7 | process is dead, and call a SIGCHLD handler for it. Improve | ||
| 8 | diagnostics in DebPrint. | ||
| 9 | (reap_subprocess): Reset the FILE_AT_EOF flag set by | ||
| 10 | reader_thread. | ||
| 11 | (sys_select): Watch a process whose procinfo.hProcess is non-NULL | ||
| 12 | even if its char_avail is NULL. Allows to reap subprocesses that | ||
| 13 | were forcibly deleted by delete-process. (Bug#13546) | ||
| 14 | |||
| 15 | * w32.c (sys_socket, sys_bind, sys_connect, sys_gethostname) | ||
| 16 | (sys_gethostbyname, sys_getservbyname, sys_getpeername) | ||
| 17 | (sys_shutdown, sys_setsockopt, sys_listen, sys_getsockname) | ||
| 18 | (sys_accept, sys_recvfrom, sys_sendto, fcntl): In case of failure, | ||
| 19 | make sure errno is set to an appropriate value. (Bug#13546) | ||
| 20 | (socket_to_fd): Add assertion against indexing fd_info[] with a | ||
| 21 | value that is out of bounds. | ||
| 22 | (sys_accept): If fd is negative, do not set up the child_process | ||
| 23 | structure for reading. | ||
| 24 | |||
| 1 | 2013-02-15 Dmitry Antipov <dmantipov@yandex.ru> | 25 | 2013-02-15 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 26 | ||
| 3 | * composite.c (fill_gstring_header): Remove useless prototype. | 27 | * composite.c (fill_gstring_header): Remove useless prototype. |
| @@ -6232,7 +6232,7 @@ sys_socket (int af, int type, int protocol) | |||
| 6232 | 6232 | ||
| 6233 | if (winsock_lib == NULL) | 6233 | if (winsock_lib == NULL) |
| 6234 | { | 6234 | { |
| 6235 | h_errno = ENETDOWN; | 6235 | errno = h_errno = ENETDOWN; |
| 6236 | return INVALID_SOCKET; | 6236 | return INVALID_SOCKET; |
| 6237 | } | 6237 | } |
| 6238 | 6238 | ||
| @@ -6242,7 +6242,13 @@ sys_socket (int af, int type, int protocol) | |||
| 6242 | s = pfn_socket (af, type, protocol); | 6242 | s = pfn_socket (af, type, protocol); |
| 6243 | 6243 | ||
| 6244 | if (s != INVALID_SOCKET) | 6244 | if (s != INVALID_SOCKET) |
| 6245 | return socket_to_fd (s); | 6245 | { |
| 6246 | int retval = socket_to_fd (s); | ||
| 6247 | |||
| 6248 | if (retval == -1) | ||
| 6249 | errno = h_errno; | ||
| 6250 | return retval; | ||
| 6251 | } | ||
| 6246 | 6252 | ||
| 6247 | set_errno (); | 6253 | set_errno (); |
| 6248 | return -1; | 6254 | return -1; |
| @@ -6309,6 +6315,7 @@ socket_to_fd (SOCKET s) | |||
| 6309 | } | 6315 | } |
| 6310 | } | 6316 | } |
| 6311 | } | 6317 | } |
| 6318 | eassert (fd < MAXDESC); | ||
| 6312 | fd_info[fd].hnd = (HANDLE) s; | 6319 | fd_info[fd].hnd = (HANDLE) s; |
| 6313 | 6320 | ||
| 6314 | /* set our own internal flags */ | 6321 | /* set our own internal flags */ |
| @@ -6347,7 +6354,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen) | |||
| 6347 | { | 6354 | { |
| 6348 | if (winsock_lib == NULL) | 6355 | if (winsock_lib == NULL) |
| 6349 | { | 6356 | { |
| 6350 | h_errno = ENOTSOCK; | 6357 | errno = h_errno = ENOTSOCK; |
| 6351 | return SOCKET_ERROR; | 6358 | return SOCKET_ERROR; |
| 6352 | } | 6359 | } |
| 6353 | 6360 | ||
| @@ -6359,7 +6366,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen) | |||
| 6359 | set_errno (); | 6366 | set_errno (); |
| 6360 | return rc; | 6367 | return rc; |
| 6361 | } | 6368 | } |
| 6362 | h_errno = ENOTSOCK; | 6369 | errno = h_errno = ENOTSOCK; |
| 6363 | return SOCKET_ERROR; | 6370 | return SOCKET_ERROR; |
| 6364 | } | 6371 | } |
| 6365 | 6372 | ||
| @@ -6368,7 +6375,7 @@ sys_connect (int s, const struct sockaddr * name, int namelen) | |||
| 6368 | { | 6375 | { |
| 6369 | if (winsock_lib == NULL) | 6376 | if (winsock_lib == NULL) |
| 6370 | { | 6377 | { |
| 6371 | h_errno = ENOTSOCK; | 6378 | errno = h_errno = ENOTSOCK; |
| 6372 | return SOCKET_ERROR; | 6379 | return SOCKET_ERROR; |
| 6373 | } | 6380 | } |
| 6374 | 6381 | ||
| @@ -6380,7 +6387,7 @@ sys_connect (int s, const struct sockaddr * name, int namelen) | |||
| 6380 | set_errno (); | 6387 | set_errno (); |
| 6381 | return rc; | 6388 | return rc; |
| 6382 | } | 6389 | } |
| 6383 | h_errno = ENOTSOCK; | 6390 | errno = h_errno = ENOTSOCK; |
| 6384 | return SOCKET_ERROR; | 6391 | return SOCKET_ERROR; |
| 6385 | } | 6392 | } |
| 6386 | 6393 | ||
| @@ -6414,7 +6421,7 @@ sys_gethostname (char * name, int namelen) | |||
| 6414 | if (namelen > MAX_COMPUTERNAME_LENGTH) | 6421 | if (namelen > MAX_COMPUTERNAME_LENGTH) |
| 6415 | return !GetComputerName (name, (DWORD *)&namelen); | 6422 | return !GetComputerName (name, (DWORD *)&namelen); |
| 6416 | 6423 | ||
| 6417 | h_errno = EFAULT; | 6424 | errno = h_errno = EFAULT; |
| 6418 | return SOCKET_ERROR; | 6425 | return SOCKET_ERROR; |
| 6419 | } | 6426 | } |
| 6420 | 6427 | ||
| @@ -6425,7 +6432,7 @@ sys_gethostbyname (const char * name) | |||
| 6425 | 6432 | ||
| 6426 | if (winsock_lib == NULL) | 6433 | if (winsock_lib == NULL) |
| 6427 | { | 6434 | { |
| 6428 | h_errno = ENETDOWN; | 6435 | errno = h_errno = ENETDOWN; |
| 6429 | return NULL; | 6436 | return NULL; |
| 6430 | } | 6437 | } |
| 6431 | 6438 | ||
| @@ -6443,7 +6450,7 @@ sys_getservbyname (const char * name, const char * proto) | |||
| 6443 | 6450 | ||
| 6444 | if (winsock_lib == NULL) | 6451 | if (winsock_lib == NULL) |
| 6445 | { | 6452 | { |
| 6446 | h_errno = ENETDOWN; | 6453 | errno = h_errno = ENETDOWN; |
| 6447 | return NULL; | 6454 | return NULL; |
| 6448 | } | 6455 | } |
| 6449 | 6456 | ||
| @@ -6459,7 +6466,7 @@ sys_getpeername (int s, struct sockaddr *addr, int * namelen) | |||
| 6459 | { | 6466 | { |
| 6460 | if (winsock_lib == NULL) | 6467 | if (winsock_lib == NULL) |
| 6461 | { | 6468 | { |
| 6462 | h_errno = ENETDOWN; | 6469 | errno = h_errno = ENETDOWN; |
| 6463 | return SOCKET_ERROR; | 6470 | return SOCKET_ERROR; |
| 6464 | } | 6471 | } |
| 6465 | 6472 | ||
| @@ -6471,7 +6478,7 @@ sys_getpeername (int s, struct sockaddr *addr, int * namelen) | |||
| 6471 | set_errno (); | 6478 | set_errno (); |
| 6472 | return rc; | 6479 | return rc; |
| 6473 | } | 6480 | } |
| 6474 | h_errno = ENOTSOCK; | 6481 | errno = h_errno = ENOTSOCK; |
| 6475 | return SOCKET_ERROR; | 6482 | return SOCKET_ERROR; |
| 6476 | } | 6483 | } |
| 6477 | 6484 | ||
| @@ -6480,7 +6487,7 @@ sys_shutdown (int s, int how) | |||
| 6480 | { | 6487 | { |
| 6481 | if (winsock_lib == NULL) | 6488 | if (winsock_lib == NULL) |
| 6482 | { | 6489 | { |
| 6483 | h_errno = ENETDOWN; | 6490 | errno = h_errno = ENETDOWN; |
| 6484 | return SOCKET_ERROR; | 6491 | return SOCKET_ERROR; |
| 6485 | } | 6492 | } |
| 6486 | 6493 | ||
| @@ -6492,7 +6499,7 @@ sys_shutdown (int s, int how) | |||
| 6492 | set_errno (); | 6499 | set_errno (); |
| 6493 | return rc; | 6500 | return rc; |
| 6494 | } | 6501 | } |
| 6495 | h_errno = ENOTSOCK; | 6502 | errno = h_errno = ENOTSOCK; |
| 6496 | return SOCKET_ERROR; | 6503 | return SOCKET_ERROR; |
| 6497 | } | 6504 | } |
| 6498 | 6505 | ||
| @@ -6501,7 +6508,7 @@ sys_setsockopt (int s, int level, int optname, const void * optval, int optlen) | |||
| 6501 | { | 6508 | { |
| 6502 | if (winsock_lib == NULL) | 6509 | if (winsock_lib == NULL) |
| 6503 | { | 6510 | { |
| 6504 | h_errno = ENETDOWN; | 6511 | errno = h_errno = ENETDOWN; |
| 6505 | return SOCKET_ERROR; | 6512 | return SOCKET_ERROR; |
| 6506 | } | 6513 | } |
| 6507 | 6514 | ||
| @@ -6514,7 +6521,7 @@ sys_setsockopt (int s, int level, int optname, const void * optval, int optlen) | |||
| 6514 | set_errno (); | 6521 | set_errno (); |
| 6515 | return rc; | 6522 | return rc; |
| 6516 | } | 6523 | } |
| 6517 | h_errno = ENOTSOCK; | 6524 | errno = h_errno = ENOTSOCK; |
| 6518 | return SOCKET_ERROR; | 6525 | return SOCKET_ERROR; |
| 6519 | } | 6526 | } |
| 6520 | 6527 | ||
| @@ -6523,7 +6530,7 @@ sys_listen (int s, int backlog) | |||
| 6523 | { | 6530 | { |
| 6524 | if (winsock_lib == NULL) | 6531 | if (winsock_lib == NULL) |
| 6525 | { | 6532 | { |
| 6526 | h_errno = ENETDOWN; | 6533 | errno = h_errno = ENETDOWN; |
| 6527 | return SOCKET_ERROR; | 6534 | return SOCKET_ERROR; |
| 6528 | } | 6535 | } |
| 6529 | 6536 | ||
| @@ -6537,7 +6544,7 @@ sys_listen (int s, int backlog) | |||
| 6537 | fd_info[s].flags |= FILE_LISTEN; | 6544 | fd_info[s].flags |= FILE_LISTEN; |
| 6538 | return rc; | 6545 | return rc; |
| 6539 | } | 6546 | } |
| 6540 | h_errno = ENOTSOCK; | 6547 | errno = h_errno = ENOTSOCK; |
| 6541 | return SOCKET_ERROR; | 6548 | return SOCKET_ERROR; |
| 6542 | } | 6549 | } |
| 6543 | 6550 | ||
| @@ -6546,7 +6553,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen) | |||
| 6546 | { | 6553 | { |
| 6547 | if (winsock_lib == NULL) | 6554 | if (winsock_lib == NULL) |
| 6548 | { | 6555 | { |
| 6549 | h_errno = ENETDOWN; | 6556 | errno = h_errno = ENETDOWN; |
| 6550 | return SOCKET_ERROR; | 6557 | return SOCKET_ERROR; |
| 6551 | } | 6558 | } |
| 6552 | 6559 | ||
| @@ -6558,7 +6565,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen) | |||
| 6558 | set_errno (); | 6565 | set_errno (); |
| 6559 | return rc; | 6566 | return rc; |
| 6560 | } | 6567 | } |
| 6561 | h_errno = ENOTSOCK; | 6568 | errno = h_errno = ENOTSOCK; |
| 6562 | return SOCKET_ERROR; | 6569 | return SOCKET_ERROR; |
| 6563 | } | 6570 | } |
| 6564 | 6571 | ||
| @@ -6567,7 +6574,7 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen) | |||
| 6567 | { | 6574 | { |
| 6568 | if (winsock_lib == NULL) | 6575 | if (winsock_lib == NULL) |
| 6569 | { | 6576 | { |
| 6570 | h_errno = ENETDOWN; | 6577 | errno = h_errno = ENETDOWN; |
| 6571 | return -1; | 6578 | return -1; |
| 6572 | } | 6579 | } |
| 6573 | 6580 | ||
| @@ -6579,13 +6586,20 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen) | |||
| 6579 | if (t == INVALID_SOCKET) | 6586 | if (t == INVALID_SOCKET) |
| 6580 | set_errno (); | 6587 | set_errno (); |
| 6581 | else | 6588 | else |
| 6582 | fd = socket_to_fd (t); | 6589 | { |
| 6590 | fd = socket_to_fd (t); | ||
| 6591 | if (fd < 0) | ||
| 6592 | errno = h_errno; /* socket_to_fd sets h_errno */ | ||
| 6593 | } | ||
| 6583 | 6594 | ||
| 6584 | fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED; | 6595 | if (fd >= 0) |
| 6585 | ResetEvent (fd_info[s].cp->char_avail); | 6596 | { |
| 6597 | fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED; | ||
| 6598 | ResetEvent (fd_info[s].cp->char_avail); | ||
| 6599 | } | ||
| 6586 | return fd; | 6600 | return fd; |
| 6587 | } | 6601 | } |
| 6588 | h_errno = ENOTSOCK; | 6602 | errno = h_errno = ENOTSOCK; |
| 6589 | return -1; | 6603 | return -1; |
| 6590 | } | 6604 | } |
| 6591 | 6605 | ||
| @@ -6595,7 +6609,7 @@ sys_recvfrom (int s, char * buf, int len, int flags, | |||
| 6595 | { | 6609 | { |
| 6596 | if (winsock_lib == NULL) | 6610 | if (winsock_lib == NULL) |
| 6597 | { | 6611 | { |
| 6598 | h_errno = ENETDOWN; | 6612 | errno = h_errno = ENETDOWN; |
| 6599 | return SOCKET_ERROR; | 6613 | return SOCKET_ERROR; |
| 6600 | } | 6614 | } |
| 6601 | 6615 | ||
| @@ -6607,7 +6621,7 @@ sys_recvfrom (int s, char * buf, int len, int flags, | |||
| 6607 | set_errno (); | 6621 | set_errno (); |
| 6608 | return rc; | 6622 | return rc; |
| 6609 | } | 6623 | } |
| 6610 | h_errno = ENOTSOCK; | 6624 | errno = h_errno = ENOTSOCK; |
| 6611 | return SOCKET_ERROR; | 6625 | return SOCKET_ERROR; |
| 6612 | } | 6626 | } |
| 6613 | 6627 | ||
| @@ -6617,7 +6631,7 @@ sys_sendto (int s, const char * buf, int len, int flags, | |||
| 6617 | { | 6631 | { |
| 6618 | if (winsock_lib == NULL) | 6632 | if (winsock_lib == NULL) |
| 6619 | { | 6633 | { |
| 6620 | h_errno = ENETDOWN; | 6634 | errno = h_errno = ENETDOWN; |
| 6621 | return SOCKET_ERROR; | 6635 | return SOCKET_ERROR; |
| 6622 | } | 6636 | } |
| 6623 | 6637 | ||
| @@ -6629,7 +6643,7 @@ sys_sendto (int s, const char * buf, int len, int flags, | |||
| 6629 | set_errno (); | 6643 | set_errno (); |
| 6630 | return rc; | 6644 | return rc; |
| 6631 | } | 6645 | } |
| 6632 | h_errno = ENOTSOCK; | 6646 | errno = h_errno = ENOTSOCK; |
| 6633 | return SOCKET_ERROR; | 6647 | return SOCKET_ERROR; |
| 6634 | } | 6648 | } |
| 6635 | 6649 | ||
| @@ -6640,7 +6654,7 @@ fcntl (int s, int cmd, int options) | |||
| 6640 | { | 6654 | { |
| 6641 | if (winsock_lib == NULL) | 6655 | if (winsock_lib == NULL) |
| 6642 | { | 6656 | { |
| 6643 | h_errno = ENETDOWN; | 6657 | errno = h_errno = ENETDOWN; |
| 6644 | return -1; | 6658 | return -1; |
| 6645 | } | 6659 | } |
| 6646 | 6660 | ||
| @@ -6663,7 +6677,7 @@ fcntl (int s, int cmd, int options) | |||
| 6663 | return SOCKET_ERROR; | 6677 | return SOCKET_ERROR; |
| 6664 | } | 6678 | } |
| 6665 | } | 6679 | } |
| 6666 | h_errno = ENOTSOCK; | 6680 | errno = h_errno = ENOTSOCK; |
| 6667 | return SOCKET_ERROR; | 6681 | return SOCKET_ERROR; |
| 6668 | } | 6682 | } |
| 6669 | 6683 | ||
diff --git a/src/w32proc.c b/src/w32proc.c index ce1474c7323..8226564c88f 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -804,6 +804,9 @@ new_child (void) | |||
| 804 | goto Initialize; | 804 | goto Initialize; |
| 805 | if (child_proc_count == MAX_CHILDREN) | 805 | if (child_proc_count == MAX_CHILDREN) |
| 806 | { | 806 | { |
| 807 | int i = 0; | ||
| 808 | child_process *dead_cp = NULL; | ||
| 809 | |||
| 807 | DebPrint (("new_child: No vacant slots, looking for dead processes\n")); | 810 | DebPrint (("new_child: No vacant slots, looking for dead processes\n")); |
| 808 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) | 811 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) |
| 809 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess) | 812 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess) |
| @@ -819,15 +822,27 @@ new_child (void) | |||
| 819 | if (status != STILL_ACTIVE | 822 | if (status != STILL_ACTIVE |
| 820 | || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0) | 823 | || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0) |
| 821 | { | 824 | { |
| 822 | DebPrint (("new_child: Freeing slot of dead process %d\n", | 825 | DebPrint (("new_child: Freeing slot of dead process %d, fd %d\n", |
| 823 | cp->procinfo.dwProcessId)); | 826 | cp->procinfo.dwProcessId, cp->fd)); |
| 824 | CloseHandle (cp->procinfo.hProcess); | 827 | CloseHandle (cp->procinfo.hProcess); |
| 825 | cp->procinfo.hProcess = NULL; | 828 | cp->procinfo.hProcess = NULL; |
| 826 | CloseHandle (cp->procinfo.hThread); | 829 | CloseHandle (cp->procinfo.hThread); |
| 827 | cp->procinfo.hThread = NULL; | 830 | cp->procinfo.hThread = NULL; |
| 828 | goto Initialize; | 831 | /* Free up to 2 dead slots at a time, so that if we |
| 832 | have a lot of them, they will eventually all be | ||
| 833 | freed when the tornado ends. */ | ||
| 834 | if (i == 0) | ||
| 835 | dead_cp = cp; | ||
| 836 | else | ||
| 837 | break; | ||
| 838 | i++; | ||
| 829 | } | 839 | } |
| 830 | } | 840 | } |
| 841 | if (dead_cp) | ||
| 842 | { | ||
| 843 | cp = dead_cp; | ||
| 844 | goto Initialize; | ||
| 845 | } | ||
| 831 | } | 846 | } |
| 832 | if (child_proc_count == MAX_CHILDREN) | 847 | if (child_proc_count == MAX_CHILDREN) |
| 833 | return NULL; | 848 | return NULL; |
| @@ -1002,12 +1017,24 @@ reader_thread (void *arg) | |||
| 1002 | if (cp->status == STATUS_READ_ERROR || !cp->char_avail) | 1017 | if (cp->status == STATUS_READ_ERROR || !cp->char_avail) |
| 1003 | break; | 1018 | break; |
| 1004 | 1019 | ||
| 1020 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess && cp->fd >= 0) | ||
| 1021 | { | ||
| 1022 | /* Somebody already called delete_child on this child, since | ||
| 1023 | only delete_child zeroes out cp->char_avail. This means | ||
| 1024 | no one will read from cp->fd and will not set the | ||
| 1025 | FILE_AT_EOF flag, therefore preventing sys_select from | ||
| 1026 | noticing that the process died. Set the flag here | ||
| 1027 | instead. */ | ||
| 1028 | fd_info[cp->fd].flags |= FILE_AT_EOF; | ||
| 1029 | } | ||
| 1030 | |||
| 1005 | /* The name char_avail is a misnomer - it really just means the | 1031 | /* The name char_avail is a misnomer - it really just means the |
| 1006 | read-ahead has completed, whether successfully or not. */ | 1032 | read-ahead has completed, whether successfully or not. */ |
| 1007 | if (!SetEvent (cp->char_avail)) | 1033 | if (!SetEvent (cp->char_avail)) |
| 1008 | { | 1034 | { |
| 1009 | DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n", | 1035 | DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n", |
| 1010 | GetLastError (), cp->fd)); | 1036 | (DWORD_PTR)cp->char_avail, GetLastError (), |
| 1037 | cp->fd, cp->pid)); | ||
| 1011 | return 1; | 1038 | return 1; |
| 1012 | } | 1039 | } |
| 1013 | 1040 | ||
| @@ -1210,6 +1237,11 @@ reap_subprocess (child_process *cp) | |||
| 1210 | sys_read when the subprocess output is fully read. */ | 1237 | sys_read when the subprocess output is fully read. */ |
| 1211 | if (cp->fd < 0) | 1238 | if (cp->fd < 0) |
| 1212 | delete_child (cp); | 1239 | delete_child (cp); |
| 1240 | else | ||
| 1241 | { | ||
| 1242 | /* Reset the flag set by reader_thread. */ | ||
| 1243 | fd_info[cp->fd].flags &= ~FILE_AT_EOF; | ||
| 1244 | } | ||
| 1213 | } | 1245 | } |
| 1214 | 1246 | ||
| 1215 | /* Wait for a child process specified by PID, or for any of our | 1247 | /* Wait for a child process specified by PID, or for any of our |
| @@ -2035,7 +2067,7 @@ count_children: | |||
| 2035 | /* Some child_procs might be sockets; ignore them. Also some | 2067 | /* Some child_procs might be sockets; ignore them. Also some |
| 2036 | children may have died already, but we haven't finished reading | 2068 | children may have died already, but we haven't finished reading |
| 2037 | the process output; ignore them too. */ | 2069 | the process output; ignore them too. */ |
| 2038 | if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess | 2070 | if ((CHILD_ACTIVE (cp) || cp->procinfo.hProcess) |
| 2039 | && (cp->fd < 0 | 2071 | && (cp->fd < 0 |
| 2040 | || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 | 2072 | || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 |
| 2041 | || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) | 2073 | || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) |