system.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. libc_hidden_proto(_exit)
  12. libc_hidden_proto(wait4)
  13. libc_hidden_proto(execl)
  14. libc_hidden_proto(signal)
  15. libc_hidden_proto(vfork)
  16. /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
  17. #include <sys/syscall.h>
  18. #if ! defined __NR_vfork
  19. #define vfork fork
  20. libc_hidden_proto(fork)
  21. #endif
  22. int __libc_system(char *command)
  23. {
  24. int wait_val, pid;
  25. __sighandler_t save_quit, save_int, save_chld;
  26. if (command == 0)
  27. return 1;
  28. save_quit = signal(SIGQUIT, SIG_IGN);
  29. save_int = signal(SIGINT, SIG_IGN);
  30. save_chld = signal(SIGCHLD, SIG_DFL);
  31. if ((pid = vfork()) < 0) {
  32. signal(SIGQUIT, save_quit);
  33. signal(SIGINT, save_int);
  34. signal(SIGCHLD, save_chld);
  35. return -1;
  36. }
  37. if (pid == 0) {
  38. signal(SIGQUIT, SIG_DFL);
  39. signal(SIGINT, SIG_DFL);
  40. signal(SIGCHLD, SIG_DFL);
  41. execl("/bin/sh", "sh", "-c", command, (char *) 0);
  42. _exit(127);
  43. }
  44. /* Signals are not absolutly guarenteed with vfork */
  45. signal(SIGQUIT, SIG_IGN);
  46. signal(SIGINT, SIG_IGN);
  47. #if 0
  48. __printf("Waiting for child %d\n", pid);
  49. #endif
  50. if (wait4(pid, &wait_val, 0, 0) == -1)
  51. wait_val = -1;
  52. signal(SIGQUIT, save_quit);
  53. signal(SIGINT, save_int);
  54. signal(SIGCHLD, save_chld);
  55. return wait_val;
  56. }
  57. strong_alias(__libc_system,system)