summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@novell.com>2005-06-22 09:43:37 +0000
committerTor Lillqvist <tml@src.gnome.org>2005-06-22 09:43:37 +0000
commit1833a93dddaaa77b11761a92d8961bba67217d94 (patch)
tree4978351be84b47dbf92117585c964f5bc4009b60
parentadb066fa110346c26c5f5392b6489c6285f1cbc1 (diff)
New function. Creates a directory including intermediate parent
2005-06-22 Tor Lillqvist <tml@novell.com> * glib/gfileutils.c (g_makepath): New function. Creates a directory including intermediate parent directories as needed. (#60509) * glib/gfileutils.h: Declare it. * glib/glib.symbols: Add it. * tests/testglib.c: Test it.
-rw-r--r--ChangeLog13
-rw-r--r--ChangeLog.pre-2-1013
-rw-r--r--ChangeLog.pre-2-1213
-rw-r--r--ChangeLog.pre-2-813
-rw-r--r--glib/gfileutils.c72
-rw-r--r--glib/gfileutils.h3
-rw-r--r--glib/glib.symbols1
-rw-r--r--tests/testglib.c118
8 files changed, 233 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 0f7bb905c..19902d7d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,15 +1,22 @@
2005-06-22 Tor Lillqvist <tml@novell.com>
+ * glib/gfileutils.c (g_makepath): New function. Creates a
+ directory including intermediate parent directories as
+ needed. (#60509)
+
+ * glib/gfileutils.h: Declare it.
+
* glib/gutils.c (g_get_host_name): New function. Returns the
machine's name, or one of its names. Document that it is
best-effort only, and not guaranteed to be unique or anything.
(g_get_any_init): Get the host name here. On Unix use
gethostname(), on Windows use GetComputerName(). (#5200)
- * glib/gutils.h
- * glib/glib.symbols: Add here, too.
+ * glib/gutils.h: Declare it.
+
+ * glib/glib.symbols: Add new functions.
- * tests/testglib.c: Test it.
+ * tests/testglib.c: Test g_makepath() and g_get_host_name().
2005-06-18 Matthias Clasen <mclasen@redhat.com>
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 0f7bb905c..19902d7d7 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,15 +1,22 @@
2005-06-22 Tor Lillqvist <tml@novell.com>
+ * glib/gfileutils.c (g_makepath): New function. Creates a
+ directory including intermediate parent directories as
+ needed. (#60509)
+
+ * glib/gfileutils.h: Declare it.
+
* glib/gutils.c (g_get_host_name): New function. Returns the
machine's name, or one of its names. Document that it is
best-effort only, and not guaranteed to be unique or anything.
(g_get_any_init): Get the host name here. On Unix use
gethostname(), on Windows use GetComputerName(). (#5200)
- * glib/gutils.h
- * glib/glib.symbols: Add here, too.
+ * glib/gutils.h: Declare it.
+
+ * glib/glib.symbols: Add new functions.
- * tests/testglib.c: Test it.
+ * tests/testglib.c: Test g_makepath() and g_get_host_name().
2005-06-18 Matthias Clasen <mclasen@redhat.com>
diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12
index 0f7bb905c..19902d7d7 100644
--- a/ChangeLog.pre-2-12
+++ b/ChangeLog.pre-2-12
@@ -1,15 +1,22 @@
2005-06-22 Tor Lillqvist <tml@novell.com>
+ * glib/gfileutils.c (g_makepath): New function. Creates a
+ directory including intermediate parent directories as
+ needed. (#60509)
+
+ * glib/gfileutils.h: Declare it.
+
* glib/gutils.c (g_get_host_name): New function. Returns the
machine's name, or one of its names. Document that it is
best-effort only, and not guaranteed to be unique or anything.
(g_get_any_init): Get the host name here. On Unix use
gethostname(), on Windows use GetComputerName(). (#5200)
- * glib/gutils.h
- * glib/glib.symbols: Add here, too.
+ * glib/gutils.h: Declare it.
+
+ * glib/glib.symbols: Add new functions.
- * tests/testglib.c: Test it.
+ * tests/testglib.c: Test g_makepath() and g_get_host_name().
2005-06-18 Matthias Clasen <mclasen@redhat.com>
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 0f7bb905c..19902d7d7 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,15 +1,22 @@
2005-06-22 Tor Lillqvist <tml@novell.com>
+ * glib/gfileutils.c (g_makepath): New function. Creates a
+ directory including intermediate parent directories as
+ needed. (#60509)
+
+ * glib/gfileutils.h: Declare it.
+
* glib/gutils.c (g_get_host_name): New function. Returns the
machine's name, or one of its names. Document that it is
best-effort only, and not guaranteed to be unique or anything.
(g_get_any_init): Get the host name here. On Unix use
gethostname(), on Windows use GetComputerName(). (#5200)
- * glib/gutils.h
- * glib/glib.symbols: Add here, too.
+ * glib/gutils.h: Declare it.
+
+ * glib/glib.symbols: Add new functions.
- * tests/testglib.c: Test it.
+ * tests/testglib.c: Test g_makepath() and g_get_host_name().
2005-06-18 Matthias Clasen <mclasen@redhat.com>
diff --git a/glib/gfileutils.c b/glib/gfileutils.c
index d0dd3ce53..a236a54ce 100644
--- a/glib/gfileutils.c
+++ b/glib/gfileutils.c
@@ -58,6 +58,78 @@
#include "galias.h"
/**
+ * g_makepath:
+ * @pathname: a pathname in the GLib file name encoding
+ * @mode: permissions to use for newly created directories
+ *
+ * Create a directory if it doesn't already exist. Create intermediate
+ * parent directories as needed, too.
+ *
+ * Returns: 0 if the directoty already exists, or was successfully
+ * created. Returns -1 if an error occurred, with errno set.
+ *
+ * Since: 2.8
+ */
+int
+g_makepath (const gchar *pathname,
+ int mode)
+{
+ gchar *fn, *p;
+
+ if (pathname == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ fn = g_strdup (pathname);
+
+ if (g_path_is_absolute (fn))
+ p = (gchar *) g_path_skip_root (fn);
+ else
+ p = fn;
+
+ do
+ {
+ while (*p && !G_IS_DIR_SEPARATOR (*p))
+ p++;
+
+ if (!*p)
+ p = NULL;
+ else
+ *p = '\0';
+
+ if (!g_file_test (fn, G_FILE_TEST_EXISTS))
+ {
+ if (g_mkdir (fn, mode) == -1)
+ {
+ int errno_save = errno;
+ g_free (fn);
+ errno = errno_save;
+ return -1;
+ }
+ }
+ else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
+ {
+ g_free (fn);
+ errno = ENOTDIR;
+ return -1;
+ }
+ if (p)
+ {
+ *p++ = G_DIR_SEPARATOR;
+ while (*p && G_IS_DIR_SEPARATOR (*p))
+ p++;
+ }
+ }
+ while (p);
+
+ g_free (fn);
+
+ return 0;
+}
+
+/**
* g_file_test:
* @filename: a filename to test in the GLib file name encoding
* @test: bitfield of #GFileTest flags
diff --git a/glib/gfileutils.h b/glib/gfileutils.h
index 7c23cadd3..a43dd8a6c 100644
--- a/glib/gfileutils.h
+++ b/glib/gfileutils.h
@@ -107,6 +107,9 @@ gchar *g_build_path (const gchar *separator,
gchar *g_build_filename (const gchar *first_element,
...) G_GNUC_NULL_TERMINATED;
+int g_makepath (const gchar *pathname,
+ int mode);
+
G_END_DECLS
#endif /* __G_FILEUTILS_H__ */
diff --git a/glib/glib.symbols b/glib/glib.symbols
index b02923098..6dbcc3897 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -260,6 +260,7 @@ g_file_open_tmp PRIVATE
g_file_test PRIVATE
g_file_read_link
g_mkstemp PRIVATE
+g_makepath
#ifdef G_OS_WIN32
g_file_get_contents_utf8
g_file_open_tmp_utf8
diff --git a/tests/testglib.c b/tests/testglib.c
index 00f14cce3..02504088e 100644
--- a/tests/testglib.c
+++ b/tests/testglib.c
@@ -38,6 +38,7 @@
#include <errno.h>
#include "glib.h"
+#include "gstdio.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -318,6 +319,119 @@ find_first_that(gpointer key,
}
+static gboolean
+test_g_makepath_1 (const gchar *base)
+{
+ char *p0 = g_build_filename (base, "fum", NULL);
+ char *p1 = g_build_filename (p0, "tem", NULL);
+ char *p2 = g_build_filename (p1, "zap", NULL);
+ FILE *f;
+
+ g_remove (p2);
+ g_remove (p1);
+ g_remove (p0);
+
+ if (g_file_test (p0, G_FILE_TEST_EXISTS))
+ {
+ g_print ("failed, %s exists, cannot test g_makepath\n", p0);
+ return FALSE;
+ }
+
+ if (g_file_test (p1, G_FILE_TEST_EXISTS))
+ {
+ g_print ("failed, %s exists, cannot test g_makepath\n", p1);
+ return FALSE;
+ }
+
+ if (g_file_test (p2, G_FILE_TEST_EXISTS))
+ {
+ g_print ("failed, %s exists, cannot test g_makepath\n", p2);
+ return FALSE;
+ }
+
+ if (g_makepath (p2, 0666) == -1)
+ {
+ g_print ("failed, g_makepath(%s) failed: %s\n", p2, g_strerror (errno));
+ return FALSE;
+ }
+
+ if (!g_file_test (p2, G_FILE_TEST_IS_DIR))
+ {
+ g_print ("failed, g_makepath(%s) succeeded, but %s is not a directory\n", p2, p2);
+ return FALSE;
+ }
+
+ if (!g_file_test (p1, G_FILE_TEST_IS_DIR))
+ {
+ g_print ("failed, g_makepath(%s) succeeded, but %s is not a directory\n", p2, p1);
+ return FALSE;
+ }
+
+ if (!g_file_test (p0, G_FILE_TEST_IS_DIR))
+ {
+ g_print ("failed, g_makepath(%s) succeeded, but %s is not a directory\n", p2, p0);
+ return FALSE;
+ }
+
+ g_rmdir (p2);
+ if (g_file_test (p2, G_FILE_TEST_EXISTS))
+ {
+ g_print ("failed, did g_rmdir(%s), but %s is still there\n", p2, p2);
+ return FALSE;
+ }
+
+ g_rmdir (p1);
+ if (g_file_test (p1, G_FILE_TEST_EXISTS))
+ {
+ g_print ("failed, did g_rmdir(%s), but %s is still there\n", p1, p1);
+ return FALSE;
+ }
+
+ f = g_fopen (p1, "w");
+ if (f == NULL)
+ {
+ g_print ("failed, couldn't create file %s\n", p1);
+ return FALSE;
+ }
+ fclose (f);
+
+ if (g_makepath (p1, 0666) == 0)
+ {
+ g_print ("failed, g_makepath(%s) succeeded, even if %s is a file\n", p1, p1);
+ return FALSE;
+ }
+
+ if (g_makepath (p2, 0666) == 0)
+ {
+ g_print ("failed, g_makepath(%s) succeeded, even if %s is a file\n", p2, p1);
+ return FALSE;
+ }
+
+ g_remove (p2);
+ g_remove (p1);
+ g_remove (p0);
+
+ return TRUE;
+}
+
+static gboolean
+test_g_makepath (void)
+{
+ g_print ("checking g_makepath()...");
+ if (!test_g_makepath_1 ("hum"))
+ return FALSE;
+ g_remove ("hum");
+ if (!test_g_makepath_1 ("hii///haa/hee"))
+ return FALSE;
+ g_remove ("hii/haa/hee");
+ g_remove ("hii/haa");
+ g_remove ("hii");
+ if (!test_g_makepath_1 (g_get_current_dir ()))
+ return FALSE;
+
+ return TRUE;
+}
+
int
main (int argc,
char *argv[])
@@ -482,7 +596,6 @@ main (int argc,
string = g_path_get_basename ("/foo/file");
g_assert (strcmp (string, "file") == 0);
g_free (string);
- g_print ("ok\n");
#endif
g_print ("checking g_path_get_dirname()...");
@@ -526,6 +639,9 @@ main (int argc,
if (n_skip_root_checks)
g_print ("ok\n");
+ if (test_g_makepath ())
+ g_print ("ok\n");
+
g_print ("checking doubly linked lists...");
list = NULL;