* gimplify.c (find_single_pointer_decl_1): New static function.
[official-gcc.git] / gcc / ada / expect.c
blob69a3364b6d31c0ea61dde0a621a9e025ecd9761e
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 Ada Core Technologies, Inc. *
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)
81 HANDLE process_handle;
83 if (sig == 9)
85 process_handle = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
86 if (process_handle != NULL)
88 TerminateProcess (process_handle, 0);
89 CloseHandle (process_handle);
94 int
95 __gnat_waitpid (int pid)
97 HANDLE process_handle;
98 DWORD exitcode = 1;
99 DWORD res;
101 process_handle = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, pid);
103 if (process_handle != NULL)
105 res = WaitForSingleObject (process_handle, INFINITE);
106 GetExitCodeProcess (process_handle, &exitcode);
107 CloseHandle (process_handle);
110 return (int) exitcode;
114 __gnat_expect_fork (void)
116 return 0;
119 void
120 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
122 *pid = (int) spawnve (_P_NOWAIT, cmd, argv, NULL);
126 __gnat_pipe (int *fd)
128 HANDLE read, write;
130 CreatePipe (&read, &write, NULL, 0);
131 fd[0]=_open_osfhandle ((long)read, 0);
132 fd[1]=_open_osfhandle ((long)write, 0);
133 return 0; /* always success */
137 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
139 #define MAX_DELAY 100
141 int i, delay, infinite = 0;
142 DWORD avail;
143 HANDLE handles[num_fd];
145 for (i = 0; i < num_fd; i++)
146 is_set[i] = 0;
148 for (i = 0; i < num_fd; i++)
149 handles[i] = (HANDLE) _get_osfhandle (fd [i]);
151 /* Start with small delays, and then increase them, to avoid polling too
152 much when waiting a long time */
153 delay = 5;
155 if (timeout < 0)
156 infinite = 1;
158 while (1)
160 for (i = 0; i < num_fd; i++)
162 if (!PeekNamedPipe (handles [i], NULL, 0, NULL, &avail, NULL))
163 return -1;
165 if (avail > 0)
167 is_set[i] = 1;
168 return 1;
172 if (!infinite && timeout <= 0)
173 return 0;
175 Sleep (delay);
176 timeout -= delay;
178 if (delay < MAX_DELAY)
179 delay += 10;
183 #elif defined (VMS)
184 #include <unistd.h>
185 #include <stdio.h>
186 #include <unixio.h>
187 #include <stdlib.h>
188 #include <string.h>
189 #include <vms/descrip.h>
190 #include <stdio.h>
191 #include <vms/stsdef.h>
192 #include <vms/iodef.h>
195 __gnat_waitpid (int pid)
197 int status = 0;
199 waitpid (pid, &status, 0);
200 status = WEXITSTATUS (status);
202 return status;
206 __gnat_pipe (int *fd)
208 return pipe (fd);
212 __gnat_expect_fork (void)
214 return -1;
217 void
218 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
220 *pid = (int) getpid ();
221 /* Since cmd is fully qualified, it is incorrect to call execvp */
222 execv (cmd, argv);
223 _exit (1);
227 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
229 int i, num, ready = 0;
230 unsigned int status;
231 int mbxchans [num_fd];
232 struct dsc$descriptor_s mbxname;
233 struct io_status_block {
234 short int condition;
235 short int count;
236 int dev;
237 } iosb;
238 char buf [256];
240 for (i = 0; i < num_fd; i++)
241 is_set[i] = 0;
243 for (i = 0; i < num_fd; i++)
246 /* Get name of the mailbox used in the pipe */
247 getname (fd [i], buf);
249 /* Assign a channel to the mailbox */
250 if (strlen (buf) > 0)
252 mbxname.dsc$w_length = strlen (buf);
253 mbxname.dsc$b_dtype = DSC$K_DTYPE_T;
254 mbxname.dsc$b_class = DSC$K_CLASS_S;
255 mbxname.dsc$a_pointer = buf;
257 status = SYS$ASSIGN (&mbxname, &mbxchans[i], 0, 0, 0);
259 if ((status & 1) != 1)
261 ready = -1;
262 return ready;
267 num = timeout / 100;
269 while (1)
271 for (i = 0; i < num_fd; i++)
273 if (mbxchans[i] > 0)
276 /* Peek in the mailbox to see if there's data */
277 status = SYS$QIOW
278 (0, mbxchans[i], IO$_SENSEMODE|IO$M_READERCHECK,
279 &iosb, 0, 0, 0, 0, 0, 0, 0, 0);
281 if ((status & 1) != 1)
283 ready = -1;
284 goto deassign;
287 if (iosb.count > 0)
289 is_set[i] = 1;
290 ready = 1;
291 goto deassign;
296 if (timeout > 0 && num == 0)
298 ready = 0;
299 goto deassign;
302 usleep (100000);
303 num--;
306 deassign:
308 /* Deassign channels assigned above */
309 for (i = 0; i < num_fd; i++)
311 if (mbxchans[i] > 0)
312 status = SYS$DASSGN (mbxchans[i]);
315 return ready;
318 #elif defined (__unix__)
320 #ifdef __hpux__
321 #include <sys/ptyio.h>
322 #endif
324 #include <sys/time.h>
326 #ifndef NO_FD_SET
327 #define SELECT_MASK fd_set
328 #else /* !NO_FD_SET */
329 #ifndef _AIX
330 typedef long fd_mask;
331 #endif /* _AIX */
332 #ifdef _IBMR2
333 #define SELECT_MASK void
334 #else /* !_IBMR2 */
335 #define SELECT_MASK int
336 #endif /* !_IBMR2 */
337 #endif /* !NO_FD_SET */
339 void
340 __gnat_kill (int pid, int sig)
342 kill (pid, sig);
346 __gnat_waitpid (int pid)
348 int status = 0;
350 waitpid (pid, &status, 0);
351 status = WEXITSTATUS (status);
353 return status;
357 __gnat_pipe (int *fd)
359 return pipe (fd);
363 __gnat_expect_fork (void)
365 return fork ();
368 void
369 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
371 *pid = (int) getpid ();
372 /* Since cmd is fully qualified, it is incorrect to call execvp */
373 execv (cmd, argv);
374 _exit (1);
378 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
380 struct timeval tv;
381 SELECT_MASK rset;
382 SELECT_MASK eset;
384 int max_fd = 0;
385 int ready;
386 int i;
387 int received;
389 tv.tv_sec = timeout / 1000;
390 tv.tv_usec = (timeout % 1000) * 1000;
392 do {
393 FD_ZERO (&rset);
394 FD_ZERO (&eset);
396 for (i = 0; i < num_fd; i++)
398 FD_SET (fd[i], &rset);
399 FD_SET (fd[i], &eset);
401 if (fd[i] > max_fd)
402 max_fd = fd[i];
405 ready =
406 select (max_fd + 1, &rset, NULL, &eset, timeout == -1 ? NULL : &tv);
408 if (ready > 0)
410 received = 0;
412 for (i = 0; i < num_fd; i++)
414 if (FD_ISSET (fd[i], &rset))
416 is_set[i] = 1;
417 received = 1;
419 else
420 is_set[i] = 0;
423 #ifdef __hpux__
424 for (i = 0; i < num_fd; i++)
426 if (FD_ISSET (fd[i], &eset))
428 struct request_info ei;
430 /* Only query and reset error state if no file descriptor
431 is ready to be read, otherwise we will be signalling a
432 died process too early */
434 if (!received)
436 ioctl (fd[i], TIOCREQCHECK, &ei);
438 if (ei.request == TIOCCLOSE)
440 ioctl (fd[i], TIOCREQSET, &ei);
441 return -1;
444 ioctl (fd[i], TIOCREQSET, &ei);
446 ready--;
449 #endif
451 } while (timeout == -1 && ready == 0);
453 return ready;
456 #else
458 void
459 __gnat_kill (int pid, int sig)
464 __gnat_waitpid (int pid, int sig)
466 return 0;
470 __gnat_pipe (int *fd)
472 return -1;
476 __gnat_expect_fork (void)
478 return -1;
481 void
482 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
484 *pid = 0;
488 __gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
490 return -1;
492 #endif