move batch directory creation to ecore_file.
authorbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 11 Apr 2009 07:10:12 +0000 (07:10 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 11 Apr 2009 07:10:12 +0000 (07:10 +0000)
as suggested by raster, this could be abstracted into ecore-file and
other applications could use it as well.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@39965 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

configure.ac
src/lib/ecore_file/Ecore_File.h
src/lib/ecore_file/ecore_file.c

index a8e84d2..7a55f0b 100644 (file)
@@ -11,6 +11,7 @@ AC_ISC_POSIX
 
 AM_INIT_AUTOMAKE(1.6 dist-bzip2)
 AM_CONFIG_HEADER(config.h)
+AC_GNU_SOURCE
 
 AC_LIBTOOL_WIN32_DLL
 define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
@@ -669,6 +670,25 @@ AC_SUBST(lt_enable_auto_import)
 AC_FUNC_ALLOCA
 AC_CHECK_FUNCS(gettimeofday strlcpy)
 
+have_atfile_source=auto
+AC_ARG_ENABLE(atfile-source,
+        AC_HELP_STRING([--disable-atfile-source],
+                       [disable use of atfile source functions as openat and mkdirat @<:@default=detect@:>@]),
+        [have_atfile_source=$enableval], [have_atfile_source=auto])
+
+if test "x$have_atfile_source" != "xno"; then
+        AC_CHECK_FUNCS(mkdirat,
+                [
+                have_atfile_source=yes
+                AC_DEFINE(HAVE_ATFILE_SOURCE, 1, [mkdirat exists])
+                ],
+                [
+                if test "x$have_atfile_source" = "xyes"; then
+                        AC_MSG_ERROR([required atfile-source but no mkdirat()])
+                fi
+                have_atfile_source=no
+                ])
+fi
 
 ### Ecore modules
 
index cf656cc..c9c7c92 100644 (file)
@@ -70,6 +70,7 @@ extern "C" {
    EAPI int         ecore_file_is_dir       (const char *file);
    EAPI int         ecore_file_mkdir        (const char *dir);
    EAPI int         ecore_file_mkdirs       (const char **dirs);
+   EAPI int         ecore_file_mksubdirs    (const char *base, const char **subdirs);
    EAPI int         ecore_file_rmdir        (const char *dir);
    EAPI int         ecore_file_recursive_rm (const char *dir);
    EAPI int         ecore_file_mkpath       (const char *path);
index 60b476c..a34e004 100644 (file)
@@ -6,6 +6,7 @@
 # include <config.h>
 #endif
 
+#include <Ecore_Str.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
@@ -174,6 +175,100 @@ ecore_file_mkdirs(const char **dirs)
 }
 
 /**
+ * Create complete list of sub-directories in a batch (optimized).
+ *
+ * @param base the base directory to act on, will be created if does
+ *     not exists.
+ * @param subdirs list of directories, null terminated. These are
+ *     created similarly to ecore_file_mkdir(), so same mode and whole
+ *     path to that point must exists. So if creating base/a/b/c,
+ *     provide subdirs with "a", "a/b" and "a/b/c" in that order!
+ *
+ * @return number of successfull directories created, -1 if subdirs or
+ *     base is NULL or invalid.
+ *
+ * @see ecore_file_mkdir() and ecore_file_mkpaths()
+ */
+EAPI int
+ecore_file_mksubdirs(const char *base, const char **subdirs)
+{
+#ifndef HAVE_ATFILE_SOURCE
+   char buf[PATH_MAX];
+   int baselen;
+#else
+   int fd;
+   DIR *dir;
+#endif
+   int i;
+
+   if (!subdirs) return -1;
+   if ((!base) || (base[0] == '\0')) return -1;
+
+   if ((!ecore_file_is_dir(base)) && (!ecore_file_mkpath(base)))
+     return 0;
+
+#ifndef HAVE_ATFILE_SOURCE
+   baselen = ecore_strlcpy(buf, base, sizeof(buf));
+   if ((baselen < 1) || (baselen + 1 >= (int)sizeof(buf)))
+     return 0;
+
+   if (buf[baselen - 1] != '/')
+     {
+       buf[baselen] = '/';
+       baselen++;
+     }
+#else
+   dir = opendir(base);
+   if (!dir)
+     return 0;
+   fd = dirfd(dir);
+#endif
+
+   i = 0;
+   for (; *subdirs != NULL; subdirs++)
+     {
+       struct stat st;
+
+#ifndef HAVE_ATFILE_SOURCE
+       ecore_strlcpy(buf + baselen, *subdirs, sizeof(buf) - baselen);
+       printf("no atfile: %s\n", buf);
+       if (stat(buf, &st) == 0)
+#else
+         printf("atfile: %s/%s\n", base, *subdirs);
+       if (fstatat(fd, *subdirs, &st, 0) == 0)
+#endif
+         {
+            if (S_ISDIR(st.st_mode))
+              {
+                 i++;
+                 continue;
+              }
+         }
+       else
+         {
+            if (errno == ENOENT)
+              {
+#ifndef HAVE_ATFILE_SOURCE
+                 if (mkdir(buf, default_mode) == 0)
+#else
+                 if (mkdirat(fd, *subdirs, default_mode) == 0)
+#endif
+                   {
+                      i++;
+                      continue;
+                   }
+                }
+           }
+     }
+
+#ifdef HAVE_ATFILE_SOURCE
+   closedir(dir);
+#endif
+
+   return i;
+}
+
+/**
  * Delete the given dir
  * @param  dir The name of the directory to delete
  * @return 1 on success, 0 on failure