open.c 3.8 KB

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