Merge from emacs-24; up to 2012-12-19T19:51:40Z!monnier@iro.umontreal.ca
This commit is contained in:
commit
d64d97e537
4 changed files with 107 additions and 37 deletions
|
@ -1,4 +1,4 @@
|
|||
2013-02-14 Glenn Morris <rgm@gnu.org>
|
||||
2013-02-15 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* modes.texi (Basic Major Modes): 'z' no longer bound in special-mode.
|
||||
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
2013-02-15 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32proc.c (new_child): Free up to 2 slots of dead processes at a
|
||||
time. Improve diagnostics in DebPrint.
|
||||
(reader_thread): If cp->char_avail is NULL, set the FILE_AT_EOF
|
||||
flag, so that sys_select could have a chance of noticing that this
|
||||
process is dead, and call a SIGCHLD handler for it. Improve
|
||||
diagnostics in DebPrint.
|
||||
(reap_subprocess): Reset the FILE_AT_EOF flag set by
|
||||
reader_thread.
|
||||
(sys_select): Watch a process whose procinfo.hProcess is non-NULL
|
||||
even if its char_avail is NULL. Allows to reap subprocesses that
|
||||
were forcibly deleted by delete-process. (Bug#13546)
|
||||
|
||||
* w32.c (sys_socket, sys_bind, sys_connect, sys_gethostname)
|
||||
(sys_gethostbyname, sys_getservbyname, sys_getpeername)
|
||||
(sys_shutdown, sys_setsockopt, sys_listen, sys_getsockname)
|
||||
(sys_accept, sys_recvfrom, sys_sendto, fcntl): In case of failure,
|
||||
make sure errno is set to an appropriate value. (Bug#13546)
|
||||
(socket_to_fd): Add assertion against indexing fd_info[] with a
|
||||
value that is out of bounds.
|
||||
(sys_accept): If fd is negative, do not set up the child_process
|
||||
structure for reading.
|
||||
|
||||
2013-02-15 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
* composite.c (fill_gstring_header): Remove useless prototype.
|
||||
|
|
74
src/w32.c
74
src/w32.c
|
@ -6232,7 +6232,7 @@ sys_socket (int af, int type, int protocol)
|
|||
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
|
@ -6242,7 +6242,13 @@ sys_socket (int af, int type, int protocol)
|
|||
s = pfn_socket (af, type, protocol);
|
||||
|
||||
if (s != INVALID_SOCKET)
|
||||
return socket_to_fd (s);
|
||||
{
|
||||
int retval = socket_to_fd (s);
|
||||
|
||||
if (retval == -1)
|
||||
errno = h_errno;
|
||||
return retval;
|
||||
}
|
||||
|
||||
set_errno ();
|
||||
return -1;
|
||||
|
@ -6309,6 +6315,7 @@ socket_to_fd (SOCKET s)
|
|||
}
|
||||
}
|
||||
}
|
||||
eassert (fd < MAXDESC);
|
||||
fd_info[fd].hnd = (HANDLE) s;
|
||||
|
||||
/* set our own internal flags */
|
||||
|
@ -6347,7 +6354,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6359,7 +6366,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen)
|
|||
set_errno ();
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6368,7 +6375,7 @@ sys_connect (int s, const struct sockaddr * name, int namelen)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6380,7 +6387,7 @@ sys_connect (int s, const struct sockaddr * name, int namelen)
|
|||
set_errno ();
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6414,7 +6421,7 @@ sys_gethostname (char * name, int namelen)
|
|||
if (namelen > MAX_COMPUTERNAME_LENGTH)
|
||||
return !GetComputerName (name, (DWORD *)&namelen);
|
||||
|
||||
h_errno = EFAULT;
|
||||
errno = h_errno = EFAULT;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6425,7 +6432,7 @@ sys_gethostbyname (const char * name)
|
|||
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -6443,7 +6450,7 @@ sys_getservbyname (const char * name, const char * proto)
|
|||
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -6459,7 +6466,7 @@ sys_getpeername (int s, struct sockaddr *addr, int * namelen)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6471,7 +6478,7 @@ sys_getpeername (int s, struct sockaddr *addr, int * namelen)
|
|||
set_errno ();
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6480,7 +6487,7 @@ sys_shutdown (int s, int how)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6492,7 +6499,7 @@ sys_shutdown (int s, int how)
|
|||
set_errno ();
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6501,7 +6508,7 @@ sys_setsockopt (int s, int level, int optname, const void * optval, int optlen)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6514,7 +6521,7 @@ sys_setsockopt (int s, int level, int optname, const void * optval, int optlen)
|
|||
set_errno ();
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6523,7 +6530,7 @@ sys_listen (int s, int backlog)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6537,7 +6544,7 @@ sys_listen (int s, int backlog)
|
|||
fd_info[s].flags |= FILE_LISTEN;
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6546,7 +6553,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6558,7 +6565,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen)
|
|||
set_errno ();
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6567,7 +6574,7 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -6579,13 +6586,20 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen)
|
|||
if (t == INVALID_SOCKET)
|
||||
set_errno ();
|
||||
else
|
||||
fd = socket_to_fd (t);
|
||||
{
|
||||
fd = socket_to_fd (t);
|
||||
if (fd < 0)
|
||||
errno = h_errno; /* socket_to_fd sets h_errno */
|
||||
}
|
||||
|
||||
fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED;
|
||||
ResetEvent (fd_info[s].cp->char_avail);
|
||||
if (fd >= 0)
|
||||
{
|
||||
fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED;
|
||||
ResetEvent (fd_info[s].cp->char_avail);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -6595,7 +6609,7 @@ sys_recvfrom (int s, char * buf, int len, int flags,
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6607,7 +6621,7 @@ sys_recvfrom (int s, char * buf, int len, int flags,
|
|||
set_errno ();
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6617,7 +6631,7 @@ sys_sendto (int s, const char * buf, int len, int flags,
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6629,7 +6643,7 @@ sys_sendto (int s, const char * buf, int len, int flags,
|
|||
set_errno ();
|
||||
return rc;
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -6640,7 +6654,7 @@ fcntl (int s, int cmd, int options)
|
|||
{
|
||||
if (winsock_lib == NULL)
|
||||
{
|
||||
h_errno = ENETDOWN;
|
||||
errno = h_errno = ENETDOWN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -6663,7 +6677,7 @@ fcntl (int s, int cmd, int options)
|
|||
return SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
h_errno = ENOTSOCK;
|
||||
errno = h_errno = ENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -804,6 +804,9 @@ new_child (void)
|
|||
goto Initialize;
|
||||
if (child_proc_count == MAX_CHILDREN)
|
||||
{
|
||||
int i = 0;
|
||||
child_process *dead_cp = NULL;
|
||||
|
||||
DebPrint (("new_child: No vacant slots, looking for dead processes\n"));
|
||||
for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
|
||||
if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
|
||||
|
@ -819,15 +822,27 @@ new_child (void)
|
|||
if (status != STILL_ACTIVE
|
||||
|| WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
DebPrint (("new_child: Freeing slot of dead process %d\n",
|
||||
cp->procinfo.dwProcessId));
|
||||
DebPrint (("new_child: Freeing slot of dead process %d, fd %d\n",
|
||||
cp->procinfo.dwProcessId, cp->fd));
|
||||
CloseHandle (cp->procinfo.hProcess);
|
||||
cp->procinfo.hProcess = NULL;
|
||||
CloseHandle (cp->procinfo.hThread);
|
||||
cp->procinfo.hThread = NULL;
|
||||
goto Initialize;
|
||||
/* Free up to 2 dead slots at a time, so that if we
|
||||
have a lot of them, they will eventually all be
|
||||
freed when the tornado ends. */
|
||||
if (i == 0)
|
||||
dead_cp = cp;
|
||||
else
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (dead_cp)
|
||||
{
|
||||
cp = dead_cp;
|
||||
goto Initialize;
|
||||
}
|
||||
}
|
||||
if (child_proc_count == MAX_CHILDREN)
|
||||
return NULL;
|
||||
|
@ -1002,12 +1017,24 @@ reader_thread (void *arg)
|
|||
if (cp->status == STATUS_READ_ERROR || !cp->char_avail)
|
||||
break;
|
||||
|
||||
if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess && cp->fd >= 0)
|
||||
{
|
||||
/* Somebody already called delete_child on this child, since
|
||||
only delete_child zeroes out cp->char_avail. This means
|
||||
no one will read from cp->fd and will not set the
|
||||
FILE_AT_EOF flag, therefore preventing sys_select from
|
||||
noticing that the process died. Set the flag here
|
||||
instead. */
|
||||
fd_info[cp->fd].flags |= FILE_AT_EOF;
|
||||
}
|
||||
|
||||
/* The name char_avail is a misnomer - it really just means the
|
||||
read-ahead has completed, whether successfully or not. */
|
||||
if (!SetEvent (cp->char_avail))
|
||||
{
|
||||
DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n",
|
||||
GetLastError (), cp->fd));
|
||||
DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n",
|
||||
(DWORD_PTR)cp->char_avail, GetLastError (),
|
||||
cp->fd, cp->pid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1210,6 +1237,11 @@ reap_subprocess (child_process *cp)
|
|||
sys_read when the subprocess output is fully read. */
|
||||
if (cp->fd < 0)
|
||||
delete_child (cp);
|
||||
else
|
||||
{
|
||||
/* Reset the flag set by reader_thread. */
|
||||
fd_info[cp->fd].flags &= ~FILE_AT_EOF;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for a child process specified by PID, or for any of our
|
||||
|
@ -2035,7 +2067,7 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
|
|||
/* Some child_procs might be sockets; ignore them. Also some
|
||||
children may have died already, but we haven't finished reading
|
||||
the process output; ignore them too. */
|
||||
if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess
|
||||
if ((CHILD_ACTIVE (cp) || cp->procinfo.hProcess)
|
||||
&& (cp->fd < 0
|
||||
|| (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0
|
||||
|| (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)
|
||||
|
|
Loading…
Add table
Reference in a new issue