OSDN Git Service

Delete all lines containing "$Revision:".
[pf3gnuchains/gcc-fork.git] / gcc / ada / expect.c
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  ****************************************************************************/
33
34 #ifdef __alpha_vxworks
35 #include "vxWorks.h"
36 #endif
37
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
46
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. */
51
52 #ifdef _AIX
53 /* Work around the fact that gcc/cpp does not define "unix" under AiX.  */
54 #define unix
55 #endif
56
57 #ifdef _WIN32
58
59 #include <windows.h>
60 #include <process.h>
61
62 /* ??? Provide a no-op for now */
63
64 void
65 kill ()
66 {
67 }
68
69 int
70 __gnat_expect_fork ()
71 {
72   return 0;
73 }
74
75 void
76 __gnat_expect_portable_execvp (pid, cmd, argv)
77      int *pid;
78      char *cmd;
79      char *argv[];
80 {
81   *pid = (int) spawnve (_P_NOWAIT, cmd, argv, NULL);
82 }
83
84 int
85 __gnat_pipe (fd)
86      int *fd;
87 {
88   HANDLE read, write;
89
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 */
94 }
95
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;
102 {
103   int i, num;
104   DWORD avail;
105   HANDLE handles[num_fd];
106
107   for (i = 0; i < num_fd; i++)
108     is_set[i] = 0;
109
110   for (i = 0; i < num_fd; i++)
111     handles[i] = (HANDLE) _get_osfhandle (fd[i]);
112
113   num = timeout / 50;
114
115   while (1)
116     {
117       for (i = 0; i < num_fd; i++)
118         {
119           if (!PeekNamedPipe (handles[i], NULL, 0, NULL, &avail, NULL))
120             return -1;
121
122           if (avail > 0)
123             {
124               is_set[i] = 1;
125               return 1;
126             }
127         }
128
129       if (timeout >= 0 && num == 0)
130         return 0;
131
132       Sleep (50);
133       num--;
134     }
135 }
136
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>
147
148 int
149 __gnat_pipe (fd)
150      int *fd;
151 {
152   return pipe (fd);
153 }
154
155 int
156 __gnat_expect_fork ()
157 {
158   return -1;
159 }
160
161 void
162 __gnat_expect_portable_execvp (pid, cmd, argv) 
163      int *pid;
164      char *cmd;
165      char *argv[];
166 {
167   *pid = (int) getpid();
168   /* Since cmd is fully qualified, it is incorrect to to call execvp */
169   execv (cmd, argv);
170 }
171
172 int
173 __gnat_expect_poll (fd, num_fd, timeout, is_set)
174      int *fd;
175      int num_fd;
176      int timeout;
177      int *is_set;
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);
208         }
209     }
210
211   num = timeout / 100;
212
213   while (1)
214     {
215       for (i = 0; i < num_fd; i++)
216         {
217           if (mbxchans[i] > 0)
218             {
219
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);
224
225               if (iosb.count > 0)
226                 {
227                   is_set[i] = 1;
228                   ready = 1;
229                   goto deassign;
230                 }
231             }
232         }
233
234       if (timeout >= 0 && num == 0)
235         {
236           ready = 0;
237           goto deassign;
238         }
239
240       usleep (100000);
241       num--;
242     }
243
244  deassign:
245
246   /* Deassign channels assigned above */
247   for (i = 0; i < num_fd; i++)
248     {
249       if (mbxchans[i] > 0)
250         status = SYS$DASSGN (mbxchans[i]);
251     }
252
253   return ready;
254 }
255
256 #elif defined (unix)
257
258 #include <sys/time.h>
259
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 */
272
273 int
274 __gnat_pipe (fd)
275      int *fd;
276 {
277   return pipe (fd);
278 }
279
280 int
281 __gnat_expect_fork ()
282 {
283   return fork ();
284 }
285
286 void
287 __gnat_expect_portable_execvp (pid, cmd, argv) 
288      int *pid;
289      char *cmd;
290      char *argv[];
291 {
292   *pid = (int) getpid();
293   execvp (cmd, argv);
294 }
295
296 int
297 __gnat_expect_poll (fd, num_fd, timeout, is_set)
298      int *fd;
299      int num_fd;
300      int timeout;
301      int *is_set;
302 {
303   struct timeval tv;
304   SELECT_MASK rset;
305   int max_fd = 0;
306   int ready;
307   int i;
308
309   FD_ZERO (&rset);
310
311   for (i = 0; i < num_fd; i++)
312     {
313       FD_SET (fd[i], &rset);
314       if (fd[i] > max_fd)
315         max_fd = fd[i];
316     }
317
318   tv.tv_sec  = timeout / 1000;
319   tv.tv_usec = (timeout % 1000) * 1000;
320
321   ready = select (max_fd + 1, &rset, NULL, NULL, timeout == -1 ? NULL : &tv);
322
323   if (ready > 0)
324     for (i = 0; i < num_fd; i++)
325       is_set[i] = (FD_ISSET (fd[i], &rset)  ? 1 : 0);
326
327   return ready;
328 }
329
330 #else
331
332 int
333 __gnat_pipe (fd)
334      int *fd;
335 {
336   return -1;
337 }
338
339 int
340 __gnat_expect_fork ()
341 {
342   return -1;
343 }
344
345 void
346 __gnat_expect_portable_execvp (pid, cmd, argv)
347      int *pid;
348      char *cmd;
349      char *argv[];
350 {
351   *pid = 0;
352 }
353
354 int
355 __gnat_expect_poll (fd, num_fd, timeout, is_set)
356      int *fd;
357      int num_fd;
358      int timeout;
359      int *is_set;
360 {
361   return -1;
362 }
363 #endif