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, 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 #include <sys/types.h>
56 /* This file provides the low level functionalities needed to implement Expect
57 capabilities in GNAT.Expect.
58 Implementations for unix and windows systems is provided.
59 Dummy stubs are also provided for other systems. */
62 /* Work around the fact that gcc/cpp does not define "__unix__" under AiX. */
67 /* Work around the fact that gcc/cpp does not define "__unix__" on Darwin. */
77 __gnat_kill (int pid
, int sig
)
79 HANDLE process_handle
;
83 process_handle
= OpenProcess (PROCESS_TERMINATE
, FALSE
, pid
);
84 if (process_handle
!= NULL
)
86 TerminateProcess (process_handle
, 0);
87 CloseHandle (process_handle
);
93 __gnat_waitpid (int pid
)
95 HANDLE process_handle
;
99 process_handle
= OpenProcess (PROCESS_QUERY_INFORMATION
, FALSE
, pid
);
101 if (process_handle
!= NULL
)
103 res
= WaitForSingleObject (process_handle
, INFINITE
);
104 GetExitCodeProcess (process_handle
, &exitcode
);
105 CloseHandle (process_handle
);
108 return (int) exitcode
;
112 __gnat_expect_fork (void)
118 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
120 *pid
= (int) spawnve (_P_NOWAIT
, cmd
, argv
, NULL
);
124 __gnat_pipe (int *fd
)
128 CreatePipe (&read
, &write
, NULL
, 0);
129 fd
[0]=_open_osfhandle ((long)read
, 0);
130 fd
[1]=_open_osfhandle ((long)write
, 0);
131 return 0; /* always success */
135 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
137 #define MAX_DELAY 100
139 int i
, delay
, infinite
= 0;
141 HANDLE handles
[num_fd
];
143 for (i
= 0; i
< num_fd
; i
++)
146 for (i
= 0; i
< num_fd
; i
++)
147 handles
[i
] = (HANDLE
) _get_osfhandle (fd
[i
]);
149 /* Start with small delays, and then increase them, to avoid polling too
150 much when waiting a long time */
158 for (i
= 0; i
< num_fd
; i
++)
160 if (!PeekNamedPipe (handles
[i
], NULL
, 0, NULL
, &avail
, NULL
))
170 if (!infinite
&& timeout
<= 0)
176 if (delay
< MAX_DELAY
)
187 #include <vms/descrip.h>
189 #include <vms/stsdef.h>
190 #include <vms/iodef.h>
193 __gnat_waitpid (int pid
)
197 waitpid (pid
, &status
, 0);
198 status
= WEXITSTATUS (status
);
204 __gnat_pipe (int *fd
)
210 __gnat_expect_fork (void)
216 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
218 *pid
= (int) getpid ();
219 /* Since cmd is fully qualified, it is incorrect to call execvp */
225 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
227 int i
, num
, ready
= 0;
229 int mbxchans
[num_fd
];
230 struct dsc$descriptor_s mbxname
;
231 struct io_status_block
{
238 for (i
= 0; i
< num_fd
; i
++)
241 for (i
= 0; i
< num_fd
; i
++)
244 /* Get name of the mailbox used in the pipe */
245 getname (fd
[i
], buf
);
247 /* Assign a channel to the mailbox */
248 if (strlen (buf
) > 0)
250 mbxname
.dsc$w_length
= strlen (buf
);
251 mbxname
.dsc$b_dtype
= DSC$K_DTYPE_T
;
252 mbxname
.dsc$b_class
= DSC$K_CLASS_S
;
253 mbxname
.dsc$a_pointer
= buf
;
255 status
= SYS$
ASSIGN (&mbxname
, &mbxchans
[i
], 0, 0, 0);
257 if ((status
& 1) != 1)
269 for (i
= 0; i
< num_fd
; i
++)
274 /* Peek in the mailbox to see if there's data */
276 (0, mbxchans
[i
], IO$_SENSEMODE
|IO$M_READERCHECK
,
277 &iosb
, 0, 0, 0, 0, 0, 0, 0, 0);
279 if ((status
& 1) != 1)
294 if (timeout
> 0 && num
== 0)
306 /* Deassign channels assigned above */
307 for (i
= 0; i
< num_fd
; i
++)
310 status
= SYS$
DASSGN (mbxchans
[i
]);
316 #elif defined (__unix__)
319 #include <sys/ptyio.h>
322 #include <sys/time.h>
325 #define SELECT_MASK fd_set
326 #else /* !NO_FD_SET */
328 typedef long fd_mask
;
331 #define SELECT_MASK void
333 #define SELECT_MASK int
335 #endif /* !NO_FD_SET */
338 __gnat_kill (int pid
, int sig
)
344 __gnat_waitpid (int pid
)
348 waitpid (pid
, &status
, 0);
349 status
= WEXITSTATUS (status
);
355 __gnat_pipe (int *fd
)
361 __gnat_expect_fork (void)
367 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
369 *pid
= (int) getpid ();
370 /* Since cmd is fully qualified, it is incorrect to call execvp */
376 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)
387 tv
.tv_sec
= timeout
/ 1000;
388 tv
.tv_usec
= (timeout
% 1000) * 1000;
394 for (i
= 0; i
< num_fd
; i
++)
396 FD_SET (fd
[i
], &rset
);
397 FD_SET (fd
[i
], &eset
);
404 select (max_fd
+ 1, &rset
, NULL
, &eset
, timeout
== -1 ? NULL
: &tv
);
410 for (i
= 0; i
< num_fd
; i
++)
412 if (FD_ISSET (fd
[i
], &rset
))
422 for (i
= 0; i
< num_fd
; i
++)
424 if (FD_ISSET (fd
[i
], &eset
))
426 struct request_info ei
;
428 /* Only query and reset error state if no file descriptor
429 is ready to be read, otherwise we will be signalling a
430 died process too early */
434 ioctl (fd
[i
], TIOCREQCHECK
, &ei
);
436 if (ei
.request
== TIOCCLOSE
)
438 ioctl (fd
[i
], TIOCREQSET
, &ei
);
442 ioctl (fd
[i
], TIOCREQSET
, &ei
);
449 } while (timeout
== -1 && ready
== 0);
457 __gnat_kill (int pid
, int sig
)
462 __gnat_waitpid (int pid
, int sig
)
468 __gnat_pipe (int *fd
)
474 __gnat_expect_fork (void)
480 __gnat_expect_portable_execvp (int *pid
, char *cmd
, char *argv
[])
486 __gnat_expect_poll (int *fd
, int num_fd
, int timeout
, int *is_set
)