system.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /**
  2. * \file system.c
  3. *
  4. * \brief GIS Library - Command execution functions.
  5. *
  6. * (C) 2001-2008 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public License
  9. * (>=v2). Read the file COPYING that comes with GRASS for details.
  10. *
  11. * \author GRASS GIS Development Team
  12. *
  13. * \date 1999-2008
  14. */
  15. #include <grass/config.h>
  16. #include <stdlib.h>
  17. #include <unistd.h>
  18. #include <signal.h>
  19. #include <stdio.h>
  20. #include <sys/types.h>
  21. #ifndef __MINGW32__
  22. #include <sys/wait.h>
  23. #endif
  24. #include <grass/gis.h>
  25. #include <grass/glocale.h>
  26. /**
  27. * \brief Run a shell level command.
  28. *
  29. * This is essentially the UNIX <i>system()</i> call, except for the
  30. * signal handling. During the call, user generated signals (intr, quit)
  31. * for the parent are ignored, but allowed for the child. Parent
  32. * signals are reset upon completion.<br>
  33. *
  34. * This routine is useful for menu type programs that need to run
  35. * external commands and allow these commands to be interrupted by
  36. * the user without killing the menu itself.<br>
  37. *
  38. * <b>Note:</b> if you want the signal settings to be the same for the
  39. * parent and the command being run, set them yourself and use
  40. * the UNIX <i>system()</i> call instead.
  41. *
  42. * \param[in] command
  43. * \return -1 on error
  44. * \return status on success
  45. */
  46. int G_system(const char *command)
  47. {
  48. int status;
  49. #ifndef __MINGW32__
  50. int pid, w;
  51. #endif
  52. RETSIGTYPE(*sigint) ();
  53. #ifdef SIGQUIT
  54. RETSIGTYPE(*sigquit) ();
  55. #endif
  56. sigint = signal(SIGINT, SIG_IGN);
  57. #ifdef SIGQUIT
  58. sigquit = signal(SIGQUIT, SIG_IGN);
  59. #endif
  60. fflush(stdout);
  61. fflush(stderr);
  62. #ifdef __MINGW32__
  63. signal(SIGINT, SIG_DFL);
  64. _spawnlp(P_WAIT, "cmd.exe", "cmd.exe", "/c", command, NULL);
  65. status = 0;
  66. #else
  67. if ((pid = fork()) == 0) {
  68. signal(SIGINT, SIG_DFL);
  69. signal(SIGQUIT, SIG_DFL);
  70. execl("/bin/sh", "sh", "-c", command, NULL);
  71. _exit(127);
  72. }
  73. if (pid < 0) {
  74. G_warning(_("Can not create a new process!"));
  75. status = -1;
  76. }
  77. else {
  78. while ((w = wait(&status)) != pid && w != -1) ;
  79. if (w == -1)
  80. status = -1;
  81. }
  82. #endif
  83. signal(SIGINT, sigint);
  84. #ifdef SIGQUIT
  85. signal(SIGQUIT, sigquit);
  86. #endif
  87. return (status);
  88. }