1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 2001-2004 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, 59 Temple Place - Suite 330, Boston, *
20 * MA 02111-1307, 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 /* This file provides the low level functionalities needed to implement Expect
47 capabilities in GNAT.Expect.
48 Implementations for unix and windows systems is provided.
49 Dummy stubs are also provided for other systems. */
52 /* Work around the fact that gcc/cpp does not define "__unix__" under AiX. */
57 /* Work around the fact that gcc/cpp does not define "__unix__" on Darwin. */
67 __gnat_kill (int pid
, int sig
)
69 HANDLE process_handle
;
73 process_handle
= OpenProcess (PROCESS_TERMINATE
, FALSE
, pid
);
74 if (process_handle
!= NULL
)
75 TerminateProcess (process_handle
, 0);
80 __gnat_expect_fork (void)
86 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
88 *pid
= (int) spawnve (_P_NOWAIT
, cmd
, argv
, NULL
);
96 CreatePipe (&read
, &write
, NULL
, 0);
97 fd
[0]=_open_osfhandle ((long)read
, 0);
98 fd
[1]=_open_osfhandle ((long)write
, 0);
99 return 0; /* always success */
103 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
105 #define MAX_DELAY 100
107 int i
, delay
, infinite
= 0;
109 HANDLE handles
[num_fd
];
111 for (i
= 0; i
< num_fd
; i
++)
114 for (i
= 0; i
< num_fd
; i
++)
115 handles
[i
] = (HANDLE
) _get_osfhandle (fd
[i
]);
117 /* Start with small delays, and then increase them, to avoid polling too
118 much when waiting a long time */
126 for (i
= 0; i
< num_fd
; i
++)
128 if (!PeekNamedPipe (handles
[i
], NULL
, 0, NULL
, &avail
, NULL
))
138 if (!infinite
&& timeout
<= 0)
144 if (delay
< MAX_DELAY
)
161 __gnat_pipe (int *fd
)
167 __gnat_expect_fork (void)
173 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
175 *pid
= (int) getpid ();
176 /* Since cmd is fully qualified, it is incorrect to call execvp */
182 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
184 int i
, num
, ready
= 0;
186 int mbxchans
[num_fd
];
187 struct dsc$descriptor_s mbxname
;
188 struct io_status_block
{
195 for (i
= 0; i
< num_fd
; i
++)
198 for (i
= 0; i
< num_fd
; i
++)
201 /* Get name of the mailbox used in the pipe */
202 getname (fd
[i
], buf
);
204 /* Assign a channel to the mailbox */
205 if (strlen (buf
) > 0)
207 mbxname
.dsc$w_length
= strlen (buf
);
208 mbxname
.dsc$b_dtype
= DSC$K_DTYPE_T
;
209 mbxname
.dsc$b_class
= DSC$K_CLASS_S
;
210 mbxname
.dsc$a_pointer
= buf
;
212 status
= SYS$
ASSIGN (&mbxname
, &mbxchans
[i
], 0, 0, 0);
214 if ((status
& 1) != 1)
226 for (i
= 0; i
< num_fd
; i
++)
231 /* Peek in the mailbox to see if there's data */
233 (0, mbxchans
[i
], IO$_SENSEMODE
|IO$M_READERCHECK
,
234 &iosb
, 0, 0, 0, 0, 0, 0, 0, 0);
236 if ((status
& 1) != 1)
251 if (timeout
> 0 && num
== 0)
263 /* Deassign channels assigned above */
264 for (i
= 0; i
< num_fd
; i
++)
267 status
= SYS$
DASSGN (mbxchans
[i
]);
273 #elif defined (__unix__)
276 #include <sys/ptyio.h>
279 #include <sys/time.h>
282 #define SELECT_MASK fd_set
283 #else /* !NO_FD_SET */
285 typedef long fd_mask
;
288 #define SELECT_MASK void
290 #define SELECT_MASK int
292 #endif /* !NO_FD_SET */
295 __gnat_kill (int pid
, int sig
)
301 __gnat_pipe (int *fd
)
307 __gnat_expect_fork (void)
313 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
315 *pid
= (int) getpid ();
316 /* Since cmd is fully qualified, it is incorrect to call execvp */
322 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
333 tv
.tv_sec
= timeout
/ 1000;
334 tv
.tv_usec
= (timeout
% 1000) * 1000;
340 for (i
= 0; i
< num_fd
; i
++)
342 FD_SET (fd
[i
], &rset
);
343 FD_SET (fd
[i
], &eset
);
350 select (max_fd
+ 1, &rset
, NULL
, &eset
, timeout
== -1 ? NULL
: &tv
);
356 for (i
= 0; i
< num_fd
; i
++)
358 if (FD_ISSET (fd
[i
], &rset
))
368 for (i
= 0; i
< num_fd
; i
++)
370 if (FD_ISSET (fd
[i
], &eset
))
372 struct request_info ei
;
374 /* Only query and reset error state if no file descriptor
375 is ready to be read, otherwise we will be signalling a
376 died process too early */
380 ioctl (fd
[i
], TIOCREQCHECK
, &ei
);
382 if (ei
.request
== TIOCCLOSE
)
384 ioctl (fd
[i
], TIOCREQSET
, &ei
);
388 ioctl (fd
[i
], TIOCREQSET
, &ei
);
395 } while (timeout
== -1 && ready
== 0);
403 __gnat_kill (int pid
, int sig
)
408 __gnat_pipe (int *fd
)
414 __gnat_expect_fork (void)
420 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
426 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)