popen.c 1.3 KB

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