system.c 2.1 KB

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