1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 2001-2005 Ada Core Technologies, Inc. *
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)
81 HANDLE process_handle;
85 process_handle = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
86 if (process_handle != NULL)
88 TerminateProcess (process_handle, 0);
89 CloseHandle (process_handle);
95 __gnat_waitpid (int pid)
97 HANDLE process_handle;
101 process_handle = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, pid);
103 if (process_handle != NULL)
105 res = WaitForSingleObject (process_handle, INFINITE);
106 GetExitCodeProcess (process_handle, &exitcode);
107 CloseHandle (process_handle);
110 return (int) exitcode;
114 __gnat_expect_fork (void)
120 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
122 *pid = (int) spawnve (_P_NOWAIT, cmd, argv, NULL);
126 __gnat_pipe (int *fd)
130 CreatePipe (&read, &write, NULL, 0);
131 fd[0]=_open_osfhandle ((long)read, 0);
132 fd[1]=_open_osfhandle ((long)write, 0);
133 return 0; /* always success */
137 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
139 #define MAX_DELAY 100
141 int i, delay, infinite = 0;
143 HANDLE handles[num_fd];
145 for (i = 0; i < num_fd; i++)
148 for (i = 0; i < num_fd; i++)
149 handles[i] = (HANDLE) _get_osfhandle (fd [i]);
151 /* Start with small delays, and then increase them, to avoid polling too
152 much when waiting a long time */
160 for (i = 0; i < num_fd; i++)
162 if (!PeekNamedPipe (handles [i], NULL, 0, NULL, &avail, NULL))
172 if (!infinite && timeout <= 0)
178 if (delay < MAX_DELAY)
189 #include <vms/descrip.h>
191 #include <vms/stsdef.h>
192 #include <vms/iodef.h>
195 __gnat_waitpid (int pid)
199 waitpid (pid, &status, 0);
200 status = WEXITSTATUS (status);
206 __gnat_pipe (int *fd)
212 __gnat_expect_fork (void)
218 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
220 *pid = (int) getpid ();
221 /* Since cmd is fully qualified, it is incorrect to call execvp */
227 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
229 int i, num, ready = 0;
231 int mbxchans [num_fd];
232 struct dsc$descriptor_s mbxname;
233 struct io_status_block {
240 for (i = 0; i < num_fd; i++)
243 for (i = 0; i < num_fd; i++)
246 /* Get name of the mailbox used in the pipe */
247 getname (fd [i], buf);
249 /* Assign a channel to the mailbox */
250 if (strlen (buf) > 0)
252 mbxname.dsc$w_length = strlen (buf);
253 mbxname.dsc$b_dtype = DSC$K_DTYPE_T;
254 mbxname.dsc$b_class = DSC$K_CLASS_S;
255 mbxname.dsc$a_pointer = buf;
257 status = SYS$ASSIGN (&mbxname, &mbxchans[i], 0, 0, 0);
259 if ((status & 1) != 1)
271 for (i = 0; i < num_fd; i++)
276 /* Peek in the mailbox to see if there's data */
278 (0, mbxchans[i], IO$_SENSEMODE|IO$M_READERCHECK,
279 &iosb, 0, 0, 0, 0, 0, 0, 0, 0);
281 if ((status & 1) != 1)
296 if (timeout > 0 && num == 0)
308 /* Deassign channels assigned above */
309 for (i = 0; i < num_fd; i++)
312 status = SYS$DASSGN (mbxchans[i]);
318 #elif defined (__unix__)
321 #include <sys/ptyio.h>
324 #include <sys/time.h>
327 #define SELECT_MASK fd_set
328 #else /* !NO_FD_SET */
330 typedef long fd_mask;
333 #define SELECT_MASK void
335 #define SELECT_MASK int
337 #endif /* !NO_FD_SET */
340 __gnat_kill (int pid, int sig)
346 __gnat_waitpid (int pid)
350 waitpid (pid, &status, 0);
351 status = WEXITSTATUS (status);
357 __gnat_pipe (int *fd)
363 __gnat_expect_fork (void)
369 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
371 *pid = (int) getpid ();
372 /* Since cmd is fully qualified, it is incorrect to call execvp */
378 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
389 tv.tv_sec = timeout / 1000;
390 tv.tv_usec = (timeout % 1000) * 1000;
396 for (i = 0; i < num_fd; i++)
398 FD_SET (fd[i], &rset);
399 FD_SET (fd[i], &eset);
406 select (max_fd + 1, &rset, NULL, &eset, timeout == -1 ? NULL : &tv);
412 for (i = 0; i < num_fd; i++)
414 if (FD_ISSET (fd[i], &rset))
424 for (i = 0; i < num_fd; i++)
426 if (FD_ISSET (fd[i], &eset))
428 struct request_info ei;
430 /* Only query and reset error state if no file descriptor
431 is ready to be read, otherwise we will be signalling a
432 died process too early */
436 ioctl (fd[i], TIOCREQCHECK, &ei);
438 if (ei.request == TIOCCLOSE)
440 ioctl (fd[i], TIOCREQSET, &ei);
444 ioctl (fd[i], TIOCREQSET, &ei);
451 } while (timeout == -1 && ready == 0);
459 __gnat_kill (int pid, int sig)
464 __gnat_waitpid (int pid, int sig)
470 __gnat_pipe (int *fd)
476 __gnat_expect_fork (void)
482 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
488 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)