diff options
| author | Eli Zaretskii | 2021-12-11 20:15:53 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2021-12-11 20:15:53 +0200 |
| commit | a81669c69fda1a2d0d4238b8440145fb2aeb959f (patch) | |
| tree | ef4f554f4505d9a5171f57878e2f38dea8d01cda /src/w32proc.c | |
| parent | 8c50016b100ec2c548ec90131e0f5fb5f4ebb5c1 (diff) | |
| download | emacs-a81669c69fda1a2d0d4238b8440145fb2aeb959f.tar.gz emacs-a81669c69fda1a2d0d4238b8440145fb2aeb959f.zip | |
Fix hang when deleting a pipe process
* src/w32.h (FILE_DONT_CLOSE): New flag.
* src/w32.c (sys_close): Don't close descriptors used to read from
the pipe process. Leave the FILE_DONT_CLOSE flag set in the
descriptor's info.
(register_aux_fd): Set the FILE_DONT_CLOSE flag in the
descriptor's info.
* src/w32proc.c (reader_thread): When exiting normally, close the
file descriptor used to read from a pipe process. (Bug#52414)
Diffstat (limited to 'src/w32proc.c')
| -rw-r--r-- | src/w32proc.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/src/w32proc.c b/src/w32proc.c index 360f45e9e11..bfe720eb623 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -1206,6 +1206,7 @@ static DWORD WINAPI | |||
| 1206 | reader_thread (void *arg) | 1206 | reader_thread (void *arg) |
| 1207 | { | 1207 | { |
| 1208 | child_process *cp; | 1208 | child_process *cp; |
| 1209 | int fd; | ||
| 1209 | 1210 | ||
| 1210 | /* Our identity */ | 1211 | /* Our identity */ |
| 1211 | cp = (child_process *)arg; | 1212 | cp = (child_process *)arg; |
| @@ -1220,12 +1221,13 @@ reader_thread (void *arg) | |||
| 1220 | { | 1221 | { |
| 1221 | int rc; | 1222 | int rc; |
| 1222 | 1223 | ||
| 1223 | if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_CONNECT) != 0) | 1224 | fd = cp->fd; |
| 1224 | rc = _sys_wait_connect (cp->fd); | 1225 | if (fd >= 0 && (fd_info[fd].flags & FILE_CONNECT) != 0) |
| 1225 | else if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_LISTEN) != 0) | 1226 | rc = _sys_wait_connect (fd); |
| 1226 | rc = _sys_wait_accept (cp->fd); | 1227 | else if (fd >= 0 && (fd_info[fd].flags & FILE_LISTEN) != 0) |
| 1228 | rc = _sys_wait_accept (fd); | ||
| 1227 | else | 1229 | else |
| 1228 | rc = _sys_read_ahead (cp->fd); | 1230 | rc = _sys_read_ahead (fd); |
| 1229 | 1231 | ||
| 1230 | /* Don't bother waiting for the event if we already have been | 1232 | /* Don't bother waiting for the event if we already have been |
| 1231 | told to exit by delete_child. */ | 1233 | told to exit by delete_child. */ |
| @@ -1238,7 +1240,7 @@ reader_thread (void *arg) | |||
| 1238 | { | 1240 | { |
| 1239 | DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n", | 1241 | DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n", |
| 1240 | (DWORD_PTR)cp->char_avail, GetLastError (), | 1242 | (DWORD_PTR)cp->char_avail, GetLastError (), |
| 1241 | cp->fd, cp->pid)); | 1243 | fd, cp->pid)); |
| 1242 | return 1; | 1244 | return 1; |
| 1243 | } | 1245 | } |
| 1244 | 1246 | ||
| @@ -1266,6 +1268,13 @@ reader_thread (void *arg) | |||
| 1266 | if (cp->status == STATUS_READ_ERROR) | 1268 | if (cp->status == STATUS_READ_ERROR) |
| 1267 | break; | 1269 | break; |
| 1268 | } | 1270 | } |
| 1271 | /* If this thread was reading from a pipe process, close the | ||
| 1272 | descriptor used for reading, as sys_close doesn't in that case. */ | ||
| 1273 | if (fd_info[fd].flags == FILE_DONT_CLOSE) | ||
| 1274 | { | ||
| 1275 | fd_info[fd].flags = 0; | ||
| 1276 | _close (fd); | ||
| 1277 | } | ||
| 1269 | return 0; | 1278 | return 0; |
| 1270 | } | 1279 | } |
| 1271 | 1280 | ||