GRASS GIS 8 Programmer's Manual 8.2.0(2022)-exported
gis/open.c
Go to the documentation of this file.
1/*!
2 * \file lib/gis/open.c
3 *
4 * \brief GIS Library - Open file functions
5 *
6 * (C) 1999-2015 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 USACERL and many others
13 */
14
15#include <grass/config.h>
16#include <errno.h>
17#include <string.h>
18
19#include <unistd.h>
20#include <fcntl.h>
21
22#include <grass/gis.h>
23#include <grass/glocale.h>
24
25#include "gis_local_proto.h"
26
27/*!
28 \brief Lowest level open routine.
29
30 Opens the file <i>name</i> in <i>element</i> ("cell", etc.) in mapset <i>mapset</i>
31 according to the i/o <i>mode</i>.
32
33 - mode = 0 (read) will look for <i>name</i> in <i>mapset</i> and
34 open the file for read only the file must exist
35
36 - mode = 1 (write) will create an empty file <i>name</i> in the
37 current mapset and open the file for write only
38 <i>mapset</i> ignored
39
40 - mode = 2 (read and write) will open a file in the current mapset
41 for reading and writing creating a new file if
42 necessary <i>mapset</i> ignored
43
44 \param element database element name
45 \param name map file name
46 \param mapset mapset containing map <i>name</i>
47 \param mode r/w mode 0=read, 1=write, 2=read/write
48
49 \return open file descriptor (int)
50 \return -1 could not open
51*/
52static int G__open(const char *element,
53 const char *name, const char *mapset, int mode)
54{
55 int fd;
56 int is_tmp;
57 char path[GPATH_MAX];
58 char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
59
61
62 is_tmp = (element && strncmp(element, ".tmp", 4) == 0);
63
64 /* READ */
65 if (mode == 0) {
66 if (G_name_is_fully_qualified(name, xname, xmapset)) {
67 if (*mapset && strcmp(xmapset, mapset) != 0) {
68 G_warning(_("G__open(read): mapset <%s> doesn't match xmapset <%s>"),
69 mapset, xmapset);
70 return -1;
71 }
72 name = xname;
73 mapset = xmapset;
74 }
75
76 if (!is_tmp) {
77 mapset = G_find_file2(element, name, mapset);
78
79 if (!mapset)
80 return -1;
81
82 G_file_name(path, element, name, mapset);
83 }
84 else {
86 }
87
88 if ((fd = open(path, 0)) < 0)
89 G_warning(_("G__open(read): Unable to open '%s': %s"),
90 path, strerror(errno));
91 return fd;
92 }
93 /* WRITE */
94 if (mode == 1 || mode == 2) {
95 mapset = G_mapset();
96 if (G_name_is_fully_qualified(name, xname, xmapset)) {
97 if (strcmp(xmapset, mapset) != 0) {
98 G_warning(_("G__open(write): xmapset <%s> != G_mapset() <%s>"),
99 xmapset, mapset);
100 return -1;
101 }
102 name = xname;
103 }
104
105 if (*name && G_legal_filename(name) == -1)
106 return -1;
107
108 if (!is_tmp)
109 G_file_name(path, element, name, mapset);
110 else
111 G_file_name_tmp(path, element, name, mapset);
112
113 if (mode == 1 || access(path, 0) != 0) {
114 if (is_tmp)
116 else
118 close(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666));
119 }
120
121 if ((fd = open(path, mode)) < 0)
122 G_warning(_("G__open(write): Unable to open '%s': %s"),
123 path, strerror(errno));
124 return fd;
125 }
126 return -1;
127}
128
129/*!
130 \brief Open a new database file
131
132 Creates <i>name</i> in the current mapset and opens it
133 for write only.
134
135 The database file <i>name</i> under the <i>element</i> in the
136 current mapset is created and opened for writing (but not reading).
137 The UNIX open() routine is used to open the file. If the file does
138 not exist, -1 is returned. Otherwise the file is positioned at the
139 end of the file and the file descriptor from the open() is returned.
140
141 \param element database element name
142 \param name map file name
143
144 \return open file descriptor (int)
145 \return -1 could not open
146*/
147
148int G_open_new(const char *element, const char *name)
149{
150 return G__open(element, name, G_mapset(), 1);
151}
152
153
154/*!
155 \brief Open a database file for reading
156
157 The database file <i>name</i> under the <i>element</i> in the
158 specified <i>mapset</i> is opened for reading (but not for writing).
159 The UNIX open() routine is used to open the file. If the file does
160 not exist, -1 is returned. Otherwise the file descriptor from the
161 open() is returned.
162
163 \param element database element name
164 \param name map file name
165 \param mapset mapset containing map <i>name</i>
166
167 \return open file descriptor (int)
168 \return -1 could not open
169*/
170int G_open_old(const char *element, const char *name, const char *mapset)
171{
172 return G__open(element, name, mapset, 0);
173}
174
175/*!
176 \brief Open a database file for update
177
178 The database file <i>name</i> under the <i>element</i> in the
179 current mapset is opened for reading and writing. The UNIX open()
180 routine is used to open the file. If the file does not exist, -1 is
181 returned. Otherwise the file is positioned at the end of the file
182 and the file descriptor from the open() is returned.
183
184 \param element database element name
185 \param name map file name
186
187 \return open file descriptor (int)
188 \return -1 could not open
189 */
190
191int G_open_update(const char *element, const char *name)
192{
193 int fd;
194
195 fd = G__open(element, name, G_mapset(), 2);
196 if (fd >= 0)
197 lseek(fd, 0L, SEEK_END);
198
199 return fd;
200}
201
202
203/*!
204 \brief Open a new database file
205
206 The database file <i>name</i> under the <i>element</i> in the
207 current mapset is created and opened for writing (but not reading).
208 The UNIX fopen() routine, with "w" write mode, is used to open the
209 file. If the file does not exist, the NULL pointer is
210 returned. Otherwise the file is positioned at the end of the file
211 and the file descriptor from the fopen() is returned.
212
213 \param element database element name
214 \param name map file name
215
216 \return open file descriptor (FILE *)
217 \return NULL on error
218 */
219
220FILE *G_fopen_new(const char *element, const char *name)
221{
222 int fd;
223
224 fd = G__open(element, name, G_mapset(), 1);
225 if (fd < 0) {
226 G_debug(1, "G_fopen_new(): element = %s, name = %s : NULL",
227 element, name);
228 return (FILE *) 0;
229 }
230
231 G_debug(2, "\tfile open: new (mode = w)");
232 return fdopen(fd, "w");
233}
234
235
236/*!
237 \brief Open a database file for reading
238
239 The database file <i>name</i> under the <i>element</i> in the
240 specified <i>mapset</i> is opened for reading (but not for writing).
241 The UNIX fopen() routine, with "r" read mode, is used to open the
242 file. If the file does not exist, the NULL pointer is
243 returned. Otherwise the file descriptor from the fopen() is
244 returned.
245
246 \param element database element name
247 \param name map file name
248 \param mapset mapset name containing map <i>name</i>
249
250 \return open file descriptor (FILE *)
251 \return NULL on error
252*/
253FILE *G_fopen_old(const char *element, const char *name, const char *mapset)
254{
255 int fd;
256
257 fd = G__open(element, name, mapset, 0);
258 if (fd < 0)
259 return (FILE *) NULL;
260
261 G_debug(2, "\tfile open: read (mode = r)");
262 return fdopen(fd, "r");
263}
264
265/*!
266 \brief Open a database file for update (append mode)
267
268 The database file <i>name</i> under the <i>element</i> in the
269 current mapset is opened for for writing. The UNIX fopen() routine,
270 with "a" append mode, is used to open the file. If the file does not
271 exist, the NULL pointer is returned. Otherwise the file descriptor
272 from the fopen() is returned.
273
274 \param element database element name
275 \param name map file name
276
277 \return open file descriptor (FILE *)
278 \return NULL on error
279*/
280FILE *G_fopen_append(const char *element, const char *name)
281{
282 int fd;
283
284 fd = G__open(element, name, G_mapset(), 2);
285 if (fd < 0)
286 return (FILE *) 0;
287 lseek(fd, 0L, SEEK_END);
288
289 G_debug(2, "\tfile open: append (mode = a)");
290 return fdopen(fd, "a");
291}
292
293/*!
294 \brief Open a database file for update (r+ mode)
295
296 The database file <i>name</i> under the <i>element</i> in the
297 current mapset is opened for for writing. The UNIX fopen() routine,
298 with "r+" append mode, is used to open the file. If the file does not
299 exist, the NULL pointer is returned. Otherwise the file descriptor
300 from the fopen() is returned.
301
302 \param element database element name
303 \param name map file name
304
305 \return open file descriptor (FILE *)
306 \return NULL on error
307*/
308FILE *G_fopen_modify(const char *element, const char *name)
309{
310 int fd;
311
312 fd = G__open(element, name, G_mapset(), 2);
313 if (fd < 0)
314 return (FILE *) 0;
315 lseek(fd, 0L, SEEK_END);
316
317 G_debug(2, "\tfile open: modify (mode = r+)");
318 return fdopen(fd, "r+");
319}
#define NULL
Definition: ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
char * G_file_name(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files.
Definition: file_name.c:61
char * G_file_name_tmp(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files in temporary directory (for internal use only)
Definition: file_name.c:126
const char * G_find_file2(const char *element, const char *name, const char *mapset)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition: find_file.c:249
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
FILE * G_fopen_append(const char *element, const char *name)
Open a database file for update (append mode)
Definition: gis/open.c:280
int G_open_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:148
int G_open_update(const char *element, const char *name)
Open a database file for update.
Definition: gis/open.c:191
FILE * G_fopen_modify(const char *element, const char *name)
Open a database file for update (r+ mode)
Definition: gis/open.c:308
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:253
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:220
int G_open_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:170
void G__check_gisinit(void)
Checks to see if GIS engine is initialized.
Definition: gisinit.c:100
int G_legal_filename(const char *s)
Check for legal database file name.
Definition: legal_name.c:34
const char * G_mapset(void)
Get current mapset name.
Definition: mapset.c:33
int G_make_mapset_object_group_tmp(const char *type)
Create directory for type of objects in the temporary directory.
Definition: mapset_msc.c:153
int G_make_mapset_object_group(const char *type)
Create directory for group of elements of a given type.
Definition: mapset_msc.c:74
const char * name
Definition: named_colr.c:7
int G_name_is_fully_qualified(const char *fullname, char *name, char *mapset)
Check if map name is fully qualified (map @ mapset)
Definition: nme_in_mps.c:36
Definition: lidar.h:87
Definition: path.h:16