]> gcc.gnu.org Git - gcc.git/blame - gcc/ada/expect.c
3psoccon.ads, [...]: Files added.
[gcc.git] / gcc / ada / expect.c
CommitLineData
70482933
RK
1/****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * E X P E C T *
6 * *
7 * C Implementation File *
8 * *
fbf5a39b 9 * Copyright (C) 2001-2003 Ada Core Technologies, Inc. *
70482933
RK
10 * *
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. *
21 * *
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. *
27 * *
28 * GNAT was originally developed by the GNAT team at New York University. *
fbf5a39b 29 * Extensive contributions were provided by Ada Core Technologies Inc. *
70482933
RK
30 * *
31 ****************************************************************************/
32
33#ifdef __alpha_vxworks
34#include "vxWorks.h"
35#endif
36
37#ifdef IN_RTS
38#define POSIX
39#include "tconfig.h"
40#include "tsystem.h"
41#else
42#include "config.h"
43#include "system.h"
44#endif
45
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. */
50
51#ifdef _AIX
52/* Work around the fact that gcc/cpp does not define "unix" under AiX. */
53#define unix
54#endif
55
56#ifdef _WIN32
57
58#include <windows.h>
59#include <process.h>
60
70482933 61void
fbf5a39b 62__gnat_kill (int pid, int sig)
70482933 63{
fbf5a39b
AC
64 HANDLE process_handle;
65
66 if (sig == 9)
67 {
68 process_handle = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
69 if (process_handle != NULL)
70 TerminateProcess (process_handle, 0);
71 }
70482933
RK
72}
73
74int
75__gnat_expect_fork ()
76{
77 return 0;
78}
79
80void
fbf5a39b 81__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
70482933 82{
07fc65c4 83 *pid = (int) spawnve (_P_NOWAIT, cmd, argv, NULL);
70482933
RK
84}
85
86int
fbf5a39b 87__gnat_pipe (int *fd)
70482933
RK
88{
89 HANDLE read, write;
90
91 CreatePipe (&read, &write, NULL, 0);
fbf5a39b
AC
92 fd[0]=_open_osfhandle ((long)read, 0);
93 fd[1]=_open_osfhandle ((long)write, 0);
70482933
RK
94 return 0; /* always success */
95}
96
97int
fbf5a39b 98__gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
70482933 99{
fbf5a39b
AC
100#define MAX_DELAY 100
101
102 int i, delay, infinite = 0;
70482933
RK
103 DWORD avail;
104 HANDLE handles[num_fd];
105
106 for (i = 0; i < num_fd; i++)
107 is_set[i] = 0;
108
109 for (i = 0; i < num_fd; i++)
fbf5a39b
AC
110 handles[i] = (HANDLE) _get_osfhandle (fd [i]);
111
112 /* Start with small delays, and then increase them, to avoid polling too
113 much when waiting a long time */
114 delay = 5;
70482933 115
fbf5a39b
AC
116 if (timeout < 0)
117 infinite = 1;
70482933
RK
118
119 while (1)
120 {
121 for (i = 0; i < num_fd; i++)
fbf5a39b
AC
122 {
123 if (!PeekNamedPipe (handles [i], NULL, 0, NULL, &avail, NULL))
124 return -1;
70482933 125
fbf5a39b
AC
126 if (avail > 0)
127 {
128 is_set[i] = 1;
129 return 1;
130 }
131 }
70482933 132
fbf5a39b
AC
133 if (!infinite && timeout <= 0)
134 return 0;
70482933 135
fbf5a39b
AC
136 Sleep (delay);
137 timeout -= delay;
138
139 if (delay < MAX_DELAY)
140 delay += 10;
70482933
RK
141 }
142}
143
07fc65c4
GB
144#elif defined (VMS)
145#include <unistd.h>
146#include <stdio.h>
147#include <unixio.h>
148#include <stdlib.h>
149#include <string.h>
150#include <descrip.h>
151#include <stdio.h>
152#include <stsdef.h>
153#include <iodef.h>
154
155int
fbf5a39b 156__gnat_pipe (int *fd)
07fc65c4
GB
157{
158 return pipe (fd);
159}
160
161int
162__gnat_expect_fork ()
163{
164 return -1;
165}
166
167void
fbf5a39b 168__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
07fc65c4 169{
fbf5a39b
AC
170 *pid = (int) getpid ();
171 /* Since cmd is fully qualified, it is incorrect to call execvp */
07fc65c4 172 execv (cmd, argv);
fbf5a39b 173 _exit (1);
07fc65c4
GB
174}
175
176int
fbf5a39b 177__gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
07fc65c4
GB
178{
179 int i, num, ready = 0;
180 unsigned int status;
181 int mbxchans [num_fd];
182 struct dsc$descriptor_s mbxname;
183 struct io_status_block {
184 short int condition;
185 short int count;
186 int dev;
187 } iosb;
188 char buf [256];
189
190 for (i = 0; i < num_fd; i++)
191 is_set[i] = 0;
192
193 for (i = 0; i < num_fd; i++)
194 {
195
196 /* Get name of the mailbox used in the pipe */
197 getname (fd [i], buf);
198
199 /* Assign a channel to the mailbox */
200 if (strlen (buf) > 0)
201 {
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;
206
207 status = SYS$ASSIGN (&mbxname, &mbxchans[i], 0, 0, 0);
fbf5a39b
AC
208
209 if ((status & 1) != 1)
210 {
211 ready = -1;
212 return ready;
213 }
07fc65c4
GB
214 }
215 }
216
217 num = timeout / 100;
218
219 while (1)
220 {
221 for (i = 0; i < num_fd; i++)
222 {
223 if (mbxchans[i] > 0)
224 {
225
226 /* Peek in the mailbox to see if there's data */
227 status = SYS$QIOW
228 (0, mbxchans[i], IO$_SENSEMODE|IO$M_READERCHECK,
229 &iosb, 0, 0, 0, 0, 0, 0, 0, 0);
230
fbf5a39b
AC
231 if ((status & 1) != 1)
232 {
233 ready = -1;
234 goto deassign;
235 }
236
07fc65c4
GB
237 if (iosb.count > 0)
238 {
239 is_set[i] = 1;
240 ready = 1;
241 goto deassign;
242 }
243 }
244 }
245
fbf5a39b 246 if (timeout > 0 && num == 0)
07fc65c4
GB
247 {
248 ready = 0;
249 goto deassign;
250 }
251
252 usleep (100000);
253 num--;
254 }
255
256 deassign:
257
258 /* Deassign channels assigned above */
259 for (i = 0; i < num_fd; i++)
260 {
261 if (mbxchans[i] > 0)
262 status = SYS$DASSGN (mbxchans[i]);
263 }
264
265 return ready;
266}
267
70482933
RK
268#elif defined (unix)
269
fbf5a39b
AC
270#ifdef hpux
271#include <sys/ptyio.h>
272#endif
273
70482933
RK
274#include <sys/time.h>
275
276#ifndef NO_FD_SET
277#define SELECT_MASK fd_set
278#else /* !NO_FD_SET */
279#ifndef _AIX
280typedef long fd_mask;
281#endif /* _AIX */
282#ifdef _IBMR2
283#define SELECT_MASK void
284#else /* !_IBMR2 */
285#define SELECT_MASK int
286#endif /* !_IBMR2 */
287#endif /* !NO_FD_SET */
288
fbf5a39b
AC
289void
290__gnat_kill (int pid, int sig)
291{
292 kill (pid, sig);
293}
294
70482933 295int
fbf5a39b 296__gnat_pipe (int *fd)
70482933
RK
297{
298 return pipe (fd);
299}
300
301int
302__gnat_expect_fork ()
303{
304 return fork ();
305}
306
307void
fbf5a39b 308__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
70482933 309{
fbf5a39b
AC
310 *pid = (int) getpid ();
311 /* Since cmd is fully qualified, it is incorrect to call execvp */
312 execv (cmd, argv);
313 _exit (1);
70482933
RK
314}
315
316int
fbf5a39b 317__gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
70482933
RK
318{
319 struct timeval tv;
320 SELECT_MASK rset;
fbf5a39b
AC
321 SELECT_MASK eset;
322
70482933
RK
323 int max_fd = 0;
324 int ready;
325 int i;
fbf5a39b 326 int received;
70482933
RK
327
328 tv.tv_sec = timeout / 1000;
329 tv.tv_usec = (timeout % 1000) * 1000;
330
fbf5a39b
AC
331 do {
332 FD_ZERO (&rset);
333 FD_ZERO (&eset);
70482933 334
70482933 335 for (i = 0; i < num_fd; i++)
fbf5a39b
AC
336 {
337 FD_SET (fd[i], &rset);
338 FD_SET (fd[i], &eset);
339
340 if (fd[i] > max_fd)
341 max_fd = fd[i];
342 }
343
344 ready =
345 select (max_fd + 1, &rset, NULL, &eset, timeout == -1 ? NULL : &tv);
346
347 if (ready > 0)
348 {
349 received = 0;
350
351 for (i = 0; i < num_fd; i++)
352 {
353 if (FD_ISSET (fd[i], &rset))
354 {
355 is_set[i] = 1;
356 received = 1;
357 }
358 else
359 is_set[i] = 0;
360 }
361
362#ifdef hpux
363 for (i = 0; i < num_fd; i++)
364 {
365 if (FD_ISSET (fd[i], &eset))
366 {
367 struct request_info ei;
368
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 */
372
373 if (!received)
374 {
375 ioctl (fd[i], TIOCREQCHECK, &ei);
376
377 if (ei.request == TIOCCLOSE)
378 {
379 ioctl (fd[i], TIOCREQSET, &ei);
380 return -1;
381 }
382
383 ioctl (fd[i], TIOCREQSET, &ei);
384 }
385 ready--;
386 }
387 }
388#endif
389 }
390 } while (timeout == -1 && ready == 0);
70482933
RK
391
392 return ready;
393}
394
395#else
396
fbf5a39b
AC
397void
398__gnat_kill (int pid, int sig)
399{
400}
401
70482933 402int
fbf5a39b 403__gnat_pipe (int *fd)
70482933
RK
404{
405 return -1;
406}
407
408int
409__gnat_expect_fork ()
410{
411 return -1;
412}
413
414void
fbf5a39b 415__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
70482933 416{
07fc65c4 417 *pid = 0;
70482933
RK
418}
419
420int
fbf5a39b 421__gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
70482933
RK
422{
423 return -1;
424}
425#endif
This page took 0.449979 seconds and 5 git commands to generate.