diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2002-05-17 23:39:39 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2002-05-17 23:39:39 +0000 |
commit | 5e2cbfb6e89534396cfb250cdc29bad574220094 (patch) | |
tree | f20e46f0039627f02f664f897a0822af0e35cdf6 /newlib/libc/sys/linux/system.c | |
parent | 7fc85bd1b9502b5fe30102e85f4743dbf45b9f01 (diff) | |
download | cygnal-5e2cbfb6e89534396cfb250cdc29bad574220094.tar.gz cygnal-5e2cbfb6e89534396cfb250cdc29bad574220094.tar.bz2 cygnal-5e2cbfb6e89534396cfb250cdc29bad574220094.zip |
2002-05-17 Jeff Johnston <jjohnstn@redhat.com>
* Makefile.am: Copy and install headers from sys/machine/include
directory. Also pass $toollibdir to lower-level directories.
* Makefile.in: Regenerated.
* libc/include/stdio.h[!_REENT_ONLY]: Change stdin, stdout, and
stderr to use _REENT macro instead of _impure_ptr directly.
* libc/include/sys/config.h[__i386__][__linux__]: Define
__DYNAMIC_REENT__.
* libc/include/sys/reent.h[!_REENT_ONLY]: Change _REENT macro to be
call to __getreent() function if !__SINGLE_THREAD__ and
__DYNAMIC_REENT__ is set.
* libc/reent/Makefile.am: Add support for getreent.c.
* libc/reent/Makefile.in: Regenerated.
* libc/string/strerror.c: Add check if EOPNOTSUPP and ENOTSUP are same.
* libc/sys/linux/Makefile.am: Add support for new files.
* libc/sys/linux/configure.in: Add $EXTRA_DIRS variable.
* libc/sys/linux/Makefile.in: Regenerated.
* libc/sys/linux/configure: Ditto.
* libc/sys/linux/io.c: Add poll syscall. Also weak-alias
__close, __read, __write, __poll, __open, __lseek, __fcntl from
their __libc_ counterparts.
* libc/sys/linux/io64.c: Add __libc_ prefix to lseek64 and open64
and weak-alias to regular names.
* libc/sys/linux/pread64.c: Rename to __libc_pread64 and weak-alias
to pread64 and __pread64.
* libc/sys/linux/process.c: Weak_alias __libc_getpid to __getpid.
* libc/sys/linux/pwrite64.c: Rename to __libc_pwrite64 and
weak-alias to pwrite64.
* libc/sys/linux/sched.c: Weak-alias __libc_sched_getparam,
__libc_sched_getscheduler, __libc_sched_get_priority_max,
__libc_sched_get_priority_min, and __libc_sched_setschedule to
name with __ instead of __libc_.
* libc/sys/linux/siglongjmp.c: Include <machine/weakalias.h>.
Rename siglongjmp to __libc_siglongjmp and weak-alias to siglongjmp.
Call __libc_longjmp instead of longjmp, from __libc_siglongjmp.
* libc/sys/linux/signal.c: Rename raise to __libc_raise and weak-alias
to raise.
* libc/sys/linux/socket.c: Weak-alias __libc_connect to __connect and
__libc_send to __send.
* libc/sys/linux/time.c: Weak-alias __libc_gettimeofday to
__gettimeofday.
* libc/sys/linux/wait.c: Rename wait to __libc_wait and weak-alias
it to wait. Rename wait3 to __libc_wait3 and weak-alias it to wait3.
* libc/sys/linux/include/setjmp.h: Use __jmp_buf in sigjmp_buf
type and typedef __jmp_buf to jmp_buf.
* libc/sys/linux/machine/i386/Makefile.am: Add syscalls.c and
setjmp.S.
* libc/sys/linux/machine/i386/Makefile.in: Regenerated.
* libc/sys/linux/machine/i386/crt0.c: Add support to clear .bss
section.
* libc/sys/linux/machine/i386/socketcall.h: Change to use __libc_
prefix for function macros and then use weak_alias() to regular names.
* libc/sys/linux/machine/i386/syscall.h: Ditto.
* libc/sys/linux/sys/errno.h: Define EOPNOTSUP to be ENOTSUP.
* libc/sys/linux/sys/stdio.h: Define _flockfile and _funlockfile
to be flockfile() and funlockfile() respectively.
* libc/sys/linux/sys/types.h
* libc/reent/getreent.c: New file.
* libc/sys/linux/flockfile.c: Ditto.
* libc/sys/linux/funlockfile.c: Ditto.
* libc/sys/linux/getreent.c: Ditto.
* libc/sys/linux/pread.c: Ditto.
* libc/sys/linux/pwrite.c: Ditto.
* libc/sys/linux/raise.c: Ditto.
* libc/sys/linux/system.c: Ditto.
* libc/sys/linux/tcdrain.c: Ditto.
* libc/sys/linux/machine/i386/i386mach.h: Ditto.
* libc/sys/linux/machine/i386/setjmp.S: Ditto.
* libc/sys/linux/machine/i386/syscalls.c: Ditto.
* libc/sys/linux/machine/i386/weakalias.h: Ditto.
* libc/sys/linux/machine/i386/include/setjmp.h: Ditto.
Diffstat (limited to 'newlib/libc/sys/linux/system.c')
-rw-r--r-- | newlib/libc/sys/linux/system.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/newlib/libc/sys/linux/system.c b/newlib/libc/sys/linux/system.c new file mode 100644 index 000000000..f8edfbf63 --- /dev/null +++ b/newlib/libc/sys/linux/system.c @@ -0,0 +1,158 @@ +/* Copyright (C) 1991-1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/wait.h> +#include <signal.h> +#include <sys/types.h> +#include <errno.h> +#include <machine/weakalias.h> + + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +#define SHELL_PATH "/bin/sh" /* Path of the shell. */ +#define SHELL_NAME "sh" /* Name to give it. */ + +/* Execute LINE as a shell command, returning its status. */ +int +__libc_system (const char *line) +{ + int status, save; + pid_t pid; + struct sigaction sa, intr, quit; +#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD + sigset_t block, omask; +#endif + + if (line == NULL) + /* Check that we have a command processor available. It might + not be available after a chroot(), for example. */ + return __libc_system ("exit 0") == 0; + + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigemptyset (&sa.sa_mask); + + if (sigaction (SIGINT, &sa, &intr) < 0) + return -1; + if (sigaction (SIGQUIT, &sa, &quit) < 0) + { + save = errno; + (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL); + errno = save; + return -1; + } + +#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD + +/* SCO 3.2v4 has a bug where `waitpid' will never return if SIGCHLD is + blocked. This makes it impossible for `system' to be implemented in + compliance with POSIX.2-1992. They have acknowledged that this is a bug + but I have not seen nor heard of any forthcoming fix. */ + + sigemptyset (&block); + sigaddset (&block, SIGCHLD); + save = errno; + if (sigprocmask (SIG_BLOCK, &block, &omask) < 0) + { + if (errno == ENOSYS) + errno = save; + else + { + save = errno; + (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL); + (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + errno = save; + return -1; + } + } +# define UNBLOCK sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) +#else +# define UNBLOCK 0 +#endif + + pid = fork (); + if (pid == (pid_t) 0) + { + /* Child side. */ + const char *new_argv[4]; + new_argv[0] = SHELL_NAME; + new_argv[1] = "-c"; + new_argv[2] = line; + new_argv[3] = NULL; + + /* Restore the signals. */ + (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL); + (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + (void) UNBLOCK; + + /* Exec the shell. */ + (void) execve (SHELL_PATH, (char *const *) new_argv, __environ); + _exit (127); + } + else if (pid < (pid_t) 0) + /* The fork failed. */ + status = -1; + else + /* Parent side. */ + { +#ifdef NO_WAITPID + pid_t child; + do + { + child = wait (&status); + if (child <= -1 && errno != EINTR) + { + status = -1; + break; + } + /* Note that pid cannot be <= -1 and therefore the loop continues + when wait returned with EINTR. */ + } + while (child != pid); +#else + int n; + + do + n = waitpid (pid, &status, 0); + while (n == -1 && errno == EINTR); + + if (n != pid) + status = -1; +#endif + } + + save = errno; + if ((sigaction (SIGINT, &intr, (struct sigaction *) NULL) | + sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) | + UNBLOCK) != 0) + { + if (errno == ENOSYS) + errno = save; + else + return -1; + } + + return status; +} +weak_alias (__libc_system, system) |