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
[])
117 *pid
= (int) spawnve (_P_NOWAIT
, cmd
, argv
, NULL
);
121 __gnat_pipe (int *fd
)
125 CreatePipe (&read
, &write
, NULL
, 0);
126 fd
[0]=_open_osfhandle ((long)read
, 0);
127 fd
[1]=_open_osfhandle ((long)write
, 0);
128 return 0; /* always success */
132 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
134 #define MAX_DELAY 100
136 int i
, delay
, infinite
= 0;
138 HANDLE handles
[num_fd
];
140 for (i
= 0; i
< num_fd
; i
++)
143 for (i
= 0; i
< num_fd
; i
++)
144 handles
[i
] = (HANDLE
) _get_osfhandle (fd
[i
]);
146 /* Start with small delays, and then increase them, to avoid polling too
147 much when waiting a long time */
155 for (i
= 0; i
< num_fd
; i
++)
157 if (!PeekNamedPipe (handles
[i
], NULL
, 0, NULL
, &avail
, NULL
))
167 if (!infinite
&& timeout
<= 0)
173 if (delay
< MAX_DELAY
)
184 #include <vms/descrip.h>
186 #include <vms/stsdef.h>
187 #include <vms/iodef.h>
190 __gnat_waitpid (int pid
)
194 waitpid (pid
, &status
, 0);
195 status
= WEXITSTATUS (status
);
201 __gnat_pipe (int *fd
)
207 __gnat_expect_fork (void)
213 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
215 *pid
= (int) getpid ();
216 /* Since cmd is fully qualified, it is incorrect to call execvp */
222 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
224 int i
, num
, ready
= 0;
226 int mbxchans
[num_fd
];
227 struct dsc$descriptor_s mbxname
;
228 struct io_status_block
{
235 for (i
= 0; i
< num_fd
; i
++)
238 for (i
= 0; i
< num_fd
; i
++)
241 /* Get name of the mailbox used in the pipe */
242 getname (fd
[i
], buf
);
244 /* Assign a channel to the mailbox */
245 if (strlen (buf
) > 0)
247 mbxname
.dsc$w_length
= strlen (buf
);
248 mbxname
.dsc$b_dtype
= DSC$K_DTYPE_T
;
249 mbxname
.dsc$b_class
= DSC$K_CLASS_S
;
250 mbxname
.dsc$a_pointer
= buf
;
252 status
= SYS$
ASSIGN (&mbxname
, &mbxchans
[i
], 0, 0, 0);
254 if ((status
& 1) != 1)
266 for (i
= 0; i
< num_fd
; i
++)
271 /* Peek in the mailbox to see if there's data */
273 (0, mbxchans
[i
], IO$_SENSEMODE
|IO$M_READERCHECK
,
274 &iosb
, 0, 0, 0, 0, 0, 0, 0, 0);
276 if ((status
& 1) != 1)
291 if (timeout
> 0 && num
== 0)
303 /* Deassign channels assigned above */
304 for (i
= 0; i
< num_fd
; i
++)
307 status
= SYS$
DASSGN (mbxchans
[i
]);
313 #elif defined (__unix__)
316 #include <sys/ptyio.h>
319 #include <sys/time.h>
322 #define SELECT_MASK fd_set
323 #else /* !NO_FD_SET */
325 typedef long fd_mask
;
328 #define SELECT_MASK void
330 #define SELECT_MASK int
332 #endif /* !NO_FD_SET */
335 __gnat_kill (int pid
, int sig
, int close
)
341 __gnat_waitpid (int pid
)
345 waitpid (pid
, &status
, 0);
346 status
= WEXITSTATUS (status
);
352 __gnat_pipe (int *fd
)
358 __gnat_expect_fork (void)
364 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
366 *pid
= (int) getpid ();
367 /* Since cmd is fully qualified, it is incorrect to call execvp */
373 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
384 tv
.tv_sec
= timeout
/ 1000;
385 tv
.tv_usec
= (timeout
% 1000) * 1000;
391 for (i
= 0; i
< num_fd
; i
++)
393 FD_SET (fd
[i
], &rset
);
394 FD_SET (fd
[i
], &eset
);
401 select (max_fd
+ 1, &rset
, NULL
, &eset
, timeout
== -1 ? NULL
: &tv
);
407 for (i
= 0; i
< num_fd
; i
++)
409 if (FD_ISSET (fd
[i
], &rset
))
419 for (i
= 0; i
< num_fd
; i
++)
421 if (FD_ISSET (fd
[i
], &eset
))
423 struct request_info ei
;
425 /* Only query and reset error state if no file descriptor
426 is ready to be read, otherwise we will be signalling a
427 died process too early */
431 ioctl (fd
[i
], TIOCREQCHECK
, &ei
);
433 if (ei
.request
== TIOCCLOSE
)
435 ioctl (fd
[i
], TIOCREQSET
, &ei
);
439 ioctl (fd
[i
], TIOCREQSET
, &ei
);
446 } while (timeout
== -1 && ready
== 0);
454 __gnat_kill (int pid
, int sig
, int close
)
459 __gnat_waitpid (int pid
, int sig
)
465 __gnat_pipe (int *fd
)
471 __gnat_expect_fork (void)
477 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
483 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)