1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 2001-2003 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. */
62 __gnat_kill (int pid
, int sig
)
64 HANDLE process_handle
;
68 process_handle
= OpenProcess (PROCESS_TERMINATE
, FALSE
, pid
);
69 if (process_handle
!= NULL
)
70 TerminateProcess (process_handle
, 0);
75 __gnat_expect_fork (void)
81 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
83 *pid
= (int) spawnve (_P_NOWAIT
, cmd
, argv
, NULL
);
91 CreatePipe (&read
, &write
, NULL
, 0);
92 fd
[0]=_open_osfhandle ((long)read
, 0);
93 fd
[1]=_open_osfhandle ((long)write
, 0);
94 return 0; /* always success */
98 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
100 #define MAX_DELAY 100
102 int i
, delay
, infinite
= 0;
104 HANDLE handles
[num_fd
];
106 for (i
= 0; i
< num_fd
; i
++)
109 for (i
= 0; i
< num_fd
; i
++)
110 handles
[i
] = (HANDLE
) _get_osfhandle (fd
[i
]);
112 /* Start with small delays, and then increase them, to avoid polling too
113 much when waiting a long time */
121 for (i
= 0; i
< num_fd
; i
++)
123 if (!PeekNamedPipe (handles
[i
], NULL
, 0, NULL
, &avail
, NULL
))
133 if (!infinite
&& timeout
<= 0)
139 if (delay
< MAX_DELAY
)
156 __gnat_pipe (int *fd
)
162 __gnat_expect_fork (void)
168 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
170 *pid
= (int) getpid ();
171 /* Since cmd is fully qualified, it is incorrect to call execvp */
177 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
179 int i
, num
, ready
= 0;
181 int mbxchans
[num_fd
];
182 struct dsc$descriptor_s mbxname
;
183 struct io_status_block
{
190 for (i
= 0; i
< num_fd
; i
++)
193 for (i
= 0; i
< num_fd
; i
++)
196 /* Get name of the mailbox used in the pipe */
197 getname (fd
[i
], buf
);
199 /* Assign a channel to the mailbox */
200 if (strlen (buf
) > 0)
202 mbxname
.dsc$w_length
= strlen (buf
);
203 mbxname
.dsc$b_dtype
= DSC$K_DTYPE_T
;
204 mbxname
.dsc$b_class
= DSC$K_CLASS_S
;
205 mbxname
.dsc$a_pointer
= buf
;
207 status
= SYS$
ASSIGN (&mbxname
, &mbxchans
[i
], 0, 0, 0);
209 if ((status
& 1) != 1)
221 for (i
= 0; i
< num_fd
; i
++)
226 /* Peek in the mailbox to see if there's data */
228 (0, mbxchans
[i
], IO$_SENSEMODE
|IO$M_READERCHECK
,
229 &iosb
, 0, 0, 0, 0, 0, 0, 0, 0);
231 if ((status
& 1) != 1)
246 if (timeout
> 0 && num
== 0)
258 /* Deassign channels assigned above */
259 for (i
= 0; i
< num_fd
; i
++)
262 status
= SYS$
DASSGN (mbxchans
[i
]);
271 #include <sys/ptyio.h>
274 #include <sys/time.h>
277 #define SELECT_MASK fd_set
278 #else /* !NO_FD_SET */
280 typedef long fd_mask
;
283 #define SELECT_MASK void
285 #define SELECT_MASK int
287 #endif /* !NO_FD_SET */
290 __gnat_kill (int pid
, int sig
)
296 __gnat_pipe (int *fd
)
302 __gnat_expect_fork (void)
308 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
310 *pid
= (int) getpid ();
311 /* Since cmd is fully qualified, it is incorrect to call execvp */
317 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
328 tv
.tv_sec
= timeout
/ 1000;
329 tv
.tv_usec
= (timeout
% 1000) * 1000;
335 for (i
= 0; i
< num_fd
; i
++)
337 FD_SET (fd
[i
], &rset
);
338 FD_SET (fd
[i
], &eset
);
345 select (max_fd
+ 1, &rset
, NULL
, &eset
, timeout
== -1 ? NULL
: &tv
);
351 for (i
= 0; i
< num_fd
; i
++)
353 if (FD_ISSET (fd
[i
], &rset
))
363 for (i
= 0; i
< num_fd
; i
++)
365 if (FD_ISSET (fd
[i
], &eset
))
367 struct request_info ei
;
369 /* Only query and reset error state if no file descriptor
370 is ready to be read, otherwise we will be signalling a
371 died process too early */
375 ioctl (fd
[i
], TIOCREQCHECK
, &ei
);
377 if (ei
.request
== TIOCCLOSE
)
379 ioctl (fd
[i
], TIOCREQSET
, &ei
);
383 ioctl (fd
[i
], TIOCREQSET
, &ei
);
390 } while (timeout
== -1 && ready
== 0);
398 __gnat_kill (int pid
, int sig
)
403 __gnat_pipe (int *fd
)
409 __gnat_expect_fork (void)
415 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
421 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)