open.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <grass/gis.h>
  6. #include <grass/dbmi.h>
  7. #include <grass/form.h>
  8. #ifdef HAVE_SOCKET
  9. #include <sys/types.h>
  10. #ifdef __MINGW32__
  11. #include <winsock.h>
  12. #else /*__MINGW32__*/
  13. #include <sys/socket.h>
  14. #include <netinet/in.h>
  15. #endif /*__MINGW32__*/
  16. #endif /*HAVE_SOCKET */
  17. #ifdef HAVE_SOCKET
  18. static int make_socketpair(int *);
  19. #endif
  20. int first = 1;
  21. /* the pipe to send data to GUI */
  22. FILE *parent_send, *parent_recv;
  23. #ifdef HAVE_SOCKET
  24. int pipefd[2];
  25. #define pfd pipefd[1] /* parent's end */
  26. #define cfd pipefd[0] /* child's end */
  27. #endif /*HAVE_SOCKET */
  28. /* Open new form
  29. *
  30. * returns: 0 success
  31. */
  32. #ifdef __MINGW32__
  33. int F_open(char *title, char *html)
  34. {
  35. G_fatal_error("F_open is not supported on Windows");
  36. return 1;
  37. }
  38. #else
  39. int F_open(char *title, char *html)
  40. {
  41. /* parent */
  42. int c;
  43. /* common */
  44. static int pid;
  45. #ifndef HAVE_SOCKET
  46. static int p1[2], p2[2];
  47. #endif /*HAVE_SOCKET */
  48. int length;
  49. /* child */
  50. G_debug(2, "F_open(): title = %s", title);
  51. if (first) {
  52. #ifdef HAVE_SOCKET
  53. if (make_socketpair(pipefd) < 0)
  54. G_fatal_error("Cannot make socket pair");
  55. #else
  56. if (pipe(p1) < 0 || pipe(p2) < 0)
  57. G_fatal_error("Cannot open pipe");
  58. #endif /*HAVE_SOCKET */
  59. if ((pid = fork()) < 0)
  60. G_fatal_error("Cannot create fork");
  61. }
  62. if (pid == 0) { /* Child */
  63. char command[2000], script[2000];
  64. G_debug(2, "CHILD");
  65. /* Note: If you are forking in a Tk based apllication you
  66. * must execl before doing any window operations in the
  67. * child or you will receive an error from the X server */
  68. close(0);
  69. close(1);
  70. #ifndef HAVE_SOCKET
  71. close(p1[1]);
  72. close(p2[0]);
  73. if (dup(p1[0]) != 0)
  74. G_fatal_error("Form: cannot dup() input");
  75. if (dup(p2[1]) != 1)
  76. G_fatal_error("Form: cannot dup() output");
  77. #else
  78. close(pfd);
  79. if (dup(cfd) != 0)
  80. G_fatal_error("Form: cannot dup() input");
  81. if (dup(cfd) != 1)
  82. G_fatal_error("Form: cannot dup() output");
  83. #endif /*HAVE_SOCKET */
  84. sprintf(command, "%s/etc/form/form", G_gisbase());
  85. sprintf(script, "%s/etc/form/form.tcl", G_gisbase());
  86. execl(command, "form", "-f", script, NULL);
  87. G_debug(2, "CHILD END\n");
  88. exit(0);
  89. }
  90. else { /* Parent */
  91. G_debug(2, "PARENT");
  92. if (first) {
  93. #ifndef HAVE_SOCKET
  94. parent_send = fdopen(p1[1], "w");
  95. close(p1[0]);
  96. parent_recv = fdopen(p2[0], "r");
  97. close(p2[1]);
  98. #else
  99. close(cfd);
  100. parent_send = fdopen(pfd, "w");
  101. parent_recv = fdopen(pfd, "r");
  102. #endif /*HAVE_SOCKET */
  103. first = 0;
  104. }
  105. G_debug(2, "PARENT HTML:\n%s\n", html);
  106. fprintf(parent_send, "O");
  107. length = strlen(title);
  108. fprintf(parent_send, "%d\n", length);
  109. fprintf(parent_send, "%s", title);
  110. length = strlen(html);
  111. fprintf(parent_send, "%d\n", length);
  112. fprintf(parent_send, "%s", html);
  113. fflush(parent_send);
  114. G_debug(2, "PARENT: Request sent\n");
  115. /* Wait for response */
  116. c = fgetc(parent_recv);
  117. G_debug(2, "PARENT: received %c\n", c);
  118. }
  119. return 0;
  120. }
  121. #endif
  122. /* Clear old forms from window
  123. *
  124. */
  125. void F_clear(void)
  126. {
  127. char c;
  128. G_debug(2, "F_clear()");
  129. if (first)
  130. return;
  131. fprintf(parent_send, "C");
  132. fflush(parent_send);
  133. c = fgetc(parent_recv);
  134. G_debug(2, "PARENT: received %c\n", c);
  135. }
  136. void F_close(void)
  137. {
  138. char c;
  139. G_debug(2, "F_close()");
  140. if (first)
  141. return;
  142. fprintf(parent_send, "D");
  143. fflush(parent_send);
  144. c = fgetc(parent_recv);
  145. G_debug(2, "PARENT: received %c\n", c);
  146. first = 1;
  147. }
  148. #ifdef HAVE_SOCKET
  149. static int make_socketpair(int *fd)
  150. {
  151. int n;
  152. if ((n = socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, fd)) < 0)
  153. return -1;
  154. else
  155. return 0;
  156. }
  157. #endif