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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [stdlib/] [system.c] - Blame information for rev 816

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/*
2
FUNCTION
3
<<system>>---execute command string
4
 
5
INDEX
6
        system
7
INDEX
8
        _system_r
9
 
10
ANSI_SYNOPSIS
11
        #include <stdlib.h>
12
        int system(char *<[s]>);
13
 
14
        int _system_r(void *<[reent]>, char *<[s]>);
15
 
16
TRAD_SYNOPSIS
17
        #include <stdlib.h>
18
        int system(<[s]>)
19
        char *<[s]>;
20
 
21
        int _system_r(<[reent]>, <[s]>)
22
        char *<[reent]>;
23
        char *<[s]>;
24
 
25
DESCRIPTION
26
 
27
Use <<system>> to pass a command string <<*<[s]>>> to <</bin/sh>> on
28
your system, and wait for it to finish executing.
29
 
30
Use ``<<system(NULL)>>'' to test whether your system has <</bin/sh>>
31
available.
32
 
33
The alternate function <<_system_r>> is a reentrant version.  The
34
extra argument <[reent]> is a pointer to a reentrancy structure.
35
 
36
RETURNS
37
<<system(NULL)>> returns a non-zero value if <</bin/sh>> is available, and
38
<<0>> if it is not.
39
 
40
With a command argument, the result of <<system>> is the exit status
41
returned by <</bin/sh>>.
42
 
43
PORTABILITY
44
ANSI C requires <<system>>, but leaves the nature and effects of a
45
command processor undefined.  ANSI C does, however, specify that
46
<<system(NULL)>> return zero or nonzero to report on the existence of
47
a command processor.
48
 
49
POSIX.2 requires <<system>>, and requires that it invoke a <<sh>>.
50
Where <<sh>> is found is left unspecified.
51
 
52
Supporting OS subroutines required: <<_exit>>, <<_execve>>, <<_fork_r>>,
53
<<_wait_r>>.
54
*/
55
 
56
#include <_ansi.h>
57
#include <errno.h>
58
#include <stddef.h>
59
#include <stdlib.h>
60
#include <unistd.h>
61
#include <_syslist.h>
62
#include <reent.h>
63
 
64
#if defined (unix) || defined (__CYGWIN__)
65
static int _EXFUN(do_system, (struct _reent *ptr _AND _CONST char *s));
66
#endif
67
 
68
int
69
_DEFUN(_system_r, (ptr, s),
70
     struct _reent *ptr _AND
71
     _CONST char *s)
72
{
73
#if defined(HAVE_SYSTEM)
74
  return _system (s);
75
  ptr = ptr;
76
#elif defined(NO_EXEC)
77
  if (s == NULL)
78
    return 0;
79
  errno = ENOSYS;
80
  return -1;
81
#else
82
 
83
  /* ??? How to handle (s == NULL) here is not exactly clear.
84
     If _fork_r fails, that's not really a justification for returning 0.
85
     For now we always return 0 and leave it to each target to explicitly
86
     handle otherwise (this can always be relaxed in the future).  */
87
 
88
#if defined (unix) || defined (__CYGWIN__)
89
  if (s == NULL)
90
    return 1;
91
  return do_system (ptr, s);
92
#else
93
  if (s == NULL)
94
    return 0;
95
  errno = ENOSYS;
96
  return -1;
97
#endif
98
 
99
#endif
100
}
101
 
102
#ifndef _REENT_ONLY
103
 
104
int
105
_DEFUN(system, (s),
106
     _CONST char *s)
107
{
108
  return _system_r (_REENT, s);
109
}
110
 
111
#endif
112
 
113
#if defined (unix) && !defined (__CYGWIN__) && !defined(__rtems__)
114
extern char **environ;
115
 
116
/* Only deal with a pointer to environ, to work around subtle bugs with shared
117
   libraries and/or small data systems where the user declares his own
118
   'environ'.  */
119
static char ***p_environ = &environ;
120
 
121
static int
122
_DEFUN(do_system, (ptr, s),
123
     struct _reent *ptr _AND
124
     _CONST char *s)
125
{
126
  char *argv[4];
127
  int pid, status;
128
 
129
  argv[0] = "sh";
130
  argv[1] = "-c";
131
  argv[2] = (char *) s;
132
  argv[3] = NULL;
133
 
134
  if ((pid = _fork_r (ptr)) == 0)
135
    {
136
      _execve ("/bin/sh", argv, *p_environ);
137
      exit (100);
138
    }
139
  else if (pid == -1)
140
    return -1;
141
  else
142
    {
143
      int rc = _wait_r (ptr, &status);
144
      if (rc == -1)
145
        return -1;
146
      status = (status >> 8) & 0xff;
147
      return status;
148
    }
149
}
150
#endif
151
 
152
#if defined (__CYGWIN__)
153
static int
154
_DEFUN(do_system, (ptr, s),
155
     struct _reent *ptr _AND
156
     _CONST char *s)
157
{
158
  char *argv[4];
159
  int pid, status;
160
 
161
  argv[0] = "sh";
162
  argv[1] = "-c";
163
  argv[2] = (char *) s;
164
  argv[3] = NULL;
165
 
166
  if ((pid = vfork ()) == 0)
167
    {
168
      /* ??? It's not clear what's the right path to take (pun intended :-).
169
         There won't be an "sh" in any fixed location so we need each user
170
         to be able to say where to find "sh".  That suggests using an
171
         environment variable, but after a few more such situations we may
172
         have too many of them.  */
173
      char *sh = getenv ("SH_PATH");
174
      if (sh == NULL)
175
        sh = "/bin/sh";
176
      _execve (sh, argv, environ);
177
      exit (100);
178
    }
179
  else if (pid == -1)
180
    return -1;
181
  else
182
    {
183
      extern int _wait (int *);
184
      int rc = _wait (&status);
185
      if (rc == -1)
186
        return -1;
187
      status = (status >> 8) & 0xff;
188
      return status;
189
    }
190
}
191
#endif

powered by: WebSVN 2.1.0

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