mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	* config.h.in: Remove HAVE_GNU_LD. * csu/Makefile: Remove use of gnu-ld. * csu/munch.awk: Removed. * csu/munch-tmpl.c: Removed. * include/libc-symbols.h: Remove use of HAVE_GNU_LD. * posix/execl.c: Likewise. * posix/execv.c: Likewise. * stdio-common/psignal.c: Likewise. * stdlib/exit.c: Likewise. * string/strsignal.c: Likewise. * string/tester.c: Likewise. * sysdeps/generic/errlist.c: Likewise. * sysdeps/generic/getenv.c: Likewise. * sysdeps/generic/getgroups.c: Likewise. * sysdeps/generic/init-posix.c: Likewise. * sysdeps/posix/gettimeofday.c: Likewise. * sysdeps/posix/system.c: Likewise. * sysdeps/unix/bsd/init-posix.c: Likewise. * sysdeps/unix/bsd/ulimit.c: Likewise. * sysdeps/unix/bsd/sun/m68k/brk.S: Likewise. * sysdeps/unix/bsd/sun/m68k/sethostid.S: Likewise. * sysdeps/unix/bsd/sun/sparc/sethostid.S: Likewise. * sysdeps/unix/i386/brk.S: Likewise. * sysdeps/unix/sparc/brk.S: Likewise.
		
			
				
	
	
		
			213 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Copyright (C) 1991-2000, 2002, 2003, 2005 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 <errno.h>
 | 
						|
#include <signal.h>
 | 
						|
#include <stddef.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/wait.h>
 | 
						|
#include <bits/libc-lock.h>
 | 
						|
#include <sysdep-cancel.h>
 | 
						|
 | 
						|
 | 
						|
#define	SHELL_PATH	"/bin/sh"	/* Path of the shell.  */
 | 
						|
#define	SHELL_NAME	"sh"		/* Name to give it.  */
 | 
						|
 | 
						|
 | 
						|
#ifdef _LIBC_REENTRANT
 | 
						|
static struct sigaction intr, quit;
 | 
						|
static int sa_refcntr;
 | 
						|
__libc_lock_define_initialized (static, lock);
 | 
						|
 | 
						|
# define DO_LOCK() __libc_lock_lock (lock)
 | 
						|
# define DO_UNLOCK() __libc_lock_unlock (lock)
 | 
						|
# define INIT_LOCK() ({ __libc_lock_init (lock); sa_refcntr = 0; })
 | 
						|
# define ADD_REF() sa_refcntr++
 | 
						|
# define SUB_REF() --sa_refcntr
 | 
						|
#else
 | 
						|
# define DO_LOCK()
 | 
						|
# define DO_UNLOCK()
 | 
						|
# define INIT_LOCK()
 | 
						|
# define ADD_REF() 0
 | 
						|
# define SUB_REF() 0
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/* Execute LINE as a shell command, returning its status.  */
 | 
						|
static int
 | 
						|
do_system (const char *line)
 | 
						|
{
 | 
						|
  int status, save;
 | 
						|
  pid_t pid;
 | 
						|
  struct sigaction sa;
 | 
						|
#ifndef _LIBC_REENTRANT
 | 
						|
  struct sigaction intr, quit;
 | 
						|
#endif
 | 
						|
  sigset_t omask;
 | 
						|
 | 
						|
  sa.sa_handler = SIG_IGN;
 | 
						|
  sa.sa_flags = 0;
 | 
						|
  __sigemptyset (&sa.sa_mask);
 | 
						|
 | 
						|
  DO_LOCK ();
 | 
						|
  if (ADD_REF () == 0)
 | 
						|
    {
 | 
						|
      if (__sigaction (SIGINT, &sa, &intr) < 0)
 | 
						|
	{
 | 
						|
	  SUB_REF ();
 | 
						|
	  goto out;
 | 
						|
	}
 | 
						|
      if (__sigaction (SIGQUIT, &sa, &quit) < 0)
 | 
						|
	{
 | 
						|
	  save = errno;
 | 
						|
	  SUB_REF ();
 | 
						|
	  goto out_restore_sigint;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  DO_UNLOCK ();
 | 
						|
 | 
						|
  /* We reuse the bitmap in the 'sa' structure.  */
 | 
						|
  __sigaddset (&sa.sa_mask, SIGCHLD);
 | 
						|
  save = errno;
 | 
						|
  if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0)
 | 
						|
    {
 | 
						|
#ifndef _LIBC
 | 
						|
      if (errno == ENOSYS)
 | 
						|
	__set_errno (save);
 | 
						|
      else
 | 
						|
#endif
 | 
						|
	{
 | 
						|
	  DO_LOCK ();
 | 
						|
	  if (SUB_REF () == 0)
 | 
						|
	    {
 | 
						|
	      save = errno;
 | 
						|
	      (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
 | 
						|
	    out_restore_sigint:
 | 
						|
	      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
 | 
						|
	      __set_errno (save);
 | 
						|
	    }
 | 
						|
	out:
 | 
						|
	  DO_UNLOCK ();
 | 
						|
	  return -1;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
#ifdef CLEANUP_HANDLER
 | 
						|
  CLEANUP_HANDLER;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef FORK
 | 
						|
  pid = FORK ();
 | 
						|
#else
 | 
						|
  pid = __fork ();
 | 
						|
#endif
 | 
						|
  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) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
 | 
						|
      INIT_LOCK ();
 | 
						|
 | 
						|
      /* 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
 | 
						|
      /* Note the system() is a cancellation point.  But since we call
 | 
						|
	 waitpid() which itself is a cancellation point we do not
 | 
						|
	 have to do anything here.  */
 | 
						|
      if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid)
 | 
						|
	status = -1;
 | 
						|
#endif
 | 
						|
    }
 | 
						|
 | 
						|
#ifdef CLEANUP_HANDLER
 | 
						|
  CLEANUP_RESET;
 | 
						|
#endif
 | 
						|
 | 
						|
  save = errno;
 | 
						|
  DO_LOCK ();
 | 
						|
  if ((SUB_REF () == 0
 | 
						|
       && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
 | 
						|
	   | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
 | 
						|
      || __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0)
 | 
						|
    {
 | 
						|
#ifndef _LIBC
 | 
						|
      /* glibc cannot be used on systems without waitpid.  */
 | 
						|
      if (errno == ENOSYS)
 | 
						|
	__set_errno (save);
 | 
						|
      else
 | 
						|
#endif
 | 
						|
	status = -1;
 | 
						|
    }
 | 
						|
  DO_UNLOCK ();
 | 
						|
 | 
						|
  return status;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
__libc_system (const char *line)
 | 
						|
{
 | 
						|
  if (line == NULL)
 | 
						|
    /* Check that we have a command processor available.  It might
 | 
						|
       not be available after a chroot(), for example.  */
 | 
						|
    return do_system ("exit 0") == 0;
 | 
						|
 | 
						|
  if (SINGLE_THREAD_P)
 | 
						|
    return do_system (line);
 | 
						|
 | 
						|
  int oldtype = LIBC_CANCEL_ASYNC ();
 | 
						|
 | 
						|
  int result = do_system (line);
 | 
						|
 | 
						|
  LIBC_CANCEL_RESET (oldtype);
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
weak_alias (__libc_system, system)
 |