GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
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];
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) {
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,
91 strerror(errno));
92 return fd;
93 }
94 /* WRITE */
95 if (mode == 1 || mode == 2) {
96 mapset = G_mapset();
97 if (G_name_is_fully_qualified(name, xname, xmapset)) {
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 */
148
149int G_open_new(const char *element, const char *name)
150{
151 return G__open(element, name, G_mapset(), 1);
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 \brief Open a new database file
204
205 The database file <i>name</i> under the <i>element</i> in the
206 current mapset is created and opened for writing (but not reading).
207 The UNIX fopen() routine, with "w" write mode, is used to open the
208 file. If the file does not exist, the NULL pointer is
209 returned. Otherwise the file is positioned at the end of the file
210 and the file descriptor from the fopen() is returned.
211
212 \param element database element name
213 \param name map file name
214
215 \return open file descriptor (FILE *)
216 \return NULL on error
217 */
218
219FILE *G_fopen_new(const char *element, const char *name)
220{
221 int fd;
222
223 fd = G__open(element, name, G_mapset(), 1);
224 if (fd < 0) {
225 G_debug(1, "G_fopen_new(): element = %s, name = %s : NULL", element,
226 name);
227 return (FILE *)0;
228 }
229
230 G_debug(2, "\tfile open: new (mode = w)");
231 return fdopen(fd, "w");
232}
233
234/*!
235 \brief Open a database file for reading
236
237 The database file <i>name</i> under the <i>element</i> in the
238 specified <i>mapset</i> is opened for reading (but not for writing).
239 The UNIX fopen() routine, with "r" read mode, is used to open the
240 file. If the file does not exist, the NULL pointer is
241 returned. Otherwise the file descriptor from the fopen() is
242 returned.
243
244 \param element database element name
245 \param name map file name
246 \param mapset mapset name containing map <i>name</i>
247
248 \return open file descriptor (FILE *)
249 \return NULL on error
250 */
251FILE *G_fopen_old(const char *element, const char *name, const char *mapset)
252{
253 int fd;
254
255 fd = G__open(element, name, mapset, 0);
256 if (fd < 0)
257 return (FILE *)NULL;
258
259 G_debug(2, "\tfile open: read (mode = r)");
260 return fdopen(fd, "r");
261}
262
263/*!
264 \brief Open a database file for update (append mode)
265
266 The database file <i>name</i> under the <i>element</i> in the
267 current mapset is opened for for writing. The UNIX fopen() routine,
268 with "a" append mode, is used to open the file. If the file does not
269 exist, the NULL pointer is returned. Otherwise the file descriptor
270 from the fopen() is returned.
271
272 \param element database element name
273 \param name map file name
274
275 \return open file descriptor (FILE *)
276 \return NULL on error
277 */
278FILE *G_fopen_append(const char *element, const char *name)
279{
280 int fd;
281
282 fd = G__open(element, name, G_mapset(), 2);
283 if (fd < 0)
284 return (FILE *)0;
285 lseek(fd, 0L, SEEK_END);
286
287 G_debug(2, "\tfile open: append (mode = a)");
288 return fdopen(fd, "a");
289}
290
291/*!
292 \brief Open a database file for update (r+ mode)
293
294 The database file <i>name</i> under the <i>element</i> in the
295 current mapset is opened for for writing. The UNIX fopen() routine,
296 with "r+" append mode, is used to open the file. If the file does not
297 exist, the NULL pointer is returned. Otherwise the file descriptor
298 from the fopen() is returned.
299
300 \param element database element name
301 \param name map file name
302
303 \return open file descriptor (FILE *)
304 \return NULL on error
305 */
306FILE *G_fopen_modify(const char *element, const char *name)
307{
308 int fd;
309
310 fd = G__open(element, name, G_mapset(), 2);
311 if (fd < 0)
312 return (FILE *)0;
313 lseek(fd, 0L, SEEK_END);
314
315 G_debug(2, "\tfile open: modify (mode = r+)");
316 return fdopen(fd, "r+");
317}
#define NULL
Definition ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
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:125
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:234
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
FILE * G_fopen_append(const char *element, const char *name)
Open a database file for update (append mode)
Definition gis/open.c:278
int G_open_new(const char *element, const char *name)
Open a new database file.
Definition gis/open.c:149
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:306
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition gis/open.c:251
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition gis/open.c:219
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:131
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:6
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 path.h:15