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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [system.c] - Blame information for rev 438

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

Line No. Rev Author Line
1 148 jeremybenn
/* Copyright (C) 1991-1999, 2000 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
 
4
   The GNU C Library is free software; you can redistribute it and/or
5
   modify it under the terms of the GNU Lesser General Public
6
   License as published by the Free Software Foundation; either
7
   version 2.1 of the License, or (at your option) any later version.
8
 
9
   The GNU C Library is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
   Lesser General Public License for more details.
13
 
14
   You should have received a copy of the GNU Lesser General Public
15
   License along with the GNU C Library; if not, write to the Free
16
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17
   02111-1307 USA.  */
18
 
19
#include <stddef.h>
20
#include <stdlib.h>
21
#include <unistd.h>
22
#include <sys/wait.h>
23
#include <signal.h>
24
#include <sys/types.h>
25
#include <errno.h>
26
#include <machine/weakalias.h>
27
 
28
 
29
#ifndef HAVE_GNU_LD
30
#define __environ       environ
31
#endif
32
 
33
#define SHELL_PATH      "/bin/sh"       /* Path of the shell.  */
34
#define SHELL_NAME      "sh"            /* Name to give it.  */
35
 
36
/* Execute LINE as a shell command, returning its status.  */
37
int
38
__libc_system (const char *line)
39
{
40
  int status, save;
41
  pid_t pid;
42
  struct sigaction sa, intr, quit;
43
#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD
44
  sigset_t block, omask;
45
#endif
46
 
47
  if (line == NULL)
48
    /* Check that we have a command processor available.  It might
49
       not be available after a chroot(), for example.  */
50
    return __libc_system ("exit 0") == 0;
51
 
52
  sa.sa_handler = SIG_IGN;
53
  sa.sa_flags = 0;
54
  sigemptyset (&sa.sa_mask);
55
 
56
  if (sigaction (SIGINT, &sa, &intr) < 0)
57
    return -1;
58
  if (sigaction (SIGQUIT, &sa, &quit) < 0)
59
    {
60
      save = errno;
61
      (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
62
      errno = save;
63
      return -1;
64
    }
65
 
66
#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD
67
 
68
/* SCO 3.2v4 has a bug where `waitpid' will never return if SIGCHLD is
69
   blocked.  This makes it impossible for `system' to be implemented in
70
   compliance with POSIX.2-1992.  They have acknowledged that this is a bug
71
   but I have not seen nor heard of any forthcoming fix.  */
72
 
73
  sigemptyset (&block);
74
  sigaddset (&block, SIGCHLD);
75
  save = errno;
76
  if (sigprocmask (SIG_BLOCK, &block, &omask) < 0)
77
    {
78
      if (errno == ENOSYS)
79
        errno = save;
80
      else
81
        {
82
          save = errno;
83
          (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
84
          (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
85
          errno = save;
86
          return -1;
87
        }
88
    }
89
# define UNBLOCK sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)
90
#else
91
# define UNBLOCK 0
92
#endif
93
 
94
  pid = fork ();
95
  if (pid == (pid_t) 0)
96
    {
97
      /* Child side.  */
98
      const char *new_argv[4];
99
      new_argv[0] = SHELL_NAME;
100
      new_argv[1] = "-c";
101
      new_argv[2] = line;
102
      new_argv[3] = NULL;
103
 
104
      /* Restore the signals.  */
105
      (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
106
      (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
107
      (void) UNBLOCK;
108
 
109
      /* Exec the shell.  */
110
      (void) execve (SHELL_PATH, (char *const *) new_argv, __environ);
111
      _exit (127);
112
    }
113
  else if (pid < (pid_t) 0)
114
    /* The fork failed.  */
115
    status = -1;
116
  else
117
    /* Parent side.  */
118
    {
119
#ifdef  NO_WAITPID
120
      pid_t child;
121
      do
122
        {
123
          child = wait (&status);
124
          if (child <= -1 && errno != EINTR)
125
            {
126
              status = -1;
127
              break;
128
            }
129
          /* Note that pid cannot be <= -1 and therefore the loop continues
130
             when wait returned with EINTR.  */
131
        }
132
      while (child != pid);
133
#else
134
      int n;
135
 
136
      do
137
        n = waitpid (pid, &status, 0);
138
      while (n == -1 && errno == EINTR);
139
 
140
      if (n != pid)
141
        status = -1;
142
#endif
143
    }
144
 
145
  save = errno;
146
  if ((sigaction (SIGINT, &intr, (struct sigaction *) NULL) |
147
       sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) |
148
       UNBLOCK) != 0)
149
    {
150
      if (errno == ENOSYS)
151
        errno = save;
152
      else
153
        return -1;
154
    }
155
 
156
  return status;
157
}
158
weak_alias (__libc_system, system)

powered by: WebSVN 2.1.0

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