FSF GCC merge 02/23/03
[official-gcc.git] / gcc / ada / expect.c
blob175a7e057c6d19f432f1acd27672dd572203a62a
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * E X P E C T *
6 * *
7 * C Implementation File *
8 * *
9 * *
10 * Copyright (C) 2001-2002 Ada Core Technologies, Inc. *
11 * *
12 * GNAT is free software; you can redistribute it and/or modify it under *
13 * terms of the GNU General Public License as published by the Free Soft- *
14 * ware Foundation; either version 2, or (at your option) any later ver- *
15 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
16 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
18 * for more details. You should have received a copy of the GNU General *
19 * Public License distributed with GNAT; see file COPYING. If not, write *
20 * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
21 * MA 02111-1307, USA. *
22 * *
23 * As a special exception, if you link this file with other files to *
24 * produce an executable, this file does not by itself cause the resulting *
25 * executable to be covered by the GNU General Public License. This except- *
26 * ion does not however invalidate any other reasons why the executable *
27 * file might be covered by the GNU Public License. *
28 * *
29 * GNAT was originally developed by the GNAT team at New York University. *
30 * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
31 * *
32 ****************************************************************************/
34 #ifdef __alpha_vxworks
35 #include "vxWorks.h"
36 #endif
38 #ifdef IN_RTS
39 #define POSIX
40 #include "tconfig.h"
41 #include "tsystem.h"
42 #else
43 #include "config.h"
44 #include "system.h"
45 #endif
47 /* This file provides the low level functionalities needed to implement Expect
48 capabilities in GNAT.Expect.
49 Implementations for unix and windows systems is provided.
50 Dummy stubs are also provided for other systems. */
52 #ifdef _AIX
53 /* Work around the fact that gcc/cpp does not define "unix" under AiX. */
54 #define unix
55 #endif
57 #ifdef _WIN32
59 #include <windows.h>
60 #include <process.h>
62 /* ??? Provide a no-op for now */
64 void
65 kill ()
69 int
70 __gnat_expect_fork ()
72 return 0;
75 void
76 __gnat_expect_portable_execvp (pid, cmd, argv)
77 int *pid;
78 char *cmd;
79 char *argv[];
81 *pid = (int) spawnve (_P_NOWAIT, cmd, argv, NULL);
84 int
85 __gnat_pipe (fd)
86 int *fd;
88 HANDLE read, write;
90 CreatePipe (&read, &write, NULL, 0);
91 fd[0]=_open_osfhandle (read, 0);
92 fd[1]=_open_osfhandle (write, 0);
93 return 0; /* always success */
96 int
97 __gnat_expect_poll (fd, num_fd, timeout, is_set)
98 int *fd;
99 int num_fd;
100 int timeout;
101 int *is_set;
103 int i, num;
104 DWORD avail;
105 HANDLE handles[num_fd];
107 for (i = 0; i < num_fd; i++)
108 is_set[i] = 0;
110 for (i = 0; i < num_fd; i++)
111 handles[i] = (HANDLE) _get_osfhandle (fd[i]);
113 num = timeout / 50;
115 while (1)
117 for (i = 0; i < num_fd; i++)
119 if (!PeekNamedPipe (handles[i], NULL, 0, NULL, &avail, NULL))
120 return -1;
122 if (avail > 0)
124 is_set[i] = 1;
125 return 1;
129 if (timeout >= 0 && num == 0)
130 return 0;
132 Sleep (50);
133 num--;
137 #elif defined (VMS)
138 #include <unistd.h>
139 #include <stdio.h>
140 #include <unixio.h>
141 #include <stdlib.h>
142 #include <string.h>
143 #include <descrip.h>
144 #include <stdio.h>
145 #include <stsdef.h>
146 #include <iodef.h>
149 __gnat_pipe (fd)
150 int *fd;
152 return pipe (fd);
156 __gnat_expect_fork ()
158 return -1;
161 void
162 __gnat_expect_portable_execvp (pid, cmd, argv)
163 int *pid;
164 char *cmd;
165 char *argv[];
167 *pid = (int) getpid();
168 /* Since cmd is fully qualified, it is incorrect to to call execvp */
169 execv (cmd, argv);
173 __gnat_expect_poll (fd, num_fd, timeout, is_set)
174 int *fd;
175 int num_fd;
176 int timeout;
177 int *is_set;
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];
190 for (i = 0; i < num_fd; i++)
191 is_set[i] = 0;
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);
211 num = timeout / 100;
213 while (1)
215 for (i = 0; i < num_fd; i++)
217 if (mbxchans[i] > 0)
220 /* Peek in the mailbox to see if there's data */
221 status = SYS$QIOW
222 (0, mbxchans[i], IO$_SENSEMODE|IO$M_READERCHECK,
223 &iosb, 0, 0, 0, 0, 0, 0, 0, 0);
225 if (iosb.count > 0)
227 is_set[i] = 1;
228 ready = 1;
229 goto deassign;
234 if (timeout >= 0 && num == 0)
236 ready = 0;
237 goto deassign;
240 usleep (100000);
241 num--;
244 deassign:
246 /* Deassign channels assigned above */
247 for (i = 0; i < num_fd; i++)
249 if (mbxchans[i] > 0)
250 status = SYS$DASSGN (mbxchans[i]);
253 return ready;
256 #elif defined (unix)
258 #include <sys/time.h>
260 #ifndef NO_FD_SET
261 #define SELECT_MASK fd_set
262 #else /* !NO_FD_SET */
263 #ifndef _AIX
264 typedef long fd_mask;
265 #endif /* _AIX */
266 #ifdef _IBMR2
267 #define SELECT_MASK void
268 #else /* !_IBMR2 */
269 #define SELECT_MASK int
270 #endif /* !_IBMR2 */
271 #endif /* !NO_FD_SET */
274 __gnat_pipe (fd)
275 int *fd;
277 return pipe (fd);
281 __gnat_expect_fork ()
283 return fork ();
286 void
287 __gnat_expect_portable_execvp (pid, cmd, argv)
288 int *pid;
289 char *cmd;
290 char *argv[];
292 *pid = (int) getpid();
293 execvp (cmd, argv);
297 __gnat_expect_poll (fd, num_fd, timeout, is_set)
298 int *fd;
299 int num_fd;
300 int timeout;
301 int *is_set;
303 struct timeval tv;
304 SELECT_MASK rset;
305 int max_fd = 0;
306 int ready;
307 int i;
309 FD_ZERO (&rset);
311 for (i = 0; i < num_fd; i++)
313 FD_SET (fd[i], &rset);
314 if (fd[i] > max_fd)
315 max_fd = fd[i];
318 tv.tv_sec = timeout / 1000;
319 tv.tv_usec = (timeout % 1000) * 1000;
321 ready = select (max_fd + 1, &rset, NULL, NULL, timeout == -1 ? NULL : &tv);
323 if (ready > 0)
324 for (i = 0; i < num_fd; i++)
325 is_set[i] = (FD_ISSET (fd[i], &rset) ? 1 : 0);
327 return ready;
330 #else
333 __gnat_pipe (fd)
334 int *fd;
336 return -1;
340 __gnat_expect_fork ()
342 return -1;
345 void
346 __gnat_expect_portable_execvp (pid, cmd, argv)
347 int *pid;
348 char *cmd;
349 char *argv[];
351 *pid = 0;
355 __gnat_expect_poll (fd, num_fd, timeout, is_set)
356 int *fd;
357 int num_fd;
358 int timeout;
359 int *is_set;
361 return -1;
363 #endif