GRASS Programmer's Manual  6.4.2(2012)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
driver.c
Go to the documentation of this file.
1 
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <grass/gis.h>
23 #include <grass/dbmi.h>
24 #include "procs.h"
25 #define DB_DRIVER_C
26 #include "dbstubs.h"
27 
28 extern char *getenv();
29 
38 int db_driver(int argc, char *argv[])
39 {
40  int stat;
41  int procnum;
42  int i;
43  int rfd, wfd;
44  FILE *send, *recv;
45  char *modestr;
46 
47  /* Read and set environment variables, see dbmi_client/start.c */
48  if ((modestr = getenv("GRASS_DB_DRIVER_GISRC_MODE"))) {
49  int mode;
50 
51  mode = atoi(modestr);
52 
53  if (mode == G_GISRC_MODE_MEMORY) {
54  G_set_gisrc_mode(G_GISRC_MODE_MEMORY);
55  G__setenv("DEBUG", getenv("DEBUG"));
56  G__setenv("GISDBASE", getenv("GISDBASE"));
57  G__setenv("LOCATION_NAME", getenv("LOCATION_NAME"));
58  G__setenv("MAPSET", getenv("MAPSET"));
59  G_debug(3, "Driver GISDBASE set to '%s'", G_getenv("GISDBASE"));
60  }
61  }
62 
63 #ifdef __MINGW32__
64  /* TODO: */
65  /* We should close everything except stdin, stdout but _fcloseall()
66  * closes open streams not file descriptors. _getmaxstdio too big number.
67  *
68  * Because the pipes were created just before this driver was started
69  * the file descriptors should not be above a closed descriptor
70  * until it was run from a multithread application and some descriptors
71  * were closed in the mean time.
72  * Also Windows documentation does not say that new file descriptor is
73  * the lowest available.
74  */
75 
76  {
77  int err_count = 0;
78  int cfd = 3;
79 
80  while (1) {
81  if (close(cfd) == -1)
82  err_count++;
83 
84  /* no good reason for 10 */
85  if (err_count > 10)
86  break;
87 
88  cfd++;
89  }
90  }
91 #endif
92 
93  send = stdout;
94  recv = stdin;
95 
96  /* THIS CODE IS FOR DEBUGGING WITH CODECENTER */
97 
98 /**********************************************/
99  if (argc == 3) {
100  rfd = wfd = -1;
101  sscanf(argv[1], "%d", &rfd);
102  sscanf(argv[2], "%d", &wfd);
103  send = fdopen(wfd, "w");
104  if (send == NULL) {
105  db_syserror(argv[1]);
106  exit(1);
107  }
108  recv = fdopen(rfd, "r");
109  if (recv == NULL) {
110  db_syserror(argv[2]);
111  exit(1);
112  }
113  }
114 
115 /**********************************************/
116 
117  db_clear_error();
121 
122 #ifndef USE_BUFFERED_IO
123  setbuf(recv, NULL);
124  setbuf(send, NULL);
125 #endif
126  db__set_protocol_fds(send, recv);
127 
128  if (db_driver_init(argc, argv) == DB_OK)
130  else {
132  exit(1);
133  }
134 
135  stat = DB_OK;
136  /* get the procedure number */
137  while (db__recv_procnum(&procnum) == DB_OK) {
138 #ifdef __MINGW32__
139  if (procnum == DB_PROC_SHUTDOWN_DRIVER) {
140  db__send_procedure_ok(procnum);
141  break;
142  }
143 #endif
144  db_clear_error();
145 
146  /* find this procedure */
147  for (i = 0; procedure[i].routine; i++)
148  if (procedure[i].procnum == procnum)
149  break;
150 
151  /* if found, call it */
152  if (procedure[i].routine) {
153  if ((stat = db__send_procedure_ok(procnum)) != DB_OK)
154  break; /* while loop */
155  if ((stat = (*procedure[i].routine) ()) != DB_OK)
156  break;
157  }
158  else if ((stat =
159  db__send_procedure_not_implemented(procnum)) != DB_OK)
160  break;
161  }
162 
164 
165  exit(stat == DB_OK ? 0 : 1);
166 }