#include #include #include #include #include #include #include #ifdef HAVE_SOCKET #include #ifdef __MINGW32__ #include #else /*__MINGW32__*/ #include #include #endif /*__MINGW32__*/ #endif /*HAVE_SOCKET */ #ifdef HAVE_SOCKET static int make_socketpair(int *); #endif int first = 1; /* the pipe to send data to GUI */ FILE *parent_send, *parent_recv; #ifdef HAVE_SOCKET int pipefd[2]; #define pfd pipefd[1] /* parent's end */ #define cfd pipefd[0] /* child's end */ #endif /*HAVE_SOCKET */ /* Open new form * * returns: 0 success */ #ifdef __MINGW32__ int F_open(char *title, char *html) { G_fatal_error("F_open is not supported on Windows"); return 1; } #else int F_open(char *title, char *html) { /* parent */ int c; /* common */ static int pid; #ifndef HAVE_SOCKET static int p1[2], p2[2]; #endif /*HAVE_SOCKET */ int length; /* child */ G_debug(2, "F_open(): title = %s", title); if (first) { #ifdef HAVE_SOCKET if (make_socketpair(pipefd) < 0) G_fatal_error("Cannot make socket pair"); #else if (pipe(p1) < 0 || pipe(p2) < 0) G_fatal_error("Cannot open pipe"); #endif /*HAVE_SOCKET */ if ((pid = fork()) < 0) G_fatal_error("Cannot create fork"); } if (pid == 0) { /* Child */ char command[2000], script[2000]; G_debug(2, "CHILD"); /* Note: If you are forking in a Tk based apllication you * must execl before doing any window operations in the * child or you will receive an error from the X server */ close(0); close(1); #ifndef HAVE_SOCKET close(p1[1]); close(p2[0]); if (dup(p1[0]) != 0) G_fatal_error("Form: cannot dup() input"); if (dup(p2[1]) != 1) G_fatal_error("Form: cannot dup() output"); #else close(pfd); if (dup(cfd) != 0) G_fatal_error("Form: cannot dup() input"); if (dup(cfd) != 1) G_fatal_error("Form: cannot dup() output"); #endif /*HAVE_SOCKET */ sprintf(command, "%s/etc/form/form", G_gisbase()); sprintf(script, "%s/etc/form/form.tcl", G_gisbase()); execl(command, "form", "-f", script, NULL); G_debug(2, "CHILD END\n"); exit(0); } else { /* Parent */ G_debug(2, "PARENT"); if (first) { #ifndef HAVE_SOCKET parent_send = fdopen(p1[1], "w"); close(p1[0]); parent_recv = fdopen(p2[0], "r"); close(p2[1]); #else close(cfd); parent_send = fdopen(pfd, "w"); parent_recv = fdopen(pfd, "r"); #endif /*HAVE_SOCKET */ first = 0; } G_debug(2, "PARENT HTML:\n%s\n", html); fprintf(parent_send, "O"); length = strlen(title); fprintf(parent_send, "%d\n", length); fprintf(parent_send, "%s", title); length = strlen(html); fprintf(parent_send, "%d\n", length); fprintf(parent_send, "%s", html); fflush(parent_send); G_debug(2, "PARENT: Request sent\n"); /* Wait for response */ c = fgetc(parent_recv); G_debug(2, "PARENT: received %c\n", c); } return 0; } #endif /* Clear old forms from window * */ void F_clear(void) { char c; G_debug(2, "F_clear()"); if (first) return; fprintf(parent_send, "C"); fflush(parent_send); c = fgetc(parent_recv); G_debug(2, "PARENT: received %c\n", c); } void F_close(void) { char c; G_debug(2, "F_close()"); if (first) return; fprintf(parent_send, "D"); fflush(parent_send); c = fgetc(parent_recv); G_debug(2, "PARENT: received %c\n", c); first = 1; } #ifdef HAVE_SOCKET static int make_socketpair(int *fd) { int n; if ((n = socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, fd)) < 0) return -1; else return 0; } #endif