1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 2001-2009, 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__)
54 #elif defined (__Lynx__)
55 /* ??? See comment in adaint.c. */
56 #define GCC_RESOURCE_H
58 #elif defined (__nucleus__)
59 /* No wait.h available on Nucleus */
64 /* This file provides the low level functionalities needed to implement Expect
65 capabilities in GNAT.Expect.
66 Implementations for unix and windows systems is provided.
67 Dummy stubs are also provided for other systems. */
70 /* Work around the fact that gcc/cpp does not define "__unix__" under AiX. */
75 /* Work around the fact that gcc/cpp does not define "__unix__" on Darwin. */
88 __gnat_kill (int pid
, int sig
, int close
)
90 HANDLE h
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
, pid
);
95 TerminateProcess (h
, 0);
96 __gnat_win32_remove_handle (NULL
, pid
);
98 else if (sig
== SIGINT
)
99 GenerateConsoleCtrlEvent (CTRL_C_EVENT
, pid
);
100 else if (sig
== SIGBREAK
)
101 GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT
, pid
);
102 /* ??? The last two alternatives don't really work. SIGBREAK requires setting
103 up process groups at start time which we don't do; treating SIGINT is just
104 not possible apparently. So we really only support signal 9. Fortunately
105 that's all we use in GNAT.Expect */
111 __gnat_waitpid (int pid
)
113 HANDLE h
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
, pid
);
119 res
= WaitForSingleObject (h
, INFINITE
);
120 GetExitCodeProcess (h
, &exitcode
);
124 __gnat_win32_remove_handle (NULL
, pid
);
125 return (int) exitcode
;
129 __gnat_expect_fork (void)
135 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
137 *pid
= __gnat_portable_no_block_spawn (argv
);
141 __gnat_pipe (int *fd
)
145 CreatePipe (&read
, &write
, NULL
, 0);
146 fd
[0]=_open_osfhandle ((intptr_t)read
, 0);
147 fd
[1]=_open_osfhandle ((intptr_t)write
, 0);
148 return 0; /* always success */
152 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
154 #define MAX_DELAY 100
156 int i
, delay
, infinite
= 0;
158 HANDLE handles
[num_fd
];
160 for (i
= 0; i
< num_fd
; i
++)
163 for (i
= 0; i
< num_fd
; i
++)
164 handles
[i
] = (HANDLE
) _get_osfhandle (fd
[i
]);
166 /* Start with small delays, and then increase them, to avoid polling too
167 much when waiting a long time */
175 for (i
= 0; i
< num_fd
; i
++)
177 if (!PeekNamedPipe (handles
[i
], NULL
, 0, NULL
, &avail
, NULL
))
187 if (!infinite
&& timeout
<= 0)
193 if (delay
< MAX_DELAY
)
204 #include <vms/descrip.h>
206 #include <vms/stsdef.h>
207 #include <vms/iodef.h>
211 __gnat_kill (int pid
, int sig
, int close
)
217 __gnat_waitpid (int pid
)
221 waitpid (pid
, &status
, 0);
222 status
= WEXITSTATUS (status
);
228 __gnat_pipe (int *fd
)
234 __gnat_expect_fork (void)
240 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
242 *pid
= (int) getpid ();
243 /* Since cmd is fully qualified, it is incorrect to call execvp */
249 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
251 int i
, num
, ready
= 0;
253 int mbxchans
[num_fd
];
254 struct dsc$descriptor_s mbxname
;
255 struct io_status_block
{
262 for (i
= 0; i
< num_fd
; i
++)
265 for (i
= 0; i
< num_fd
; i
++)
268 /* Get name of the mailbox used in the pipe */
269 getname (fd
[i
], buf
);
271 /* Assign a channel to the mailbox */
272 if (strlen (buf
) > 0)
274 mbxname
.dsc$w_length
= strlen (buf
);
275 mbxname
.dsc$b_dtype
= DSC$K_DTYPE_T
;
276 mbxname
.dsc$b_class
= DSC$K_CLASS_S
;
277 mbxname
.dsc$a_pointer
= buf
;
279 status
= SYS$
ASSIGN (&mbxname
, &mbxchans
[i
], 0, 0, 0);
281 if ((status
& 1) != 1)
293 for (i
= 0; i
< num_fd
; i
++)
298 /* Peek in the mailbox to see if there's data */
300 (0, mbxchans
[i
], IO$_SENSEMODE
|IO$M_READERCHECK
,
301 &iosb
, 0, 0, 0, 0, 0, 0, 0, 0);
303 if ((status
& 1) != 1)
318 if (timeout
> 0 && num
== 0)
330 /* Deassign channels assigned above */
331 for (i
= 0; i
< num_fd
; i
++)
334 status
= SYS$
DASSGN (mbxchans
[i
]);
339 #elif defined (__unix__) && !defined (__nucleus__)
342 #include <sys/ptyio.h>
345 #include <sys/time.h>
348 #define SELECT_MASK fd_set
349 #else /* !NO_FD_SET */
351 typedef long fd_mask
;
354 #define SELECT_MASK void
356 #define SELECT_MASK int
358 #endif /* !NO_FD_SET */
361 __gnat_kill (int pid
, int sig
, int close
)
367 __gnat_waitpid (int pid
)
371 waitpid (pid
, &status
, 0);
372 status
= WEXITSTATUS (status
);
378 __gnat_pipe (int *fd
)
384 __gnat_expect_fork (void)
390 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
392 *pid
= (int) getpid ();
393 /* Since cmd is fully qualified, it is incorrect to call execvp */
399 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
410 tv
.tv_sec
= timeout
/ 1000;
411 tv
.tv_usec
= (timeout
% 1000) * 1000;
417 for (i
= 0; i
< num_fd
; i
++)
419 FD_SET (fd
[i
], &rset
);
420 FD_SET (fd
[i
], &eset
);
427 select (max_fd
+ 1, &rset
, NULL
, &eset
, timeout
== -1 ? NULL
: &tv
);
433 for (i
= 0; i
< num_fd
; i
++)
435 if (FD_ISSET (fd
[i
], &rset
))
445 for (i
= 0; i
< num_fd
; i
++)
447 if (FD_ISSET (fd
[i
], &eset
))
449 struct request_info ei
;
451 /* Only query and reset error state if no file descriptor
452 is ready to be read, otherwise we will be signalling a
453 died process too early */
457 ioctl (fd
[i
], TIOCREQCHECK
, &ei
);
459 if (ei
.request
== TIOCCLOSE
)
461 ioctl (fd
[i
], TIOCREQSET
, &ei
);
465 ioctl (fd
[i
], TIOCREQSET
, &ei
);
472 } while (timeout
== -1 && ready
== 0);
480 __gnat_kill (int pid
, int sig
, int close
)
485 __gnat_waitpid (int pid
, int sig
)
491 __gnat_pipe (int *fd
)
497 __gnat_expect_fork (void)
503 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
509 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)