GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <stdlib.h> 00002 #include <string.h> 00003 #include <unistd.h> 00004 #include <fcntl.h> 00005 #include <grass/gis.h> 00006 #include <grass/dbmi.h> 00007 #include <grass/form.h> 00008 00009 #ifdef HAVE_SOCKET 00010 #include <sys/types.h> 00011 #ifdef __MINGW32__ 00012 #include <winsock.h> 00013 00014 #else /*__MINGW32__*/ 00015 #include <sys/socket.h> 00016 #include <netinet/in.h> 00017 00018 #endif /*__MINGW32__*/ 00019 #endif /*HAVE_SOCKET */ 00020 00021 #ifdef HAVE_SOCKET 00022 static int make_socketpair(int *); 00023 #endif 00024 00025 int first = 1; 00026 00027 /* the pipe to send data to GUI */ 00028 FILE *parent_send, *parent_recv; 00029 00030 #ifdef HAVE_SOCKET 00031 int pipefd[2]; 00032 00033 #define pfd pipefd[1] /* parent's end */ 00034 #define cfd pipefd[0] /* child's end */ 00035 00036 #endif /*HAVE_SOCKET */ 00037 00038 /* Open new form 00039 * 00040 * returns: 0 success 00041 */ 00042 #ifdef __MINGW32__ 00043 int F_open(char *title, char *html) 00044 { 00045 G_fatal_error("F_open is not supported on Windows"); 00046 return 1; 00047 } 00048 #else 00049 int F_open(char *title, char *html) 00050 { 00051 /* parent */ 00052 int c; 00053 00054 /* common */ 00055 static int pid; 00056 00057 #ifndef HAVE_SOCKET 00058 static int p1[2], p2[2]; 00059 #endif /*HAVE_SOCKET */ 00060 int length; 00061 00062 /* child */ 00063 00064 G_debug(2, "F_open(): title = %s", title); 00065 00066 if (first) { 00067 #ifdef HAVE_SOCKET 00068 if (make_socketpair(pipefd) < 0) 00069 G_fatal_error("Cannot make socket pair"); 00070 #else 00071 if (pipe(p1) < 0 || pipe(p2) < 0) 00072 G_fatal_error("Cannot open pipe"); 00073 #endif /*HAVE_SOCKET */ 00074 00075 if ((pid = fork()) < 0) 00076 G_fatal_error("Cannot create fork"); 00077 } 00078 00079 if (pid == 0) { /* Child */ 00080 char command[2000], script[2000]; 00081 00082 G_debug(2, "CHILD"); 00083 00084 /* Note: If you are forking in a Tk based apllication you 00085 * must execl before doing any window operations in the 00086 * child or you will receive an error from the X server */ 00087 00088 close(0); 00089 close(1); 00090 00091 #ifndef HAVE_SOCKET 00092 close(p1[1]); 00093 close(p2[0]); 00094 if (dup(p1[0]) != 0) 00095 G_fatal_error("Form: cannot dup() input"); 00096 if (dup(p2[1]) != 1) 00097 G_fatal_error("Form: cannot dup() output"); 00098 00099 #else 00100 close(pfd); 00101 if (dup(cfd) != 0) 00102 G_fatal_error("Form: cannot dup() input"); 00103 if (dup(cfd) != 1) 00104 G_fatal_error("Form: cannot dup() output"); 00105 00106 #endif /*HAVE_SOCKET */ 00107 00108 00109 00110 sprintf(command, "%s/etc/form/form", G_gisbase()); 00111 sprintf(script, "%s/etc/form/form.tcl", G_gisbase()); 00112 00113 execl(command, "form", "-f", script, NULL); 00114 00115 G_debug(2, "CHILD END\n"); 00116 exit(0); 00117 00118 } 00119 else { /* Parent */ 00120 G_debug(2, "PARENT"); 00121 00122 if (first) { 00123 #ifndef HAVE_SOCKET 00124 parent_send = fdopen(p1[1], "w"); 00125 close(p1[0]); 00126 parent_recv = fdopen(p2[0], "r"); 00127 close(p2[1]); 00128 #else 00129 close(cfd); 00130 parent_send = fdopen(pfd, "w"); 00131 parent_recv = fdopen(pfd, "r"); 00132 #endif /*HAVE_SOCKET */ 00133 first = 0; 00134 } 00135 00136 G_debug(2, "PARENT HTML:\n%s\n", html); 00137 00138 fprintf(parent_send, "O"); 00139 length = strlen(title); 00140 fprintf(parent_send, "%d\n", length); 00141 fprintf(parent_send, "%s", title); 00142 length = strlen(html); 00143 fprintf(parent_send, "%d\n", length); 00144 fprintf(parent_send, "%s", html); 00145 fflush(parent_send); 00146 G_debug(2, "PARENT: Request sent\n"); 00147 00148 /* Wait for response */ 00149 c = fgetc(parent_recv); 00150 G_debug(2, "PARENT: received %c\n", c); 00151 } 00152 00153 return 0; 00154 } 00155 #endif 00156 00157 /* Clear old forms from window 00158 * 00159 */ 00160 void F_clear(void) 00161 { 00162 char c; 00163 00164 G_debug(2, "F_clear()"); 00165 00166 if (first) 00167 return; 00168 00169 fprintf(parent_send, "C"); 00170 fflush(parent_send); 00171 c = fgetc(parent_recv); 00172 G_debug(2, "PARENT: received %c\n", c); 00173 } 00174 00175 void F_close(void) 00176 { 00177 char c; 00178 00179 G_debug(2, "F_close()"); 00180 00181 if (first) 00182 return; 00183 00184 fprintf(parent_send, "D"); 00185 fflush(parent_send); 00186 c = fgetc(parent_recv); 00187 G_debug(2, "PARENT: received %c\n", c); 00188 00189 first = 1; 00190 } 00191 00192 #ifdef HAVE_SOCKET 00193 static int make_socketpair(int *fd) 00194 { 00195 int n; 00196 00197 if ((n = socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, fd)) < 0) 00198 return -1; 00199 else 00200 return 0; 00201 } 00202 00203 #endif