GRASS 8 Programmer's Manual 8.6.0dev(2026)-56a9afeb9f
Loading...
Searching...
No Matches
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
31 <i>mapset</i> 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, const char *name, const char *mapset,
53 int mode)
54{
55 int fd;
56 int is_tmp;
57 char path[GPATH_MAX];
59
61
62 is_tmp = (element && strncmp(element, ".tmp", 4) == 0);
63
64 /* READ */
65 if (mode == 0) {
67 if (*mapset && strcmp(xmapset, mapset) != 0) {
69 _("G__open(read): mapset <%s> doesn't match xmapset <%s>"),
70 mapset, xmapset);
71 return -1;
72 }
73 name = xname;
74 mapset = xmapset;
75 }
76
77 if (!is_tmp) {
78 mapset = G_find_file2(element, name, mapset);
79
80 if (!mapset)
81 return -1;
82
83 G_file_name(path, element, name, mapset);
84 }
85 else {
87 }
88
89 if ((fd = open(path, 0)) < 0)
90 G_warning(_("G__open(read): Unable to open '%s': %s"), path,
92 return fd;
93 }
94 /* WRITE */
95 if (mode == 1 || mode == 2) {
96 mapset = G_mapset();
98 if (strcmp(xmapset, mapset) != 0) {
99 G_warning(_("G__open(write): xmapset <%s> != G_mapset() <%s>"),
100 xmapset, mapset);
101 return -1;
102 }
103 name = xname;
104 }
105
106 if (*name && G_legal_filename(name) == -1)
107 return -1;
108
109 if (!is_tmp)
110 G_file_name(path, element, name, mapset);
111 else
112 G_file_name_tmp(path, element, name, mapset);
113
114 if (mode == 1 || access(path, 0) != 0) {
115 if (is_tmp)
117 else
119 close(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666));
120 }
121
122 if ((fd = open(path, mode)) < 0)
123 G_warning(_("G__open(write): Unable to open '%s': %s"), path,
124 strerror(errno));
125 return fd;
126 }
127 return -1;
128}
129
130/*!
131 \brief Open a new database file
132
133 Creates <i>name</i> in the current mapset and opens it
134 for write only.
135
136 The database file <i>name</i> under the <i>element</i> in the
137 current mapset is created and opened for writing (but not reading).
138 The UNIX open() routine is used to open the file. If the file does
139 not exist, -1 is returned. Otherwise the file is positioned at the
140 end of the file and the file descriptor from the open() is returned.
141
142 \param element database element name
143 \param name map file name
144
145 \return open file descriptor (int)
146 \return -1 could not open
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 \brief Open a database file for reading
155
156 The database file <i>name</i> under the <i>element</i> in the
157 specified <i>mapset</i> is opened for reading (but not for writing).
158 The UNIX open() routine is used to open the file. If the file does
159 not exist, -1 is returned. Otherwise the file descriptor from the
160 open() is returned.
161
162 \param element database element name
163 \param name map file name
164 \param mapset mapset containing map <i>name</i>
165
166 \return open file descriptor (int)
167 \return -1 could not open
168 */
169int G_open_old(const char *element, const char *name, const char *mapset)
170{
171 return G__open(element, name, mapset, 0);
172}
173
174/*!
175 \brief Open a database file for update
176
177 The database file <i>name</i> under the <i>element</i> in the
178 current mapset is opened for reading and writing. The UNIX open()
179 routine is used to open the file. If the file does not exist, -1 is
180 returned. Otherwise the file is positioned at the end of the file
181 and the file descriptor from the open() is returned.
182
183 \param element database element name
184 \param name map file name
185
186 \return open file descriptor (int)
187 \return -1 could not open
188 */
189int G_open_update(const char *element, const char *name)
190{
191 int fd;
192
193 fd = G__open(element, name, G_mapset(), 2);
194 if (fd >= 0)
195 if (lseek(fd, 0L, SEEK_END) == -1) {
196 int err = errno;
197 G_warning(_("File read/write operation failed: %s (%d)"),
198 strerror(err), err);
199 return -1;
200 }
201
202 return fd;
203}
204
205/*!
206 \brief Open a new database file
207
208 The database file <i>name</i> under the <i>element</i> in the
209 current mapset is created and opened for writing (but not reading).
210 The UNIX fopen() routine, with "w" write mode, is used to open the
211 file. If the file does not exist, the NULL pointer is
212 returned. Otherwise the file is positioned at the end of the file
213 and the file descriptor from the fopen() is returned.
214
215 \param element database element name
216 \param name map file name
217
218 \return open file descriptor (FILE *)
219 \return NULL on error
220 */
221FILE *G_fopen_new(const char *element, const char *name)
222{
223 int fd;
224
225 fd = G__open(element, name, G_mapset(), 1);
226 if (fd < 0) {
227 G_debug(1, "G_fopen_new(): element = %s, name = %s : NULL", element,
228 name);
229 return (FILE *)0;
230 }
231
232 G_debug(2, "\tfile open: new (mode = w)");
233 return fdopen(fd, "w");
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 if (lseek(fd, 0L, SEEK_END) == -1) {
288 int err = errno;
289 G_warning(_("File read/write operation failed: %s (%d)"), strerror(err),
290 err);
291 return NULL;
292 }
293
294 G_debug(2, "\tfile open: append (mode = a)");
295 return fdopen(fd, "a");
296}
297
298/*!
299 \brief Open a database file for update (r+ mode)
300
301 The database file <i>name</i> under the <i>element</i> in the
302 current mapset is opened for for writing. The UNIX fopen() routine,
303 with "r+" append mode, is used to open the file. If the file does not
304 exist, the NULL pointer is returned. Otherwise the file descriptor
305 from the fopen() is returned.
306
307 \param element database element name
308 \param name map file name
309
310 \return open file descriptor (FILE *)
311 \return NULL on error
312 */
313FILE *G_fopen_modify(const char *element, const char *name)
314{
315 int fd;
316
317 fd = G__open(element, name, G_mapset(), 2);
318 if (fd < 0)
319 return (FILE *)0;
320 if (lseek(fd, 0L, SEEK_END) == -1) {
321 int err = errno;
322 G_warning(_("File read/write operation failed: %s (%d)"), strerror(err),
323 err);
324 return NULL;
325 }
326
327 G_debug(2, "\tfile open: modify (mode = r+)");
328 return fdopen(fd, "r+");
329}
#define NULL
Definition ccmath.h:32
int G_name_is_fully_qualified(const char *, char *, char *)
Check if map name is fully qualified (map @ mapset)
Definition nme_in_mps.c:36
void G_warning(const char *,...) __attribute__((format(printf
int G_legal_filename(const char *)
Check for legal database file name.
Definition legal_name.c:34
int G_make_mapset_object_group(const char *)
Create directory for group of elements of a given type.
Definition mapset_msc.c:75
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition file_name.c:61
const char * G_find_file2(const char *, const char *, const char *)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:234
int G_make_mapset_object_group_tmp(const char *)
Create directory for type of objects in the temporary directory.
Definition mapset_msc.c:154
char * G_file_name_tmp(char *, const char *, const char *, const char *)
Builds full path names to GIS data files in temporary directory (for internal use only)
Definition file_name.c:125
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:33
Header file for msvc/fcntl.c.
#define open
Definition fcntl.h:33
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:189
FILE * G_fopen_modify(const char *element, const char *name)
Open a database file for update (r+ mode)
Definition gis/open.c:313
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:221
int G_open_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition gis/open.c:169
#define GMAPSET_MAX
Definition gis.h:197
#define GPATH_MAX
Definition gis.h:199
#define GNAME_MAX
Definition gis.h:196
void G__check_gisinit(void)
Checks to see if GIS engine is initialized.
Definition gisinit.c:148
#define _(str)
Definition glocale.h:10
const char * name
Definition named_colr.c:6
#define fdopen
Definition stdio.h:6
Definition path.h:15
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
#define access
Definition unistd.h:7
#define close
Definition unistd.h:8