popen.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <grass/gis.h>
  5. #include <grass/spawn.h>
  6. #ifdef __MINGW32__
  7. #include <io.h>
  8. #include <fcntl.h>
  9. #define pipe(fds) _pipe(fds, 4096, O_BINARY|O_NOINHERIT)
  10. #endif
  11. static FILE *do_popen(struct Popen *state, int wr,
  12. const char *program, const char **args)
  13. {
  14. int which = wr ? 0 : 1;
  15. const char *dir = wr ? "w" : "r";
  16. int pfd, cfd;
  17. int pipe_fds[2];
  18. const char *argv[2];
  19. state->fp = NULL;
  20. state->pid = -1;
  21. if (pipe(pipe_fds) < 0)
  22. return NULL;
  23. cfd = pipe_fds[wr ? 0 : 1];
  24. pfd = pipe_fds[wr ? 1 : 0];
  25. if (!args) {
  26. argv[0] = program;
  27. argv[1] = NULL;
  28. args = argv;
  29. }
  30. state->pid = G_spawn_ex(
  31. program,
  32. SF_ARGVEC, args,
  33. SF_REDIRECT_DESCRIPTOR, which, cfd,
  34. SF_CLOSE_DESCRIPTOR, pfd,
  35. SF_BACKGROUND, NULL);
  36. if (state->pid == -1) {
  37. close(pipe_fds[0]);
  38. close(pipe_fds[1]);
  39. return NULL;
  40. }
  41. close(cfd);
  42. state->fp = fdopen(pfd, dir);
  43. return state->fp;
  44. }
  45. void G_popen_clear(struct Popen *state)
  46. {
  47. state->fp = NULL;
  48. state->pid = -1;
  49. }
  50. FILE *G_popen_write(struct Popen *state, const char *program, const char **args)
  51. {
  52. return do_popen(state, 1, program, args);
  53. }
  54. FILE *G_popen_read(struct Popen *state, const char *program, const char **args)
  55. {
  56. return do_popen(state, 0, program, args);
  57. }
  58. void G_popen_close(struct Popen *state)
  59. {
  60. if (state->fp)
  61. fclose(state->fp);
  62. if (state->pid != -1)
  63. G_wait(state->pid);
  64. }