OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [ada/] [expect.c] - Blame information for rev 826

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.