GRASS 8 Programmer's Manual 8.6.0dev(2026)-f6f2c534ea
Loading...
Searching...
No Matches
start.c
Go to the documentation of this file.
1/*!
2 * \file db/dbmi_client/start.c
3 *
4 * \brief DBMI Library (client) - open database connection
5 *
6 * (C) 1999-2008 by the GRASS Development Team
7 *
8 * This program is free software under the GNU General Public
9 * License (>=v2). Read the file COPYING that comes with GRASS
10 * for details.
11 *
12 * \author Joel Jones (CERL/UIUC), Radim Blazek
13 */
14
15#include <string.h>
16#include <stdlib.h>
17#include <unistd.h>
18
19#ifdef _WIN32
20#include <windows.h>
21#include <process.h>
22#include <fcntl.h>
23#endif
24
25#include <grass/spawn.h>
26#include <grass/dbmi.h>
27
28#define READ 0
29#define WRITE 1
30
31static void close_on_exec(int fd)
32{
33#ifndef _WIN32
34 int flags = fcntl(fd, F_GETFD);
35
36 fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
37#endif
38}
39
40/*!
41 \brief Initialize a new dbDriver for db transaction.
42
43 If <i>name</i> is NULL, the db name will be assigned
44 connection.driverName.
45
46 \param name driver name
47
48 \return pointer to dbDriver structure
49 \return NULL on error
50 */
52{
54 dbDbmscap *list, *cur;
55 const char *startup;
56 int p1[2], p2[2];
57 int pid;
58 int stat;
60 char ebuf[5];
61
62 /* Set some environment variables which are later read by driver.
63 * This is necessary when application is running without GISRC file and all
64 * gis variables are set by application.
65 * Even if GISRC is set, application may change some variables during
66 * runtime, if for example reads data from different gdatabase, location or
67 * mapset */
68
69 /* setenv() is not portable, putenv() is POSIX, putenv() in glibc 2.0-2.1.1
70 * doesn't conform to SUSv2, G_putenv() as well, but that is what we want,
71 * makes a copy of string */
73 G_debug(3, "G_GISRC_MODE_MEMORY\n");
74 snprintf(ebuf, sizeof(ebuf), "%d", G_GISRC_MODE_MEMORY);
75 G_putenv("GRASS_DB_DRIVER_GISRC_MODE",
76 ebuf); /* to tell driver that it must read variables */
77
78 if (G_getenv_nofatal("DEBUG")) {
79 G_putenv("DEBUG", G_getenv_nofatal("DEBUG"));
80 }
81 else {
82 G_putenv("DEBUG", "0");
83 }
84
85 G_putenv("GISDBASE", G_getenv_nofatal("GISDBASE"));
86 G_putenv("LOCATION_NAME", G_getenv_nofatal("LOCATION_NAME"));
87 G_putenv("MAPSET", G_getenv_nofatal("MAPSET"));
88 }
89 else {
90 /* Warning: GISRC_MODE_MEMORY _must_ be set to G_GISRC_MODE_FILE,
91 * because the module can be run from an application which previously
92 * set environment variable to G_GISRC_MODE_MEMORY */
93 snprintf(ebuf, sizeof(ebuf), "%d", G_GISRC_MODE_FILE);
94 G_putenv("GRASS_DB_DRIVER_GISRC_MODE", ebuf);
95 }
96
97 /* read the dbmscap file */
98 if (NULL == (list = db_read_dbmscap()))
99 return (dbDriver *)NULL;
100
101 /* if name is empty use connection.driverName, added by RB 4/2000 */
102 if (name == NULL || name[0] == '\0') {
104 if (NULL == (name = connection.driverName))
105 return (dbDriver *)NULL;
106 }
107
108 /* find this system name */
109 for (cur = list; cur; cur = cur->next)
110 if (strcmp(cur->driverName, name) == 0)
111 break;
112 if (cur == NULL) {
113 char msg[256];
114
116 snprintf(msg, sizeof(msg), "%s: no such driver available", name);
117 db_error(msg);
118 return (dbDriver *)NULL;
119 }
120
121 /* allocate a driver structure */
122 driver = (dbDriver *)db_malloc(sizeof(dbDriver));
123 if (driver == NULL) {
125 return (dbDriver *)NULL;
126 }
127
128 /* copy the relevant info from the dbmscap entry into the driver structure
129 */
130 db_copy_dbmscap_entry(&driver->dbmscap, cur);
131 startup = driver->dbmscap.startup;
132
133 /* free the dbmscap list */
135
136 /* run the driver as a child process and create pipes to its stdin, stdout
137 */
138
139#ifdef _WIN32
140#define pipe(fds) _pipe(fds, 250000, _O_BINARY | _O_NOINHERIT)
141#endif
142
143 /* open the pipes */
144 if ((pipe(p1) < 0) || (pipe(p2) < 0)) {
145 db_syserror("can't open any pipes");
146 return (dbDriver *)NULL;
147 }
148
149 close_on_exec(p1[READ]);
150 close_on_exec(p1[WRITE]);
151 close_on_exec(p2[READ]);
152 close_on_exec(p2[WRITE]);
153
154 pid =
157 p2[WRITE], SF_CLOSE_DESCRIPTOR, p2[READ], startup, NULL);
158
159 /* create a child */
160 if (pid < 0) {
161 db_syserror("can't create fork");
162 return (dbDriver *)NULL;
163 }
164
165 close(p1[READ]);
166 close(p2[WRITE]);
167
168 /* record driver process id in driver struct */
169 driver->pid = pid;
170
171 /* convert pipes to FILE* */
172 driver->send = fdopen(p1[WRITE], "wb");
173 driver->recv = fdopen(p2[READ], "rb");
174
175 /* most systems will have to use unbuffered io to get the send/recv to work
176 */
177#ifndef USE_BUFFERED_IO
178 setbuf(driver->send, NULL);
179 setbuf(driver->recv, NULL);
180#endif
181
182 db__set_protocol_fds(driver->send, driver->recv);
184 driver = NULL;
185
186 return driver;
187}
#define NULL
Definition ccmath.h:32
Main header of GRASS DataBase Management Interface.
#define DB_OK
Definition dbmi.h:71
void db_copy_dbmscap_entry(dbDbmscap *, dbDbmscap *)
Copy dbmscap entry.
Definition dbmscap.c:79
dbDbmscap * db_read_dbmscap(void)
Read dbmscap.
Definition dbmscap.c:98
int db_get_connection(dbConnection *)
Get default DB connection settings for the current mapset.
void db__set_protocol_fds(FILE *, FILE *)
?
void db_error(const char *)
Report error message.
void db_syserror(const char *)
Report system error.
void db_free_dbmscap(dbDbmscap *)
Free dbmscap.
Definition dbmscap.c:264
void * db_malloc(int)
Allocate memory.
int db__recv_return_code(int *)
Receive return code.
Definition ret_codes.c:51
const char * G_getenv_nofatal(const char *)
Get environment variable.
Definition env.c:405
void G_putenv(const char *, const char *)
Sets the UNIX environment variable name to value.
Definition putenv.c:31
int G_get_gisrc_mode(void)
Get info where variables are stored.
Definition env.c:73
int G_debug(int, const char *,...) __attribute__((format(printf
int G_spawn_ex(const char *command,...)
Spawn new process based on command.
Definition spawn.c:899
Header file for msvc/fcntl.c.
#define G_GISRC_MODE_FILE
Definition gis.h:185
#define G_GISRC_MODE_MEMORY
Definition gis.h:186
const char * name
Definition named_colr.c:6
#define SF_CLOSE_DESCRIPTOR
Definition spawn.h:19
#define SF_REDIRECT_DESCRIPTOR
Definition spawn.h:18
#define SF_BACKGROUND
Definition spawn.h:23
dbDriver * db_start_driver(const char *name)
Initialize a new dbDriver for db transaction.
Definition start.c:51
#define WRITE
Definition start.c:29
#define READ
Definition start.c:28
#define fdopen
Definition stdio.h:6
char driverName[256]
Definition dbmi.h:153
struct _dbmscap * next
Definition dbmi.h:156
Definition manage.h:4
#define close
Definition unistd.h:8