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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib-1.10.0/] [newlib/] [libc/] [stdlib/] [system.c] - Blame information for rev 1773

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

Line No. Rev Author Line
1 1010 ivang
/*
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 <errno.h>
57
#include <stddef.h>
58
#include <stdlib.h>
59
#include <unistd.h>
60
#include <_syslist.h>
61
#include <reent.h>
62
 
63
#if defined (unix) || defined (__CYGWIN__)
64
static int do_system ();
65
#endif
66
 
67
int
68
_system_r (ptr, s)
69
     struct _reent *ptr;
70
     _CONST char *s;
71
{
72
#ifdef NO_EXEC
73
  if (s == NULL)
74
    return 0;
75
  errno = ENOSYS;
76
  return -1;
77
#else
78
 
79
  /* ??? How to handle (s == NULL) here is not exactly clear.
80
     If _fork_r fails, that's not really a justification for returning 0.
81
     For now we always return 0 and leave it to each target to explicitly
82
     handle otherwise (this can always be relaxed in the future).  */
83
 
84
#if defined (unix) || defined (__CYGWIN__)
85
  if (s == NULL)
86
    return 1;
87
  return do_system (ptr, s);
88
#else
89
  if (s == NULL)
90
    return 0;
91
  errno = ENOSYS;
92
  return -1;
93
#endif
94
 
95
#endif
96
}
97
 
98
#ifndef _REENT_ONLY
99
 
100
int
101
system (s)
102
     _CONST char *s;
103
{
104
  return _system_r (_REENT, s);
105
}
106
 
107
#endif
108
 
109
#if defined (unix) && !defined (__CYGWIN__) && !defined(__rtems__)
110
extern char **environ;
111
 
112
/* Only deal with a pointer to environ, to work around subtle bugs with shared
113
   libraries and/or small data systems where the user declares his own
114
   'environ'.  */
115
static char ***p_environ = &environ;
116
 
117
static int
118
do_system (ptr, s)
119
     struct _reent *ptr;
120
     _CONST char *s;
121
{
122
  char *argv[4];
123
  int pid, status;
124
 
125
  argv[0] = "sh";
126
  argv[1] = "-c";
127
  argv[2] = (char *) s;
128
  argv[3] = NULL;
129
 
130
  if ((pid = _fork_r (ptr)) == 0)
131
    {
132
      _execve ("/bin/sh", argv, *p_environ);
133
      exit (100);
134
    }
135
  else if (pid == -1)
136
    return -1;
137
  else
138
    {
139
      int rc = _wait_r (ptr, &status);
140
      if (rc == -1)
141
        return -1;
142
      status = (status >> 8) & 0xff;
143
      return status;
144
    }
145
}
146
#endif
147
 
148
#if defined (__CYGWIN__)
149
static int
150
do_system (ptr, s)
151
     struct _reent *ptr;
152
     _CONST char *s;
153
{
154
  char *argv[4];
155
  int pid, status;
156
 
157
  argv[0] = "sh";
158
  argv[1] = "-c";
159
  argv[2] = (char *) s;
160
  argv[3] = NULL;
161
 
162
  if ((pid = vfork ()) == 0)
163
    {
164
      /* ??? It's not clear what's the right path to take (pun intended :-).
165
         There won't be an "sh" in any fixed location so we need each user
166
         to be able to say where to find "sh".  That suggests using an
167
         environment variable, but after a few more such situations we may
168
         have too many of them.  */
169
      char *sh = getenv ("SH_PATH");
170
      if (sh == NULL)
171
        sh = "/bin/sh";
172
      _execve (sh, argv, environ);
173
      exit (100);
174
    }
175
  else if (pid == -1)
176
    return -1;
177
  else
178
    {
179
      int rc = _wait (&status);
180
      if (rc == -1)
181
        return -1;
182
      status = (status >> 8) & 0xff;
183
      return status;
184
    }
185
}
186
#endif

powered by: WebSVN 2.1.0

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