Loading...
Searching...
No Matches
gis/open.c
Go to the documentation of this file.
/*!
* \file lib/gis/open.c
*
* \brief GIS Library - Open file functions
*
* (C) 1999-2015 by the GRASS Development Team
*
* This program is free software under the GNU General Public
* License (>=v2). Read the file COPYING that comes with GRASS
* for details.
*
* \author USACERL and many others
*/
#include <grass/config.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <grass/gis.h>
#include <grass/glocale.h>
#include "gis_local_proto.h"
/*!
\brief Lowest level open routine.
Opens the file <i>name</i> in <i>element</i> ("cell", etc.) in mapset
<i>mapset</i> according to the i/o <i>mode</i>.
- mode = 0 (read) will look for <i>name</i> in <i>mapset</i> and
open the file for read only the file must exist
- mode = 1 (write) will create an empty file <i>name</i> in the
current mapset and open the file for write only
<i>mapset</i> ignored
- mode = 2 (read and write) will open a file in the current mapset
for reading and writing creating a new file if
necessary <i>mapset</i> ignored
\param element database element name
\param name map file name
\param mapset mapset containing map <i>name</i>
\param mode r/w mode 0=read, 1=write, 2=read/write
\return open file descriptor (int)
\return -1 could not open
*/
static int G__open(const char *element, const char *name, const char *mapset,
int mode)
{
int fd;
int is_tmp;
char path[GPATH_MAX];
char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
G__check_gisinit();
is_tmp = (element && strncmp(element, ".tmp", 4) == 0);
/* READ */
if (mode == 0) {
if (G_name_is_fully_qualified(name, xname, xmapset)) {
if (*mapset && strcmp(xmapset, mapset) != 0) {
G_warning(
_("G__open(read): mapset <%s> doesn't match xmapset <%s>"),
mapset, xmapset);
return -1;
}
name = xname;
mapset = xmapset;
}
if (!is_tmp) {
mapset = G_find_file2(element, name, mapset);
if (!mapset)
return -1;
G_file_name(path, element, name, mapset);
}
else {
G_file_name_tmp(path, element, name, mapset);
}
if ((fd = open(path, 0)) < 0)
G_warning(_("G__open(read): Unable to open '%s': %s"), path,
strerror(errno));
return fd;
}
/* WRITE */
if (mode == 1 || mode == 2) {
mapset = G_mapset();
if (G_name_is_fully_qualified(name, xname, xmapset)) {
if (strcmp(xmapset, mapset) != 0) {
G_warning(_("G__open(write): xmapset <%s> != G_mapset() <%s>"),
xmapset, mapset);
return -1;
}
name = xname;
}
if (*name && G_legal_filename(name) == -1)
return -1;
if (!is_tmp)
G_file_name(path, element, name, mapset);
else
G_file_name_tmp(path, element, name, mapset);
if (mode == 1 || access(path, 0) != 0) {
if (is_tmp)
G_make_mapset_object_group_tmp(element);
else
G_make_mapset_object_group(element);
close(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666));
}
if ((fd = open(path, mode)) < 0)
G_warning(_("G__open(write): Unable to open '%s': %s"), path,
strerror(errno));
return fd;
}
return -1;
}
/*!
\brief Open a new database file
Creates <i>name</i> in the current mapset and opens it
for write only.
The database file <i>name</i> under the <i>element</i> in the
current mapset is created and opened for writing (but not reading).
The UNIX open() routine is used to open the file. If the file does
not exist, -1 is returned. Otherwise the file is positioned at the
end of the file and the file descriptor from the open() is returned.
\param element database element name
\param name map file name
\return open file descriptor (int)
\return -1 could not open
*/
int G_open_new(const char *element, const char *name)
{
return G__open(element, name, G_mapset(), 1);
}
/*!
\brief Open a database file for reading
The database file <i>name</i> under the <i>element</i> in the
specified <i>mapset</i> is opened for reading (but not for writing).
The UNIX open() routine is used to open the file. If the file does
not exist, -1 is returned. Otherwise the file descriptor from the
open() is returned.
\param element database element name
\param name map file name
\param mapset mapset containing map <i>name</i>
\return open file descriptor (int)
\return -1 could not open
*/
int G_open_old(const char *element, const char *name, const char *mapset)
{
return G__open(element, name, mapset, 0);
}
/*!
\brief Open a database file for update
The database file <i>name</i> under the <i>element</i> in the
current mapset is opened for reading and writing. The UNIX open()
routine is used to open the file. If the file does not exist, -1 is
returned. Otherwise the file is positioned at the end of the file
and the file descriptor from the open() is returned.
\param element database element name
\param name map file name
\return open file descriptor (int)
\return -1 could not open
*/
int G_open_update(const char *element, const char *name)
{
int fd;
fd = G__open(element, name, G_mapset(), 2);
if (fd >= 0)
if (lseek(fd, 0L, SEEK_END) == -1) {
int err = errno;
G_warning(_("File read/write operation failed: %s (%d)"),
strerror(err), err);
return -1;
}
return fd;
}
/*!
\brief Open a new database file
The database file <i>name</i> under the <i>element</i> in the
current mapset is created and opened for writing (but not reading).
The UNIX fopen() routine, with "w" write mode, is used to open the
file. If the file does not exist, the NULL pointer is
returned. Otherwise the file is positioned at the end of the file
and the file descriptor from the fopen() is returned.
\param element database element name
\param name map file name
\return open file descriptor (FILE *)
\return NULL on error
*/
FILE *G_fopen_new(const char *element, const char *name)
{
int fd;
fd = G__open(element, name, G_mapset(), 1);
if (fd < 0) {
G_debug(1, "G_fopen_new(): element = %s, name = %s : NULL", element,
name);
return (FILE *)0;
}
G_debug(2, "\tfile open: new (mode = w)");
return fdopen(fd, "w");
}
/*!
\brief Open a database file for reading
The database file <i>name</i> under the <i>element</i> in the
specified <i>mapset</i> is opened for reading (but not for writing).
The UNIX fopen() routine, with "r" read mode, is used to open the
file. If the file does not exist, the NULL pointer is
returned. Otherwise the file descriptor from the fopen() is
returned.
\param element database element name
\param name map file name
\param mapset mapset name containing map <i>name</i>
\return open file descriptor (FILE *)
\return NULL on error
*/
FILE *G_fopen_old(const char *element, const char *name, const char *mapset)
{
int fd;
fd = G__open(element, name, mapset, 0);
if (fd < 0)
return (FILE *)NULL;
G_debug(2, "\tfile open: read (mode = r)");
return fdopen(fd, "r");
}
/*!
\brief Open a database file for update (append mode)
The database file <i>name</i> under the <i>element</i> in the
current mapset is opened for for writing. The UNIX fopen() routine,
with "a" append mode, is used to open the file. If the file does not
exist, the NULL pointer is returned. Otherwise the file descriptor
from the fopen() is returned.
\param element database element name
\param name map file name
\return open file descriptor (FILE *)
\return NULL on error
*/
FILE *G_fopen_append(const char *element, const char *name)
{
int fd;
fd = G__open(element, name, G_mapset(), 2);
if (fd < 0)
return (FILE *)0;
if (lseek(fd, 0L, SEEK_END) == -1) {
int err = errno;
G_warning(_("File read/write operation failed: %s (%d)"), strerror(err),
err);
return NULL;
}
G_debug(2, "\tfile open: append (mode = a)");
return fdopen(fd, "a");
}
/*!
\brief Open a database file for update (r+ mode)
The database file <i>name</i> under the <i>element</i> in the
current mapset is opened for for writing. The UNIX fopen() routine,
with "r+" append mode, is used to open the file. If the file does not
exist, the NULL pointer is returned. Otherwise the file descriptor
from the fopen() is returned.
\param element database element name
\param name map file name
\return open file descriptor (FILE *)
\return NULL on error
*/
FILE *G_fopen_modify(const char *element, const char *name)
{
int fd;
fd = G__open(element, name, G_mapset(), 2);
if (fd < 0)
return (FILE *)0;
if (lseek(fd, 0L, SEEK_END) == -1) {
int err = errno;
G_warning(_("File read/write operation failed: %s (%d)"), strerror(err),
err);
return NULL;
}
G_debug(2, "\tfile open: modify (mode = r+)");
return fdopen(fd, "r+");
}
NULL
#define NULL
Definition ccmath.h:32
G_debug
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
G_file_name
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
G_file_name_tmp
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
G_find_file2
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
G_warning
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
G_fopen_append
FILE * G_fopen_append(const char *element, const char *name)
Open a database file for update (append mode).
Definition gis/open.c:280
G_open_new
int G_open_new(const char *element, const char *name)
Open a new database file.
Definition gis/open.c:148
G_open_update
int G_open_update(const char *element, const char *name)
Open a database file for update.
Definition gis/open.c:189
G_fopen_modify
FILE * G_fopen_modify(const char *element, const char *name)
Open a database file for update (r+ mode).
Definition gis/open.c:313
G_fopen_old
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition gis/open.c:253
G_fopen_new
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition gis/open.c:221
G_open_old
int G_open_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition gis/open.c:169
G__check_gisinit
void G__check_gisinit(void)
Checks to see if GIS engine is initialized.
Definition gisinit.c:148
G_legal_filename
int G_legal_filename(const char *s)
Check for legal database file name.
Definition legal_name.c:34
G_mapset
const char * G_mapset(void)
Get current mapset name.
Definition mapset.c:33
G_make_mapset_object_group_tmp
int G_make_mapset_object_group_tmp(const char *type)
Create directory for type of objects in the temporary directory.
Definition mapset_msc.c:154
G_make_mapset_object_group
int G_make_mapset_object_group(const char *type)
Create directory for group of elements of a given type.
Definition mapset_msc.c:75
name
const char * name
Definition named_colr.c:6
G_name_is_fully_qualified
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
element
Definition lidar.h:85
path
Definition path.h:15
err
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition symbol/read.c:216