* c-cppbuiltin.c (c_cpp_builtins): Define __pic__ and __PIC__ when
[official-gcc.git] / gcc / ada / expect.c
blobdd03b1ca1f8452dc93d955ed5ad4b4f498b0a25a
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * E X P E C T *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 2001-2005, AdaCore *
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, 51 Franklin Street, Fifth Floor, *
20 * Boston, MA 02110-1301, 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. *
29 * Extensive contributions were provided by Ada Core Technologies Inc. *
30 * *
31 ****************************************************************************/
33 #ifdef __alpha_vxworks
34 #include "vxWorks.h"
35 #endif
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
46 #include <sys/types.h>
48 #ifdef __MINGW32__
49 #if OLD_MINGW
50 #include <sys/wait.h>
51 #endif
52 #elif defined (__vxworks) && defined (__RTP__)
53 #include <wait.h>
54 #else
55 #include <sys/wait.h>
56 #endif
58 /* This file provides the low level functionalities needed to implement Expect
59 capabilities in GNAT.Expect.
60 Implementations for unix and windows systems is provided.
61 Dummy stubs are also provided for other systems. */
63 #ifdef _AIX
64 /* Work around the fact that gcc/cpp does not define "__unix__" under AiX. */
65 #define __unix__
66 #endif
68 #ifdef __APPLE__
69 /* Work around the fact that gcc/cpp does not define "__unix__" on Darwin. */
70 #define __unix__
71 #endif
73 #ifdef _WIN32
75 #include <windows.h>
76 #include <process.h>
78 void
79 __gnat_kill (int pid, int sig, int close)
81 if (sig == 9)
83 if ((HANDLE)pid != NULL)
85 TerminateProcess ((HANDLE)pid, 0);
86 if (close)
87 CloseHandle ((HANDLE)pid);
92 int
93 __gnat_waitpid (int pid)
95 DWORD exitcode = 1;
96 DWORD res;
98 if ((HANDLE)pid != NULL)
100 res = WaitForSingleObject ((HANDLE)pid, INFINITE);
101 GetExitCodeProcess ((HANDLE)pid, &exitcode);
102 CloseHandle ((HANDLE)pid);
105 return (int) exitcode;
109 __gnat_expect_fork (void)
111 return 0;
114 void
115 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
117 *pid = (int) spawnve (_P_NOWAIT, cmd, argv, NULL);
121 __gnat_pipe (int *fd)
123 HANDLE read, write;
125 CreatePipe (&read, &write, NULL, 0);
126 fd[0]=_open_osfhandle ((long)read, 0);
127 fd[1]=_open_osfhandle ((long)write, 0);
128 return 0; /* always success */
132 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
134 #define MAX_DELAY 100
136 int i, delay, infinite = 0;
137 DWORD avail;
138 HANDLE handles[num_fd];
140 for (i = 0; i < num_fd; i++)
141 is_set[i] = 0;
143 for (i = 0; i < num_fd; i++)
144 handles[i] = (HANDLE) _get_osfhandle (fd [i]);
146 /* Start with small delays, and then increase them, to avoid polling too
147 much when waiting a long time */
148 delay = 5;
150 if (timeout < 0)
151 infinite = 1;
153 while (1)
155 for (i = 0; i < num_fd; i++)
157 if (!PeekNamedPipe (handles [i], NULL, 0, NULL, &avail, NULL))
158 return -1;
160 if (avail > 0)
162 is_set[i] = 1;
163 return 1;
167 if (!infinite && timeout <= 0)
168 return 0;
170 Sleep (delay);
171 timeout -= delay;
173 if (delay < MAX_DELAY)
174 delay += 10;
178 #elif defined (VMS)
179 #include <unistd.h>
180 #include <stdio.h>
181 #include <unixio.h>
182 #include <stdlib.h>
183 #include <string.h>
184 #include <vms/descrip.h>
185 #include <stdio.h>
186 #include <vms/stsdef.h>
187 #include <vms/iodef.h>
190 __gnat_waitpid (int pid)
192 int status = 0;
194 waitpid (pid, &status, 0);
195 status = WEXITSTATUS (status);
197 return status;
201 __gnat_pipe (int *fd)
203 return pipe (fd);
207 __gnat_expect_fork (void)
209 return -1;
212 void
213 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
215 *pid = (int) getpid ();
216 /* Since cmd is fully qualified, it is incorrect to call execvp */
217 execv (cmd, argv);
218 _exit (1);
222 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
224 int i, num, ready = 0;
225 unsigned int status;
226 int mbxchans [num_fd];
227 struct dsc$descriptor_s mbxname;
228 struct io_status_block {
229 short int condition;
230 short int count;
231 int dev;
232 } iosb;
233 char buf [256];
235 for (i = 0; i < num_fd; i++)
236 is_set[i] = 0;
238 for (i = 0; i < num_fd; i++)
241 /* Get name of the mailbox used in the pipe */
242 getname (fd [i], buf);
244 /* Assign a channel to the mailbox */
245 if (strlen (buf) > 0)
247 mbxname.dsc$w_length = strlen (buf);
248 mbxname.dsc$b_dtype = DSC$K_DTYPE_T;
249 mbxname.dsc$b_class = DSC$K_CLASS_S;
250 mbxname.dsc$a_pointer = buf;
252 status = SYS$ASSIGN (&mbxname, &mbxchans[i], 0, 0, 0);
254 if ((status & 1) != 1)
256 ready = -1;
257 return ready;
262 num = timeout / 100;
264 while (1)
266 for (i = 0; i < num_fd; i++)
268 if (mbxchans[i] > 0)
271 /* Peek in the mailbox to see if there's data */
272 status = SYS$QIOW
273 (0, mbxchans[i], IO$_SENSEMODE|IO$M_READERCHECK,
274 &iosb, 0, 0, 0, 0, 0, 0, 0, 0);
276 if ((status & 1) != 1)
278 ready = -1;
279 goto deassign;
282 if (iosb.count > 0)
284 is_set[i] = 1;
285 ready = 1;
286 goto deassign;
291 if (timeout > 0 && num == 0)
293 ready = 0;
294 goto deassign;
297 usleep (100000);
298 num--;
301 deassign:
303 /* Deassign channels assigned above */
304 for (i = 0; i < num_fd; i++)
306 if (mbxchans[i] > 0)
307 status = SYS$DASSGN (mbxchans[i]);
310 return ready;
313 #elif defined (__unix__)
315 #ifdef __hpux__
316 #include <sys/ptyio.h>
317 #endif
319 #include <sys/time.h>
321 #ifndef NO_FD_SET
322 #define SELECT_MASK fd_set
323 #else /* !NO_FD_SET */
324 #ifndef _AIX
325 typedef long fd_mask;
326 #endif /* _AIX */
327 #ifdef _IBMR2
328 #define SELECT_MASK void
329 #else /* !_IBMR2 */
330 #define SELECT_MASK int
331 #endif /* !_IBMR2 */
332 #endif /* !NO_FD_SET */
334 void
335 __gnat_kill (int pid, int sig, int close)
337 kill (pid, sig);
341 __gnat_waitpid (int pid)
343 int status = 0;
345 waitpid (pid, &status, 0);
346 status = WEXITSTATUS (status);
348 return status;
352 __gnat_pipe (int *fd)
354 return pipe (fd);
358 __gnat_expect_fork (void)
360 return fork ();
363 void
364 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
366 *pid = (int) getpid ();
367 /* Since cmd is fully qualified, it is incorrect to call execvp */
368 execv (cmd, argv);
369 _exit (1);
373 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
375 struct timeval tv;
376 SELECT_MASK rset;
377 SELECT_MASK eset;
379 int max_fd = 0;
380 int ready;
381 int i;
382 int received;
384 tv.tv_sec = timeout / 1000;
385 tv.tv_usec = (timeout % 1000) * 1000;
387 do {
388 FD_ZERO (&rset);
389 FD_ZERO (&eset);
391 for (i = 0; i < num_fd; i++)
393 FD_SET (fd[i], &rset);
394 FD_SET (fd[i], &eset);
396 if (fd[i] > max_fd)
397 max_fd = fd[i];
400 ready =
401 select (max_fd + 1, &rset, NULL, &eset, timeout == -1 ? NULL : &tv);
403 if (ready > 0)
405 received = 0;
407 for (i = 0; i < num_fd; i++)
409 if (FD_ISSET (fd[i], &rset))
411 is_set[i] = 1;
412 received = 1;
414 else
415 is_set[i] = 0;
418 #ifdef __hpux__
419 for (i = 0; i < num_fd; i++)
421 if (FD_ISSET (fd[i], &eset))
423 struct request_info ei;
425 /* Only query and reset error state if no file descriptor
426 is ready to be read, otherwise we will be signalling a
427 died process too early */
429 if (!received)
431 ioctl (fd[i], TIOCREQCHECK, &ei);
433 if (ei.request == TIOCCLOSE)
435 ioctl (fd[i], TIOCREQSET, &ei);
436 return -1;
439 ioctl (fd[i], TIOCREQSET, &ei);
441 ready--;
444 #endif
446 } while (timeout == -1 && ready == 0);
448 return ready;
451 #else
453 void
454 __gnat_kill (int pid, int sig, int close)
459 __gnat_waitpid (int pid, int sig)
461 return 0;
465 __gnat_pipe (int *fd)
467 return -1;
471 __gnat_expect_fork (void)
473 return -1;
476 void
477 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
479 *pid = 0;
483 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
485 return -1;
487 #endif