system.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. #include <stdio.h>
  7. #include <stddef.h>
  8. #include <signal.h>
  9. #include <unistd.h>
  10. #include <sys/wait.h>
  11. #include <stdlib.h>
  12. libc_hidden_proto(_exit)
  13. libc_hidden_proto(wait4)
  14. libc_hidden_proto(execl)
  15. libc_hidden_proto(signal)
  16. libc_hidden_proto(vfork)
  17. /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
  18. #include <sys/syscall.h>
  19. #ifndef __NR_vfork
  20. # define vfork fork
  21. libc_hidden_proto(fork)
  22. #endif
  23. extern __typeof(system) __libc_system;
  24. int __libc_system(const char *command)
  25. {
  26. int wait_val, pid;
  27. __sighandler_t save_quit, save_int, save_chld;
  28. if (command == 0)
  29. return 1;
  30. save_quit = signal(SIGQUIT, SIG_IGN);
  31. save_int = signal(SIGINT, SIG_IGN);
  32. save_chld = signal(SIGCHLD, SIG_DFL);
  33. if ((pid = vfork()) < 0) {
  34. signal(SIGQUIT, save_quit);
  35. signal(SIGINT, save_int);
  36. signal(SIGCHLD, save_chld);
  37. return -1;
  38. }
  39. if (pid == 0) {
  40. signal(SIGQUIT, SIG_DFL);
  41. signal(SIGINT, SIG_DFL);
  42. signal(SIGCHLD, SIG_DFL);
  43. execl("/bin/sh", "sh", "-c", command, (char *) 0);
  44. _exit(127);
  45. }
  46. /* Signals are not absolutly guarenteed with vfork */
  47. signal(SIGQUIT, SIG_IGN);
  48. signal(SIGINT, SIG_IGN);
  49. #if 0
  50. __printf("Waiting for child %d\n", pid);
  51. #endif
  52. if (wait4(pid, &wait_val, 0, 0) == -1)
  53. wait_val = -1;
  54. signal(SIGQUIT, save_quit);
  55. signal(SIGINT, save_int);
  56. signal(SIGCHLD, save_chld);
  57. return wait_val;
  58. }
  59. weak_alias(__libc_system,system)