1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 2001-2005, AdaCore *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 2, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. You should have received a copy of the GNU General *
18 * Public License distributed with GNAT; see file COPYING. If not, write *
19 * to the Free Software Foundation, 51 Franklin Street, Fifth Floor, *
20 * Boston, MA 02110-1301, USA. *
22 * As a special exception, if you link this file with other files to *
23 * produce an executable, this file does not by itself cause the resulting *
24 * executable to be covered by the GNU General Public License. This except- *
25 * ion does not however invalidate any other reasons why the executable *
26 * file might be covered by the GNU Public License. *
28 * GNAT was originally developed by the GNAT team at New York University. *
29 * Extensive contributions were provided by Ada Core Technologies Inc. *
31 ****************************************************************************/
33 #ifdef __alpha_vxworks
46 #include <sys/types.h>
52 #elif defined (__vxworks) && defined (__RTP__)
58 /* This file provides the low level functionalities needed to implement Expect
59 capabilities in GNAT.Expect.
60 Implementations for unix and windows systems is provided.
61 Dummy stubs are also provided for other systems. */
64 /* Work around the fact that gcc/cpp does not define "__unix__" under AiX. */
69 /* Work around the fact that gcc/cpp does not define "__unix__" on Darwin. */
79 __gnat_kill (int pid, int sig, int close)
83 if ((HANDLE)pid != NULL)
85 TerminateProcess ((HANDLE)pid, 0);
87 CloseHandle ((HANDLE)pid);
93 __gnat_waitpid (int pid)
98 if ((HANDLE)pid != NULL)
100 res = WaitForSingleObject ((HANDLE)pid, INFINITE);
101 GetExitCodeProcess ((HANDLE)pid, &exitcode);
102 CloseHandle ((HANDLE)pid);
105 return (int) exitcode;
109 __gnat_expect_fork (void)
115 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
119 PROCESS_INFORMATION PI;
120 SECURITY_ATTRIBUTES SA;
125 /* compute the total command line length. */
129 csize += strlen (argv[k]) + 1;
133 full_command = (char *) malloc (csize);
134 full_command[0] = '\0';
137 SI.cb = sizeof (STARTUPINFO);
138 SI.lpReserved = NULL;
139 SI.lpReserved2 = NULL;
144 SI.wShowWindow = SW_HIDE;
146 /* Security attributes. */
147 SA.nLength = sizeof (SECURITY_ATTRIBUTES);
148 SA.bInheritHandle = TRUE;
149 SA.lpSecurityDescriptor = NULL;
154 strcat (full_command, argv[k]);
155 strcat (full_command, " ");
159 result = CreateProcess
160 (NULL, (char *) full_command, &SA, NULL, TRUE,
161 GetPriorityClass (GetCurrentProcess()), NULL, NULL, &SI, &PI);
167 CloseHandle (PI.hThread);
168 *pid = (int) PI.hProcess;
175 __gnat_pipe (int *fd)
179 CreatePipe (&read, &write, NULL, 0);
180 fd[0]=_open_osfhandle ((long)read, 0);
181 fd[1]=_open_osfhandle ((long)write, 0);
182 return 0; /* always success */
186 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
188 #define MAX_DELAY 100
190 int i, delay, infinite = 0;
192 HANDLE handles[num_fd];
194 for (i = 0; i < num_fd; i++)
197 for (i = 0; i < num_fd; i++)
198 handles[i] = (HANDLE) _get_osfhandle (fd [i]);
200 /* Start with small delays, and then increase them, to avoid polling too
201 much when waiting a long time */
209 for (i = 0; i < num_fd; i++)
211 if (!PeekNamedPipe (handles [i], NULL, 0, NULL, &avail, NULL))
221 if (!infinite && timeout <= 0)
227 if (delay < MAX_DELAY)
238 #include <vms/descrip.h>
240 #include <vms/stsdef.h>
241 #include <vms/iodef.h>
244 __gnat_waitpid (int pid)
248 waitpid (pid, &status, 0);
249 status = WEXITSTATUS (status);
255 __gnat_pipe (int *fd)
261 __gnat_expect_fork (void)
267 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
269 *pid = (int) getpid ();
270 /* Since cmd is fully qualified, it is incorrect to call execvp */
276 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
278 int i, num, ready = 0;
280 int mbxchans [num_fd];
281 struct dsc$descriptor_s mbxname;
282 struct io_status_block {
289 for (i = 0; i < num_fd; i++)
292 for (i = 0; i < num_fd; i++)
295 /* Get name of the mailbox used in the pipe */
296 getname (fd [i], buf);
298 /* Assign a channel to the mailbox */
299 if (strlen (buf) > 0)
301 mbxname.dsc$w_length = strlen (buf);
302 mbxname.dsc$b_dtype = DSC$K_DTYPE_T;
303 mbxname.dsc$b_class = DSC$K_CLASS_S;
304 mbxname.dsc$a_pointer = buf;
306 status = SYS$ASSIGN (&mbxname, &mbxchans[i], 0, 0, 0);
308 if ((status & 1) != 1)
320 for (i = 0; i < num_fd; i++)
325 /* Peek in the mailbox to see if there's data */
327 (0, mbxchans[i], IO$_SENSEMODE|IO$M_READERCHECK,
328 &iosb, 0, 0, 0, 0, 0, 0, 0, 0);
330 if ((status & 1) != 1)
345 if (timeout > 0 && num == 0)
357 /* Deassign channels assigned above */
358 for (i = 0; i < num_fd; i++)
361 status = SYS$DASSGN (mbxchans[i]);
367 #elif defined (__unix__)
370 #include <sys/ptyio.h>
373 #include <sys/time.h>
376 #define SELECT_MASK fd_set
377 #else /* !NO_FD_SET */
379 typedef long fd_mask;
382 #define SELECT_MASK void
384 #define SELECT_MASK int
386 #endif /* !NO_FD_SET */
389 __gnat_kill (int pid, int sig, int close)
395 __gnat_waitpid (int pid)
399 waitpid (pid, &status, 0);
400 status = WEXITSTATUS (status);
406 __gnat_pipe (int *fd)
412 __gnat_expect_fork (void)
418 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
420 *pid = (int) getpid ();
421 /* Since cmd is fully qualified, it is incorrect to call execvp */
427 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
438 tv.tv_sec = timeout / 1000;
439 tv.tv_usec = (timeout % 1000) * 1000;
445 for (i = 0; i < num_fd; i++)
447 FD_SET (fd[i], &rset);
448 FD_SET (fd[i], &eset);
455 select (max_fd + 1, &rset, NULL, &eset, timeout == -1 ? NULL : &tv);
461 for (i = 0; i < num_fd; i++)
463 if (FD_ISSET (fd[i], &rset))
473 for (i = 0; i < num_fd; i++)
475 if (FD_ISSET (fd[i], &eset))
477 struct request_info ei;
479 /* Only query and reset error state if no file descriptor
480 is ready to be read, otherwise we will be signalling a
481 died process too early */
485 ioctl (fd[i], TIOCREQCHECK, &ei);
487 if (ei.request == TIOCCLOSE)
489 ioctl (fd[i], TIOCREQSET, &ei);
493 ioctl (fd[i], TIOCREQSET, &ei);
500 } while (timeout == -1 && ready == 0);
508 __gnat_kill (int pid, int sig, int close)
513 __gnat_waitpid (int pid, int sig)
519 __gnat_pipe (int *fd)
525 __gnat_expect_fork (void)
531 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
537 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)