Skip to content

Commit

Permalink
lib/gis: allow creation of temporary files outside the current mapset (
Browse files Browse the repository at this point in the history
…OSGeo#1786)

* lib/gis: allow creation of temporary files outside the current mapset

Co-authored-by: Tomas Zigo <[email protected]>
  • Loading branch information
metzm and tmszi authored Jul 1, 2022
1 parent da18254 commit c0ff1af
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 9 deletions.
6 changes: 6 additions & 0 deletions include/grass/defs/gis.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ char *G_file_name(char *, const char *, const char *, const char *);
char *G_file_name_misc(char *, const char *, const char *, const char *,
const char *);
char *G_file_name_tmp(char *, const char *, const char *, const char *);
char *G_file_name_basedir(char *, const char *, const char *, const char *,
const char *);

/* find_file.c */
const char *G_find_file(const char *, char *, const char *);
Expand Down Expand Up @@ -546,6 +548,7 @@ int G_make_mapset_element_tmp(const char *);
int G_make_mapset_object_group(const char *);
int G_make_mapset_dir_object(const char *, const char *);
int G_make_mapset_object_group_tmp(const char *);
int G_make_mapset_object_group_basedir(const char *, const char *);
int G__make_mapset_element_misc(const char *, const char *);
int G_mapset_permissions(const char *);
int G_mapset_permissions2(const char *, const char *, const char *);
Expand Down Expand Up @@ -760,9 +763,12 @@ char *G_strcasestr(const char *, const char *);
/* tempfile.c */
void G_init_tempfile(void);
char *G_tempfile(void);
char *G_tempfile_basedir(const char *);
char *G_tempfile_pid(int);
char *G_tempfile_pid_basedir(int, const char *);
void G_temp_element(char *);
void G__temp_element(char *, int);
void G__temp_element_basedir(char *, const char *);

/* mkstemp.c */
char *G_mktemp(char *);
Expand Down
22 changes: 22 additions & 0 deletions lib/gis/file_name.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,28 @@ char *G_file_name_tmp(char *path,
return file_name(path, NULL, element, name, mapset, tmp_path);
}

/*!
\brief Builds full path names to GIS data files in temporary directory (for internal use only)
By default the GRASS temporary directory is located at
$LOCATION/$MAPSET/.tmp/$HOSTNAME/. If basedir is provided, the
temporary directory is located at <basedir>/.tmp/$HOSTNAME/.
\param[out] path buffer to hold resultant full path to file
\param element database element (eg, "cell", "cellhd", "vector", etc)
\param name name of file to build path to (fully qualified names allowed)
\param mapset mapset name
\return pointer to <i>path</i> buffer
*/
char *G_file_name_basedir(char *path,
const char *element,
const char *name, const char *mapset,
const char *basedir)
{
return file_name(path, NULL, element, name, mapset, basedir);
}

char *file_name(char *path,
const char *dir, const char *element, const char *name,
const char *mapset, const char *base)
Expand Down
22 changes: 22 additions & 0 deletions lib/gis/mapset_msc.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,28 @@ int G_make_mapset_object_group_tmp(const char *type)
return make_mapset_element_no_fail_on_race(path, type);
}

/*!
\brief Create directory for type of objects in the temporary directory.
See G_file_name_basedir() for details.
\param type object type (e.g., `cell`)
\note
Use G_make_mapset_object_group_basedir() for creating common, shared
directories for temporary data.
\return 0 no element defined
\return 1 on success
*/
int G_make_mapset_object_group_basedir(const char *type, const char *basedir)
{
char path[GPATH_MAX];

G_file_name_basedir(path, NULL, NULL, G_mapset(), basedir);
return make_mapset_element_no_fail_on_race(path, type);
}

int make_mapset_element_impl(const char *p_path, const char *p_element, bool race_ok)
{
char path[GPATH_MAX], *p;
Expand Down
88 changes: 79 additions & 9 deletions lib/gis/tempfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@ char *G_tempfile(void)
return G_tempfile_pid(getpid());
}

/*!
* \brief Returns a temporary file name.
*
* Similar to G_tempfile(), but the temporary file name will include
* a provided base directory instead of the path to the current mapset.
*
* \return pointer to a character string containing the name. The name
* is copied to allocated memory and may be released by the unix free()
* routine.
*/
char *G_tempfile_basedir(const char *basedir)
{
return G_tempfile_pid_basedir(getpid(), basedir);
}

/*!
* \brief Create tempfile from process id.
*
Expand All @@ -79,18 +94,48 @@ char *G_tempfile_pid(int pid)
char element[100];

if (pid <= 0)
pid = getpid();
pid = getpid();
G_temp_element(element);
G_init_tempfile();
do {
int uniq = G_counter_next(&unique);
sprintf(name, "%d.%d", pid, uniq);
G_file_name(path, element, name, G_mapset());
int uniq = G_counter_next(&unique);
sprintf(name, "%d.%d", pid, uniq);
G_file_name(path, element, name, G_mapset());
}
while (access(path, F_OK) == 0);

G_debug(2, "G_tempfile_pid(): %s", path);


return G_store(path);
}

/*!
* \brief Create tempfile from process id in given base directory.
*
* See G_tempfile_basedir().
*
* \param pid
* \return pointer to string path
*/
char *G_tempfile_pid_basedir(int pid, const char *basedir)
{
char path[GPATH_MAX];
char name[GNAME_MAX];
char element[100];

if (pid <= 0)
pid = getpid();
G__temp_element_basedir(element, basedir);
G_init_tempfile();
do {
int uniq = G_counter_next(&unique);
sprintf(name, "%d.%d", pid, uniq);
G_file_name_basedir(path, element, name, G_mapset(), basedir);
}
while (access(path, F_OK) == 0);

G_debug(2, "G_tempfile_pid(): %s", path);

return G_store(path);
}

Expand All @@ -117,14 +162,39 @@ void G__temp_element(char *element, int tmp)
strcpy(element, ".tmp");
machine = G__machine_name();
if (machine != NULL && *machine != 0) {
strcat(element, "/");
strcat(element, machine);
strcat(element, "/");
strcat(element, machine);
}

if (!tmp)
G_make_mapset_object_group(element);
else
G_make_mapset_object_group_tmp(element);

G_debug(2, "G__temp_element(): %s (tmp=%d)", element, tmp);
}

/*!
* \brief Populates element with a path string (internal use only!)
*
* \param[out] element element name
* \param tmp TRUE to use G_make_mapset_element_tmp() instead of G_make_mapset_element()
*/
void G__temp_element_basedir(char *element, const char *basedir)
{
const char *machine;

strcpy(element, ".tmp");
machine = G__machine_name();
if (machine != NULL && *machine != 0) {
strcat(element, "/");
strcat(element, machine);
}

if (basedir && *basedir)
G_make_mapset_object_group_basedir(element, basedir);
else
G_make_mapset_object_group(element);

G_debug(2, "G__temp_element_basedir(): %s", element);
}

0 comments on commit c0ff1af

Please sign in to comment.