|
@@ -20,6 +20,8 @@
|
|
|
#include <grass/glocale.h>
|
|
|
|
|
|
static int make_mapset_element(const char *, const char *);
|
|
|
+static int make_mapset_element_no_fail_on_race(const char *, const char *);
|
|
|
+static int make_mapset_element_impl(const char *, const char *, bool);
|
|
|
|
|
|
/*!
|
|
|
\brief Create element in the current mapset.
|
|
@@ -29,7 +31,11 @@ static int make_mapset_element(const char *, const char *);
|
|
|
routine can be called even if the element already exists.
|
|
|
|
|
|
Calls G_fatal_error() on failure.
|
|
|
-
|
|
|
+
|
|
|
+ \deprecated
|
|
|
+ This function is deprecated due to confusion in element terminology.
|
|
|
+ Use G_make_mapset_object_group() or G_make_mapset_dir_object() instead.
|
|
|
+
|
|
|
\param p_element element to be created in mapset
|
|
|
|
|
|
\return 0 no element defined
|
|
@@ -44,11 +50,80 @@ int G_make_mapset_element(const char *p_element)
|
|
|
}
|
|
|
|
|
|
/*!
|
|
|
+ \brief Create directory for group of elements of a given type.
|
|
|
+
|
|
|
+ Creates the specified element directory in the current mapset.
|
|
|
+ It will check for the existence of the element and do nothing
|
|
|
+ if it is found so this routine can be called even if the element
|
|
|
+ already exists to ensure that it exists.
|
|
|
+
|
|
|
+ If creation fails, but the directory exists after the failure,
|
|
|
+ the function reports success. Therefore, two processes creating
|
|
|
+ a directory in this way can work in parallel.
|
|
|
+
|
|
|
+ Calls G_fatal_error() on failure.
|
|
|
+
|
|
|
+ \param type object type (e.g., `cell`)
|
|
|
+
|
|
|
+ \return 0 no element defined
|
|
|
+ \return 1 on success
|
|
|
+
|
|
|
+ \sa G_make_mapset_dir_object()
|
|
|
+ \sa G_make_mapset_object_group_tmp()
|
|
|
+ */
|
|
|
+int G_make_mapset_object_group(const char *type)
|
|
|
+{
|
|
|
+ char path[GPATH_MAX];
|
|
|
+
|
|
|
+ G_file_name(path, NULL, NULL, G_mapset());
|
|
|
+ return make_mapset_element_no_fail_on_race(path, type);
|
|
|
+}
|
|
|
+
|
|
|
+/*!
|
|
|
+ \brief Create directory for an object of a given type.
|
|
|
+
|
|
|
+ Creates the specified element directory in the current mapset.
|
|
|
+ It will check for the existence of the element and do nothing
|
|
|
+ if it is found so this routine can be called even if the element
|
|
|
+ already exists to ensure that it exists.
|
|
|
+
|
|
|
+ Any failure to create it, including the case when it exists
|
|
|
+ (i.e., was created by another process after the existence test)
|
|
|
+ is considered a failure because two processes should not attempt
|
|
|
+ to create two objects of the same name (and type).
|
|
|
+
|
|
|
+ This function is for objects which are directories
|
|
|
+ (the function does not create files).
|
|
|
+
|
|
|
+ Calls G_fatal_error() on failure.
|
|
|
+
|
|
|
+ \param type object type (e.g., `vector`)
|
|
|
+ \param name object name (e.g., `bridges`)
|
|
|
+
|
|
|
+ \return 0 no element defined
|
|
|
+ \return 1 on success
|
|
|
+
|
|
|
+ \sa G_make_mapset_object_group()
|
|
|
+ */
|
|
|
+int G_make_mapset_dir_object(const char *type, const char *name)
|
|
|
+{
|
|
|
+ char path[GPATH_MAX];
|
|
|
+
|
|
|
+ G_make_mapset_object_group(type);
|
|
|
+ G_file_name(path, type, NULL, G_mapset());
|
|
|
+ return make_mapset_element(path, name);
|
|
|
+}
|
|
|
+
|
|
|
+/*!
|
|
|
\brief Create element in the temporary directory.
|
|
|
|
|
|
See G_file_name_tmp() for details.
|
|
|
|
|
|
- \param p_element element to be created in mapset
|
|
|
+ \param p_element element to be created in mapset (e.g., `elevation`)
|
|
|
+
|
|
|
+ \note
|
|
|
+ Use G_make_mapset_object_group_tmp() for creating common, shared
|
|
|
+ directories which are for multiple concrete elements (objects).
|
|
|
|
|
|
\return 0 no element defined
|
|
|
\return 1 on success
|
|
@@ -61,7 +136,29 @@ int G_make_mapset_element_tmp(const char *p_element)
|
|
|
return make_mapset_element(path, p_element);
|
|
|
}
|
|
|
|
|
|
-int make_mapset_element(const char *p_path, const char *p_element)
|
|
|
+/*!
|
|
|
+ \brief Create directory for type of objects in the temporary directory.
|
|
|
+
|
|
|
+ See G_file_name_tmp() for details.
|
|
|
+
|
|
|
+ \param type object type (e.g., `cell`)
|
|
|
+
|
|
|
+ \note
|
|
|
+ Use G_make_mapset_object_group_tmp() for creating common, shared
|
|
|
+ directories which are for multiple concrete elements (objects).
|
|
|
+
|
|
|
+ \return 0 no element defined
|
|
|
+ \return 1 on success
|
|
|
+ */
|
|
|
+int G_make_mapset_object_group_tmp(const char *type)
|
|
|
+{
|
|
|
+ char path[GPATH_MAX];
|
|
|
+
|
|
|
+ G_file_name_tmp(path, NULL, NULL, G_mapset());
|
|
|
+ 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;
|
|
|
const char *element;
|
|
@@ -85,14 +182,26 @@ int make_mapset_element(const char *p_path, const char *p_element)
|
|
|
while (1) {
|
|
|
if (*element == '/' || *element == 0) {
|
|
|
*p = 0;
|
|
|
- if (access(path, 0) != 0) { /* directory not yet created */
|
|
|
- if (G_mkdir(path) != 0)
|
|
|
- G_fatal_error(_("Unable to make mapset element %s (%s): %s"),
|
|
|
- p_element, path, strerror(errno));
|
|
|
- }
|
|
|
- if (access(path, 0) != 0) /* directory not accessible */
|
|
|
- G_fatal_error(_("Unable to access mapset element %s (%s): %s"),
|
|
|
- p_element, path, strerror(errno));
|
|
|
+ char *msg = NULL;
|
|
|
+ if (access(path, 0) != 0) {
|
|
|
+ /* Assuming that directory does not exist. */
|
|
|
+ if (G_mkdir(path) != 0) {
|
|
|
+ msg = G_store(strerror(errno));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (access(path, 0) != 0 || (msg && !race_ok)) {
|
|
|
+ /* Directory is not accessible even after attempt to create it. */
|
|
|
+ if (msg) {
|
|
|
+ /* Error already happened when mkdir. */
|
|
|
+ G_fatal_error(_("Unable to make mapset element %s (%s): %s"),
|
|
|
+ p_element, path, strerror(errno));
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Access error is not related to mkdir. */
|
|
|
+ G_fatal_error(_("Unable to access mapset element %s (%s): %s"),
|
|
|
+ p_element, path, strerror(errno));
|
|
|
+ }
|
|
|
+ }
|
|
|
if (*element == 0)
|
|
|
return 1;
|
|
|
}
|
|
@@ -100,21 +209,29 @@ int make_mapset_element(const char *p_path, const char *p_element)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+int make_mapset_element(const char *p_path, const char *p_element)
|
|
|
+{
|
|
|
+ return make_mapset_element_impl(p_path, p_element, false);
|
|
|
+}
|
|
|
+
|
|
|
+int make_mapset_element_no_fail_on_race(const char *p_path, const char *p_element)
|
|
|
+{
|
|
|
+ return make_mapset_element_impl(p_path, p_element, true);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
/*!
|
|
|
\brief Create misc element in the current mapset.
|
|
|
|
|
|
- \param dir directory path
|
|
|
- \param name element to be created in mapset
|
|
|
+ \param dir directory path (e.g., `cell_misc`)
|
|
|
+ \param name element to be created in mapset (e.g., `elevation`)
|
|
|
|
|
|
\return 0 no element defined
|
|
|
\return 1 on success
|
|
|
*/
|
|
|
int G__make_mapset_element_misc(const char *dir, const char *name)
|
|
|
{
|
|
|
- char buf[GNAME_MAX * 2 + 1];
|
|
|
-
|
|
|
- sprintf(buf, "%s/%s", dir, name);
|
|
|
- return G_make_mapset_element(buf);
|
|
|
+ G_make_mapset_dir_object(dir, name);
|
|
|
}
|
|
|
|
|
|
static int check_owner(const struct stat *info)
|