GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
form/open.c
Go to the documentation of this file.
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 
9 #ifdef HAVE_SOCKET
10 #include <sys/types.h>
11 #ifdef __MINGW32__
12 #include <winsock.h>
13 
14 #else /*__MINGW32__*/
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 
18 #endif /*__MINGW32__*/
19 #endif /*HAVE_SOCKET */
20 
21 #ifdef HAVE_SOCKET
22 static int make_socketpair(int *);
23 #endif
24 
25 int first = 1;
26 
27 /* the pipe to send data to GUI */
29 
30 #ifdef HAVE_SOCKET
31 int pipefd[2];
32 
33 #define pfd pipefd[1] /* parent's end */
34 #define cfd pipefd[0] /* child's end */
35 
36 #endif /*HAVE_SOCKET */
37 
38 /* Open new form
39  *
40  * returns: 0 success
41  */
42 #ifdef __MINGW32__
43 int F_open(char *title, char *html)
44 {
45  G_fatal_error("F_open is not supported on Windows");
46  return 1;
47 }
48 #else
49 int F_open(char *title, char *html)
50 {
51  /* parent */
52  int c;
53 
54  /* common */
55  static int pid;
56 
57 #ifndef HAVE_SOCKET
58  static int p1[2], p2[2];
59 #endif /*HAVE_SOCKET */
60  int length;
61 
62  /* child */
63 
64  G_debug(2, "F_open(): title = %s", title);
65 
66  if (first) {
67 #ifdef HAVE_SOCKET
68  if (make_socketpair(pipefd) < 0)
69  G_fatal_error("Cannot make socket pair");
70 #else
71  if (pipe(p1) < 0 || pipe(p2) < 0)
72  G_fatal_error("Cannot open pipe");
73 #endif /*HAVE_SOCKET */
74 
75  if ((pid = fork()) < 0)
76  G_fatal_error("Cannot create fork");
77  }
78 
79  if (pid == 0) { /* Child */
80  char command[2000], script[2000];
81 
82  G_debug(2, "CHILD");
83 
84  /* Note: If you are forking in a Tk based apllication you
85  * must execl before doing any window operations in the
86  * child or you will receive an error from the X server */
87 
88  close(0);
89  close(1);
90 
91 #ifndef HAVE_SOCKET
92  close(p1[1]);
93  close(p2[0]);
94  if (dup(p1[0]) != 0)
95  G_fatal_error("Form: cannot dup() input");
96  if (dup(p2[1]) != 1)
97  G_fatal_error("Form: cannot dup() output");
98 
99 #else
100  close(pfd);
101  if (dup(cfd) != 0)
102  G_fatal_error("Form: cannot dup() input");
103  if (dup(cfd) != 1)
104  G_fatal_error("Form: cannot dup() output");
105 
106 #endif /*HAVE_SOCKET */
107 
108 
109 
110  sprintf(command, "%s/etc/form/form", G_gisbase());
111  sprintf(script, "%s/etc/form/form.tcl", G_gisbase());
112 
113  execl(command, "form", "-f", script, NULL);
114 
115  G_debug(2, "CHILD END\n");
116  exit(0);
117 
118  }
119  else { /* Parent */
120  G_debug(2, "PARENT");
121 
122  if (first) {
123 #ifndef HAVE_SOCKET
124  parent_send = fdopen(p1[1], "w");
125  close(p1[0]);
126  parent_recv = fdopen(p2[0], "r");
127  close(p2[1]);
128 #else
129  close(cfd);
130  parent_send = fdopen(pfd, "w");
131  parent_recv = fdopen(pfd, "r");
132 #endif /*HAVE_SOCKET */
133  first = 0;
134  }
135 
136  G_debug(2, "PARENT HTML:\n%s\n", html);
137 
138  fprintf(parent_send, "O");
139  length = strlen(title);
140  fprintf(parent_send, "%d\n", length);
141  fprintf(parent_send, "%s", title);
142  length = strlen(html);
143  fprintf(parent_send, "%d\n", length);
144  fprintf(parent_send, "%s", html);
145  fflush(parent_send);
146  G_debug(2, "PARENT: Request sent\n");
147 
148  /* Wait for response */
149  c = fgetc(parent_recv);
150  G_debug(2, "PARENT: received %c\n", c);
151  }
152 
153  return 0;
154 }
155 #endif
156 
157 /* Clear old forms from window
158  *
159  */
160 void F_clear(void)
161 {
162  char c;
163 
164  G_debug(2, "F_clear()");
165 
166  if (first)
167  return;
168 
169  fprintf(parent_send, "C");
170  fflush(parent_send);
171  c = fgetc(parent_recv);
172  G_debug(2, "PARENT: received %c\n", c);
173 }
174 
175 void F_close(void)
176 {
177  char c;
178 
179  G_debug(2, "F_close()");
180 
181  if (first)
182  return;
183 
184  fprintf(parent_send, "D");
185  fflush(parent_send);
186  c = fgetc(parent_recv);
187  G_debug(2, "PARENT: received %c\n", c);
188 
189  first = 1;
190 }
191 
192 #ifdef HAVE_SOCKET
193 static int make_socketpair(int *fd)
194 {
195  int n;
196 
197  if ((n = socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, fd)) < 0)
198  return -1;
199  else
200  return 0;
201 }
202 
203 #endif
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
void F_clear(void)
Definition: form/open.c:160
FILE * parent_recv
Definition: form/open.c:28
FILE * fd
Definition: g3dcolor.c:368
void F_close(void)
Definition: form/open.c:175
list command
Definition: render.py:1315
FILE * parent_send
Definition: form/open.c:28
int first
Definition: form/open.c:25
return NULL
Definition: dbfopen.c:1394
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
char * G_gisbase(void)
top level module directory
Definition: gisbase.c:42
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int n
Definition: dataquad.c:291
int F_open(char *title, char *html)
Definition: form/open.c:49