]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/expect.c
trans-array.c (gfc_conv_descriptor_data_get): Rename from gfc_conv_descriptor_data.
[thirdparty/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 * *
6178dd5c 9 * Copyright (C) 2001-2005 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
e602394c
PO
46#include <sys/types.h>
47
48#ifdef __MINGW32__
49#if OLD_MINGW
50#include <sys/wait.h>
51#endif
52#else
53#include <sys/wait.h>
54#endif
55
70482933
RK
56/* This file provides the low level functionalities needed to implement Expect
57 capabilities in GNAT.Expect.
58 Implementations for unix and windows systems is provided.
59 Dummy stubs are also provided for other systems. */
60
61#ifdef _AIX
7cd6e9f1
OH
62/* Work around the fact that gcc/cpp does not define "__unix__" under AiX. */
63#define __unix__
70482933
RK
64#endif
65
d10ad8ff
AC
66#ifdef __APPLE__
67/* Work around the fact that gcc/cpp does not define "__unix__" on Darwin. */
68#define __unix__
69#endif
70
70482933
RK
71#ifdef _WIN32
72
73#include <windows.h>
74#include <process.h>
75
70482933 76void
fbf5a39b 77__gnat_kill (int pid, int sig)
70482933 78{
fbf5a39b
AC
79 HANDLE process_handle;
80
81 if (sig == 9)
82 {
83 process_handle = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
84 if (process_handle != NULL)
e602394c
PO
85 {
86 TerminateProcess (process_handle, 0);
87 CloseHandle (process_handle);
88 }
fbf5a39b 89 }
70482933
RK
90}
91
e602394c
PO
92int
93__gnat_waitpid (int pid)
94{
95 HANDLE process_handle;
96 DWORD exitcode = 1;
97 DWORD res;
98
99 process_handle = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, pid);
100
101 if (process_handle != NULL)
102 {
103 res = WaitForSingleObject (process_handle, INFINITE);
104 GetExitCodeProcess (process_handle, &exitcode);
105 CloseHandle (process_handle);
106 }
107
108 return (int) exitcode;
109}
110
70482933 111int
9373164a 112__gnat_expect_fork (void)
70482933
RK
113{
114 return 0;
115}
116
117void
fbf5a39b 118__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
70482933 119{
07fc65c4 120 *pid = (int) spawnve (_P_NOWAIT, cmd, argv, NULL);
70482933
RK
121}
122
123int
fbf5a39b 124__gnat_pipe (int *fd)
70482933
RK
125{
126 HANDLE read, write;
127
128 CreatePipe (&read, &write, NULL, 0);
fbf5a39b
AC
129 fd[0]=_open_osfhandle ((long)read, 0);
130 fd[1]=_open_osfhandle ((long)write, 0);
70482933
RK
131 return 0; /* always success */
132}
133
134int
fbf5a39b 135__gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
70482933 136{
fbf5a39b
AC
137#define MAX_DELAY 100
138
139 int i, delay, infinite = 0;
70482933
RK
140 DWORD avail;
141 HANDLE handles[num_fd];
142
143 for (i = 0; i < num_fd; i++)
144 is_set[i] = 0;
145
146 for (i = 0; i < num_fd; i++)
fbf5a39b
AC
147 handles[i] = (HANDLE) _get_osfhandle (fd [i]);
148
149 /* Start with small delays, and then increase them, to avoid polling too
150 much when waiting a long time */
151 delay = 5;
70482933 152
fbf5a39b
AC
153 if (timeout < 0)
154 infinite = 1;
70482933
RK
155
156 while (1)
157 {
158 for (i = 0; i < num_fd; i++)
fbf5a39b
AC
159 {
160 if (!PeekNamedPipe (handles [i], NULL, 0, NULL, &avail, NULL))
161 return -1;
70482933 162
fbf5a39b
AC
163 if (avail > 0)
164 {
165 is_set[i] = 1;
166 return 1;
167 }
168 }
70482933 169
fbf5a39b
AC
170 if (!infinite && timeout <= 0)
171 return 0;
70482933 172
fbf5a39b
AC
173 Sleep (delay);
174 timeout -= delay;
175
176 if (delay < MAX_DELAY)
177 delay += 10;
70482933
RK
178 }
179}
180
07fc65c4
GB
181#elif defined (VMS)
182#include <unistd.h>
183#include <stdio.h>
184#include <unixio.h>
185#include <stdlib.h>
186#include <string.h>
6178dd5c 187#include <vms/descrip.h>
07fc65c4 188#include <stdio.h>
6178dd5c
DR
189#include <vms/stsdef.h>
190#include <vms/iodef.h>
07fc65c4 191
e602394c
PO
192int
193__gnat_waitpid (int pid)
194{
195 int status = 0;
196
197 waitpid (pid, &status, 0);
198 status = WEXITSTATUS (status);
199
200 return status;
201}
202
07fc65c4 203int
fbf5a39b 204__gnat_pipe (int *fd)
07fc65c4
GB
205{
206 return pipe (fd);
207}
208
209int
9373164a 210__gnat_expect_fork (void)
07fc65c4
GB
211{
212 return -1;
213}
214
215void
fbf5a39b 216__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
07fc65c4 217{
fbf5a39b
AC
218 *pid = (int) getpid ();
219 /* Since cmd is fully qualified, it is incorrect to call execvp */
07fc65c4 220 execv (cmd, argv);
fbf5a39b 221 _exit (1);
07fc65c4
GB
222}
223
224int
fbf5a39b 225__gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
07fc65c4
GB
226{
227 int i, num, ready = 0;
228 unsigned int status;
229 int mbxchans [num_fd];
230 struct dsc$descriptor_s mbxname;
231 struct io_status_block {
232 short int condition;
233 short int count;
234 int dev;
235 } iosb;
236 char buf [256];
237
238 for (i = 0; i < num_fd; i++)
239 is_set[i] = 0;
240
241 for (i = 0; i < num_fd; i++)
242 {
243
244 /* Get name of the mailbox used in the pipe */
245 getname (fd [i], buf);
246
247 /* Assign a channel to the mailbox */
248 if (strlen (buf) > 0)
249 {
250 mbxname.dsc$w_length = strlen (buf);
251 mbxname.dsc$b_dtype = DSC$K_DTYPE_T;
252 mbxname.dsc$b_class = DSC$K_CLASS_S;
253 mbxname.dsc$a_pointer = buf;
254
255 status = SYS$ASSIGN (&mbxname, &mbxchans[i], 0, 0, 0);
fbf5a39b
AC
256
257 if ((status & 1) != 1)
258 {
259 ready = -1;
260 return ready;
261 }
07fc65c4
GB
262 }
263 }
264
265 num = timeout / 100;
266
267 while (1)
268 {
269 for (i = 0; i < num_fd; i++)
270 {
271 if (mbxchans[i] > 0)
272 {
273
274 /* Peek in the mailbox to see if there's data */
275 status = SYS$QIOW
276 (0, mbxchans[i], IO$_SENSEMODE|IO$M_READERCHECK,
277 &iosb, 0, 0, 0, 0, 0, 0, 0, 0);
278
fbf5a39b
AC
279 if ((status & 1) != 1)
280 {
281 ready = -1;
282 goto deassign;
283 }
284
07fc65c4
GB
285 if (iosb.count > 0)
286 {
287 is_set[i] = 1;
288 ready = 1;
289 goto deassign;
290 }
291 }
292 }
293
fbf5a39b 294 if (timeout > 0 && num == 0)
07fc65c4
GB
295 {
296 ready = 0;
297 goto deassign;
298 }
299
300 usleep (100000);
301 num--;
302 }
303
304 deassign:
305
306 /* Deassign channels assigned above */
307 for (i = 0; i < num_fd; i++)
308 {
309 if (mbxchans[i] > 0)
310 status = SYS$DASSGN (mbxchans[i]);
311 }
312
313 return ready;
314}
315
7cd6e9f1 316#elif defined (__unix__)
70482933 317
7cd6e9f1 318#ifdef __hpux__
fbf5a39b
AC
319#include <sys/ptyio.h>
320#endif
321
70482933
RK
322#include <sys/time.h>
323
324#ifndef NO_FD_SET
325#define SELECT_MASK fd_set
326#else /* !NO_FD_SET */
327#ifndef _AIX
328typedef long fd_mask;
329#endif /* _AIX */
330#ifdef _IBMR2
331#define SELECT_MASK void
332#else /* !_IBMR2 */
333#define SELECT_MASK int
334#endif /* !_IBMR2 */
335#endif /* !NO_FD_SET */
336
fbf5a39b
AC
337void
338__gnat_kill (int pid, int sig)
339{
340 kill (pid, sig);
341}
342
e602394c
PO
343int
344__gnat_waitpid (int pid)
345{
346 int status = 0;
347
348 waitpid (pid, &status, 0);
349 status = WEXITSTATUS (status);
350
351 return status;
352}
353
70482933 354int
fbf5a39b 355__gnat_pipe (int *fd)
70482933
RK
356{
357 return pipe (fd);
358}
359
360int
9373164a 361__gnat_expect_fork (void)
70482933
RK
362{
363 return fork ();
364}
365
366void
fbf5a39b 367__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
70482933 368{
fbf5a39b
AC
369 *pid = (int) getpid ();
370 /* Since cmd is fully qualified, it is incorrect to call execvp */
371 execv (cmd, argv);
372 _exit (1);
70482933
RK
373}
374
375int
fbf5a39b 376__gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
70482933
RK
377{
378 struct timeval tv;
379 SELECT_MASK rset;
fbf5a39b
AC
380 SELECT_MASK eset;
381
70482933
RK
382 int max_fd = 0;
383 int ready;
384 int i;
fbf5a39b 385 int received;
70482933
RK
386
387 tv.tv_sec = timeout / 1000;
388 tv.tv_usec = (timeout % 1000) * 1000;
389
fbf5a39b
AC
390 do {
391 FD_ZERO (&rset);
392 FD_ZERO (&eset);
70482933 393
70482933 394 for (i = 0; i < num_fd; i++)
fbf5a39b
AC
395 {
396 FD_SET (fd[i], &rset);
397 FD_SET (fd[i], &eset);
398
399 if (fd[i] > max_fd)
400 max_fd = fd[i];
401 }
402
403 ready =
404 select (max_fd + 1, &rset, NULL, &eset, timeout == -1 ? NULL : &tv);
405
406 if (ready > 0)
407 {
408 received = 0;
409
410 for (i = 0; i < num_fd; i++)
411 {
412 if (FD_ISSET (fd[i], &rset))
413 {
414 is_set[i] = 1;
415 received = 1;
416 }
417 else
418 is_set[i] = 0;
419 }
420
7cd6e9f1 421#ifdef __hpux__
fbf5a39b
AC
422 for (i = 0; i < num_fd; i++)
423 {
424 if (FD_ISSET (fd[i], &eset))
425 {
426 struct request_info ei;
427
428 /* Only query and reset error state if no file descriptor
429 is ready to be read, otherwise we will be signalling a
430 died process too early */
431
432 if (!received)
433 {
434 ioctl (fd[i], TIOCREQCHECK, &ei);
435
436 if (ei.request == TIOCCLOSE)
437 {
438 ioctl (fd[i], TIOCREQSET, &ei);
439 return -1;
440 }
441
442 ioctl (fd[i], TIOCREQSET, &ei);
443 }
444 ready--;
445 }
446 }
447#endif
448 }
449 } while (timeout == -1 && ready == 0);
70482933
RK
450
451 return ready;
452}
453
454#else
455
fbf5a39b
AC
456void
457__gnat_kill (int pid, int sig)
458{
459}
460
e602394c
PO
461int
462__gnat_waitpid (int pid, int sig)
463{
464 return 0;
465}
466
70482933 467int
fbf5a39b 468__gnat_pipe (int *fd)
70482933
RK
469{
470 return -1;
471}
472
473int
9373164a 474__gnat_expect_fork (void)
70482933
RK
475{
476 return -1;
477}
478
479void
fbf5a39b 480__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
70482933 481{
07fc65c4 482 *pid = 0;
70482933
RK
483}
484
485int
fbf5a39b 486__gnat_expect_poll (int *fd, int num_fd, int timeout, int *is_set)
70482933
RK
487{
488 return -1;
489}
490#endif