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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [expect.c] - Blame information for rev 744

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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