(iso-transl-dead-key-alist): Fix syntax for ?^.
[emacs.git] / src / w32proc.c
blobd13a5bca9e8eb896c7d798bddeb4c2b73b759f57
1 /* Process support for Windows NT port of GNU EMACS.
2 Copyright (C) 1992, 1995 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Drew Bliss Oct 14, 1993
22 Adapted from alarm.c by Tim Fleehart
25 #include <config.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <io.h>
31 #include <signal.h>
33 #include <windows.h>
35 #include "lisp.h"
36 #include "nt.h"
37 #include "systime.h"
38 #include "syswait.h"
39 #include "process.h"
41 #ifndef SYS_SIGLIST_DECLARED
42 extern char *sys_siglist[];
43 #endif
45 /* #define FULL_DEBUG */
47 typedef void (_CALLBACK_ *signal_handler)(int);
49 /* Defined in process.h which conflicts with the local copy */
50 #define _P_NOWAIT 1
52 typedef struct _child_process
54 int fd;
55 HANDLE char_avail;
56 HANDLE char_consumed;
57 char chr;
58 BOOL status;
59 HANDLE process;
60 DWORD pid;
61 HANDLE thrd;
62 } child_process;
64 #define MAX_CHILDREN MAXDESC
66 #ifdef EMACSDEBUG
67 void _CRTAPI1
68 _DebPrint (char *fmt, ...)
70 char buf[256];
71 va_list args;
73 va_start (args, fmt);
74 vsprintf (buf, fmt, args);
75 va_end (args);
76 OutputDebugString (buf);
78 #endif
80 /* Child process management list. */
81 static int child_proc_count = 0;
82 static child_process child_procs[MAX_CHILDREN];
83 static child_process *dead_child = NULL;
85 #define CHILD_ACTIVE(cp) ((cp)->process != NULL)
86 #define DEACTIVATE_CHILD(cp) ((cp)->process = NULL)
88 /* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
89 static signal_handler sig_handlers[NSIG];
91 /* Fake signal implementation to record the SIGCHLD handler. */
92 signal_handler
93 win32_signal (int sig, signal_handler handler)
95 signal_handler old;
97 if (sig != SIGCHLD)
99 errno = EINVAL;
100 return SIG_ERR;
102 old = sig_handlers[sig];
103 sig_handlers[sig] = handler;
104 return old;
107 /* Find an unused process slot. */
108 static child_process *
109 new_child (void)
111 child_process *cp;
113 if (child_proc_count == MAX_CHILDREN)
114 return NULL;
116 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
117 if (!CHILD_ACTIVE (cp))
118 return cp;
119 return &child_procs[child_proc_count++];
122 /* Find a child by pid. */
123 static child_process *
124 find_child_pid (DWORD pid)
126 child_process *cp;
128 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
129 if (CHILD_ACTIVE (cp) && pid == cp->pid)
130 return cp;
131 return NULL;
134 /* Find a child by fd. */
135 static child_process *
136 find_child_fd (int fd)
138 child_process *cp;
140 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
141 if (CHILD_ACTIVE (cp) && fd == cp->fd)
142 return cp;
143 return NULL;
146 /* Thread proc for child process reader threads
147 The threads just sit in a loop waiting for input
148 When they detect input, they signal the char_avail input to
149 wake up the select emulator
150 When the select emulator processes their input, it pulses
151 char_consumed so that the reader thread goes back to reading. */
152 DWORD WINAPI
153 reader_thread (void *arg)
155 child_process *cp;
157 /* Our identity */
158 cp = (child_process *)arg;
160 /* We have to wait for the go-ahead before we can start */
161 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
162 return 0;
163 /* If something went wrong, quit */
164 if (!cp->status)
165 return 0;
167 for (;;)
169 /* Use read to get CRLF translation */
170 if (read (cp->fd, &cp->chr, sizeof (char)) == sizeof (char))
172 cp->status = TRUE;
174 else
176 #ifdef FULL_DEBUG
177 DebPrint (("reader_thread.read failed with %lu for fd %ld\n",
178 GetLastError (), cp->fd));
179 #endif
180 cp->status = FALSE;
183 if (!SetEvent (cp->char_avail))
185 DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n",
186 GetLastError (), cp->fd));
187 break;
190 /* If the read died, the child has died so let the thread die */
191 if (!cp->status)
192 break;
194 /* Wait until our input is acknowledged before reading again */
195 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
197 DebPrint (("reader_thread.WaitForSingleObject failed with "
198 "%lu for fd %ld\n", GetLastError (), cp->fd));
199 break;
202 return 0;
205 static BOOL
206 create_child (char *exe, char *cmdline, char *env,
207 PROCESS_INFORMATION *info)
209 child_process *cp;
210 DWORD id;
211 STARTUPINFO start;
212 SECURITY_ATTRIBUTES sec_attrs;
213 SECURITY_DESCRIPTOR sec_desc;
215 cp = new_child ();
216 if (cp == NULL)
217 goto EH_Fail;
219 cp->fd = -1;
221 cp->char_avail = CreateEvent (NULL, FALSE, FALSE, NULL);
222 if (cp->char_avail == NULL)
223 goto EH_Fail;
225 cp->char_consumed = CreateEvent (NULL, FALSE, FALSE, NULL);
226 if (cp->char_consumed == NULL)
227 goto EH_char_avail;
229 cp->thrd = CreateThread (NULL, 1024, reader_thread, cp, 0, &id);
230 if (cp->thrd == NULL)
231 goto EH_char_consumed;
233 memset (&start, 0, sizeof (start));
234 start.cb = sizeof (start);
236 #ifdef HAVE_NTGUI
237 start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
238 start.wShowWindow = SW_HIDE;
240 start.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
241 start.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
242 start.hStdError = GetStdHandle (STD_ERROR_HANDLE);
243 #endif /* HAVE_NTGUI */
245 /* Explicitly specify no security */
246 if (!InitializeSecurityDescriptor (&sec_desc, SECURITY_DESCRIPTOR_REVISION))
247 goto EH_thrd;
248 if (!SetSecurityDescriptorDacl (&sec_desc, TRUE, NULL, FALSE))
249 goto EH_thrd;
250 sec_attrs.nLength = sizeof (sec_attrs);
251 sec_attrs.lpSecurityDescriptor = &sec_desc;
252 sec_attrs.bInheritHandle = FALSE;
254 if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
255 CREATE_NEW_PROCESS_GROUP, env, NULL,
256 &start, info))
257 goto EH_thrd;
258 cp->process = info->hProcess;
259 cp->pid = info->dwProcessId;
261 return TRUE;
263 EH_thrd:
264 id = GetLastError ();
266 cp->status = FALSE;
267 SetEvent (cp->char_consumed);
268 EH_char_consumed:
269 CloseHandle (cp->char_consumed);
270 EH_char_avail:
271 CloseHandle (cp->char_avail);
272 EH_Fail:
273 return FALSE;
276 /* create_child doesn't know what emacs' file handle will be for waiting
277 on output from the child, so we need to make this additional call
278 to register the handle with the process
279 This way the select emulator knows how to match file handles with
280 entries in child_procs. */
281 void
282 register_child (int pid, int fd)
284 child_process *cp;
286 cp = find_child_pid (pid);
287 if (cp == NULL)
289 DebPrint (("register_child unable to find pid %lu\n", pid));
290 return;
293 #ifdef FULL_DEBUG
294 DebPrint (("register_child registered fd %d with pid %lu\n", fd, pid));
295 #endif
297 cp->fd = fd;
298 cp->status = TRUE;
300 /* Tell the reader thread to start */
301 if (!SetEvent (cp->char_consumed))
303 DebPrint (("register_child.SetEvent failed with %lu for fd %ld\n",
304 GetLastError (), cp->fd));
308 /* When a process dies its pipe will break so the reader thread will
309 signal failure to the select emulator.
310 The select emulator then calls this routine to clean up.
311 Since the thread signaled failure we can assume it is exiting. */
312 static void
313 remove_child (child_process *cp)
315 /* Reap the thread */
316 if (WaitForSingleObject (cp->thrd, INFINITE) != WAIT_OBJECT_0)
318 DebPrint (("remove_child.WaitForSingleObject (thread) failed "
319 "with %lu for fd %ld\n", GetLastError (), cp->fd));
321 CloseHandle (cp->thrd);
322 CloseHandle (cp->char_consumed);
323 CloseHandle (cp->char_avail);
325 /* Reap the process */
326 if (WaitForSingleObject (cp->process, INFINITE) != WAIT_OBJECT_0)
328 DebPrint (("remove_child.WaitForSingleObject (process) failed "
329 "with %lu for fd %ld\n", GetLastError (), cp->fd));
331 CloseHandle (cp->process);
333 DEACTIVATE_CHILD (cp);
336 /* Wait for any of our existing child processes to die
337 When it does, close its handle
338 Return the pid and fill in the status if non-NULL. */
340 int
341 win32_wait (int *status)
343 DWORD active, retval;
344 int nh;
345 child_process *cp, *cps[MAX_CHILDREN];
346 HANDLE wait_hnd[MAX_CHILDREN];
348 nh = 0;
349 if (dead_child != NULL)
351 /* We want to wait for a specific child */
352 wait_hnd[nh] = dead_child->process;
353 cps[nh] = dead_child;
354 nh++;
356 else
358 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
359 if (CHILD_ACTIVE (cp))
361 wait_hnd[nh] = cp->process;
362 cps[nh] = cp;
363 nh++;
367 if (nh == 0)
369 /* Nothing to wait on, so fail */
370 errno = ECHILD;
371 return -1;
374 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, INFINITE);
375 if (active == WAIT_FAILED)
377 errno = EBADF;
378 return -1;
380 else if (active == WAIT_TIMEOUT)
382 /* Should never happen */
383 errno = EINVAL;
384 return -1;
386 else if (active >= WAIT_OBJECT_0 &&
387 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
389 active -= WAIT_OBJECT_0;
391 else if (active >= WAIT_ABANDONED_0 &&
392 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
394 active -= WAIT_ABANDONED_0;
397 if (!GetExitCodeProcess (wait_hnd[active], &retval))
399 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
400 GetLastError ()));
401 retval = 1;
403 if (retval == STILL_ACTIVE)
405 /* Should never happen */
406 DebPrint (("Wait.WaitForMultipleObjects returned an active process\n"));
407 errno = EINVAL;
408 return -1;
411 /* Massage the exit code from the process to match the format expected
412 by the WIFSTOPPED et al macros in syswait.h. Only WIFSIGNALED and
413 WIFEXITED are supported; WIFSTOPPED doesn't make sense under NT. */
415 if (retval == STATUS_CONTROL_C_EXIT)
416 retval = SIGINT;
417 else
418 retval <<= 8;
420 cp = cps[active];
422 if (status)
424 *status = retval;
426 else if (synch_process_alive)
428 synch_process_alive = 0;
430 /* Report the status of the synchronous process. */
431 if (WIFEXITED (retval))
432 synch_process_retcode = WRETCODE (retval);
433 else if (WIFSIGNALED (retval))
435 int code = WTERMSIG (retval);
436 char *signame = 0;
438 if (code < NSIG)
440 /* Suppress warning if the table has const char *. */
441 signame = (char *) sys_siglist[code];
443 if (signame == 0)
444 signame = "unknown";
446 synch_process_death = signame;
448 TerminateThread (cp->thrd, 0);
449 CloseHandle (cp->thrd);
450 CloseHandle (cp->char_consumed);
451 CloseHandle (cp->char_avail);
452 CloseHandle (cp->process);
453 DEACTIVATE_CHILD (cp);
456 return cp->pid;
459 /* We pass our process ID to our children by setting up an environment
460 variable in their environment. */
461 char ppid_env_var_buffer[64];
463 /* When a new child process is created we need to register it in our list,
464 so intercept spawn requests. */
465 int
466 win32_spawnve (int mode, char *cmdname, char **argv, char **envp)
468 Lisp_Object program, full;
469 char *cmdline, *env, *parg, **targ;
470 int arglen;
471 PROCESS_INFORMATION pi;
473 /* Handle executable names without an executable suffix. */
474 program = make_string (cmdname, strlen (cmdname));
475 if (NILP (Ffile_executable_p (program)))
477 struct gcpro gcpro1;
479 full = Qnil;
480 GCPRO1 (program);
481 openp (Vexec_path, program, EXEC_SUFFIXES, &full, 1);
482 UNGCPRO;
483 if (NILP (full))
485 errno = EINVAL;
486 return -1;
488 cmdname = XSTRING (full)->data;
489 argv[0] = cmdname;
492 if (child_proc_count == MAX_CHILDREN)
494 errno = EAGAIN;
495 return -1;
498 /* We don't care about the other modes */
499 if (mode != _P_NOWAIT)
501 errno = EINVAL;
502 return -1;
505 /* we have to do some conjuring here to put argv and envp into the
506 form CreateProcess wants... argv needs to be a space separated/null
507 terminated list of parameters, and envp is a null
508 separated/double-null terminated list of parameters.
510 Since I have no idea how large argv and envp are likely to be
511 we figure out list lengths on the fly and allocate them. */
513 /* do argv... */
514 arglen = 0;
515 targ = argv;
516 while (*targ)
518 arglen += strlen (*targ++) + 1;
520 cmdline = malloc (arglen);
521 if (cmdline == NULL)
523 errno = ENOMEM;
524 goto EH_Fail;
526 targ = argv;
527 parg = cmdline;
528 while (*targ)
530 strcpy (parg, *targ);
531 parg += strlen (*targ++);
532 *parg++ = ' ';
534 *--parg = '\0';
536 /* and envp... */
537 arglen = 1;
538 targ = envp;
539 while (*targ)
541 arglen += strlen (*targ++) + 1;
543 sprintf (ppid_env_var_buffer, "__PARENT_PROCESS_ID=%d",
544 GetCurrentProcessId ());
545 arglen += strlen (ppid_env_var_buffer) + 1;
547 env = malloc (arglen);
548 if (env == NULL)
550 errno = ENOMEM;
551 goto EH_cmdline;
553 targ = envp;
554 parg = env;
555 while (*targ)
557 strcpy (parg, *targ);
558 parg += strlen (*targ++);
559 *parg++ = '\0';
561 strcpy (parg, ppid_env_var_buffer);
562 parg += strlen (ppid_env_var_buffer);
563 *parg++ = '\0';
564 *parg = '\0';
566 /* Now create the process. */
567 if (!create_child (cmdname, cmdline, env, &pi))
569 errno = ENOEXEC;
570 goto EH_env;
573 return pi.dwProcessId;
575 EH_env:
576 free (env);
577 EH_cmdline:
578 free (cmdline);
579 EH_Fail:
580 return -1;
583 /* Emulate the select call
584 Wait for available input on any of the given rfds, or timeout if
585 a timeout is given and no input is detected
586 wfds and efds are not supported and must be NULL. */
588 /* From ntterm.c */
589 extern HANDLE keyboard_handle;
590 /* From process.c */
591 extern int proc_buffered_char[];
593 int
594 sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
595 EMACS_TIME *timeout)
597 SELECT_TYPE orfds;
598 DWORD timeout_ms;
599 int i, nh, nr;
600 DWORD active;
601 child_process *cp, *cps[MAX_CHILDREN + 1];
602 HANDLE wait_hnd[MAX_CHILDREN + 1];
603 #ifdef HAVE_NTGUI1
604 BOOL keyboardwait = FALSE ;
605 #endif /* HAVE_NTGUI */
607 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
608 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL)
610 #ifdef HAVE_TIMEVAL
611 Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
612 #else
613 Sleep ((*timeout) * 1000);
614 #endif
615 return 0;
618 /* Otherwise, we only handle rfds, so fail otherwise. */
619 if (rfds == NULL || wfds != NULL || efds != NULL)
621 errno = EINVAL;
622 return -1;
625 orfds = *rfds;
626 FD_ZERO (rfds);
627 nr = 0;
629 /* Build a list of handles to wait on. */
630 nh = 0;
631 for (i = 0; i < nfds; i++)
632 if (FD_ISSET (i, &orfds))
634 if (i == 0)
636 #ifdef HAVE_NTGUI1
637 keyboardwait = TRUE ;
638 #else
639 /* Handle stdin specially */
640 wait_hnd[nh] = keyboard_handle;
641 cps[nh] = NULL;
642 nh++;
643 #endif /* HAVE_NTGUI */
645 /* Check for any emacs-generated input in the queue since
646 it won't be detected in the wait */
647 if (detect_input_pending ())
649 FD_SET (i, rfds);
650 nr++;
653 else
655 /* Child process input */
656 cp = find_child_fd (i);
657 if (cp)
659 #ifdef FULL_DEBUG
660 DebPrint (("select waiting on child %d fd %d\n",
661 cp-child_procs, i));
662 #endif
663 wait_hnd[nh] = cp->char_avail;
664 cps[nh] = cp;
665 nh++;
667 else
669 /* Unable to find something to wait on for this fd, fail */
670 DebPrint (("select unable to find child process "
671 "for fd %ld\n", i));
672 nh = 0;
673 break;
678 /* Never do this in win32 since we will not get paint messages */
680 #ifndef HAVE_NTGUI1
681 /* Nothing to look for, so we didn't find anything */
682 if (nh == 0)
684 if (timeout)
685 #ifdef HAVE_TIMEVAL
686 Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
687 #else
688 Sleep ((*timeout) * 1000);
689 #endif
690 return 0;
692 #endif /* !HAVE_NTGUI */
694 /* Check for immediate return without waiting */
695 if (nr > 0)
696 return nr;
699 Wait for input
700 If a child process dies while this is waiting, its pipe will break
701 so the reader thread will signal an error condition, thus, the wait
702 will wake up
704 #ifdef HAVE_TIMEVAL
705 timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE;
706 #else
707 timeout_ms = timeout ? *timeout*1000 : INFINITE;
708 #endif
709 #ifdef HAVE_NTGUI1
710 active = MsgWaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms,QS_ALLINPUT);
711 #else
712 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms);
713 #endif /* HAVE_NTGUI */
714 if (active == WAIT_FAILED)
716 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n",
717 nh, timeout_ms, GetLastError ()));
718 /* Is there a better error? */
719 errno = EBADF;
720 return -1;
722 else if (active == WAIT_TIMEOUT)
724 return 0;
726 #ifdef HAVE_NTGUI1
727 else if (active == WAIT_OBJECT_0 + nh)
729 /* Keyboard input available */
730 FD_SET (0, rfds);
732 /* This shouldn't be necessary, but apparently just setting the input
733 fd is not good enough for emacs */
734 // read_input_waiting ();
736 return (1) ;
738 #endif /* HAVE_NTGUI */
739 else if (active >= WAIT_OBJECT_0 &&
740 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
742 active -= WAIT_OBJECT_0;
744 else if (active >= WAIT_ABANDONED_0 &&
745 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
747 active -= WAIT_ABANDONED_0;
750 if (cps[active] == NULL)
752 /* Keyboard input available */
753 FD_SET (0, rfds);
754 nr++;
756 /* This shouldn't be necessary, but apparently just setting the input
757 fd is not good enough for emacs */
758 read_input_waiting ();
760 else
762 /* Child process */
763 cp = cps[active];
765 /* If status is FALSE the read failed so don't report input */
766 if (cp->status)
768 FD_SET (cp->fd, rfds);
769 proc_buffered_char[cp->fd] = cp->chr;
770 nr++;
772 else
774 /* The SIGCHLD handler will do a Wait so we know it won't
775 return until the process is dead
776 We force Wait to only wait for this process to avoid it
777 picking up other children that happen to be dead but that
778 we haven't noticed yet
779 SIG_DFL for SIGCHLD is ignore? */
780 if (sig_handlers[SIGCHLD] != SIG_DFL &&
781 sig_handlers[SIGCHLD] != SIG_IGN)
783 #ifdef FULL_DEBUG
784 DebPrint (("select calling SIGCHLD handler for pid %d\n",
785 cp->pid));
786 #endif
787 dead_child = cp;
788 sig_handlers[SIGCHLD](SIGCHLD);
789 dead_child = NULL;
792 /* Clean up the child process entry in the table */
793 remove_child (cp);
796 return nr;
800 Substitute for certain kill () operations
802 int
803 win32_kill_process (int pid, int sig)
805 child_process *cp;
807 /* Only handle signals that will result in the process dying */
808 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
810 errno = EINVAL;
811 return -1;
814 cp = find_child_pid (pid);
815 if (cp == NULL)
817 DebPrint (("win32_kill_process didn't find a child with pid %lu\n", pid));
818 errno = ECHILD;
819 return -1;
822 if (sig == SIGINT)
824 /* Fake Ctrl-Break. */
825 if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
827 DebPrint (("win32_kill_process.GenerateConsoleCtrlEvent return %d "
828 "for pid %lu\n", GetLastError (), pid));
829 errno = EINVAL;
830 return -1;
833 else
835 /* Kill the process. On Win32 this doesn't kill child processes
836 so it doesn't work very well for shells which is why it's
837 not used in every case. */
838 if (!TerminateProcess (cp->process, 0xff))
840 DebPrint (("win32_kill_process.TerminateProcess returned %d "
841 "for pid %lu\n", GetLastError (), pid));
842 errno = EINVAL;
843 return -1;
846 return 0;
849 /* If the channel is a pipe this read might block since we don't
850 know how many characters are available, so check and read only
851 what's there
852 We also need to wake up the reader thread once we've read our data. */
853 int
854 read_child_output (int fd, char *buf, int max)
856 HANDLE h;
857 int to_read, nchars;
858 DWORD waiting;
859 child_process *cp;
861 h = (HANDLE)_get_osfhandle (fd);
862 if (GetFileType (h) == FILE_TYPE_PIPE)
864 PeekNamedPipe (h, NULL, 0, NULL, &waiting, NULL);
865 to_read = min (waiting, (DWORD)max);
867 else
868 to_read = max;
870 /* Use read to get CRLF translation */
871 nchars = read (fd, buf, to_read);
873 if (GetFileType (h) == FILE_TYPE_PIPE)
875 /* Wake up the reader thread
876 for this process */
877 cp = find_child_fd (fd);
878 if (cp)
880 if (!SetEvent (cp->char_consumed))
881 DebPrint (("read_child_output.SetEvent failed with "
882 "%lu for fd %ld\n", GetLastError (), fd));
884 else
885 DebPrint (("read_child_output couldn't find a child with fd %d\n",
886 fd));
889 return nchars;