From eab4fea0304679a050a5cffc05867f61bdf4d8f3 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Sat, 11 Apr 2009 07:10:12 +0000 Subject: [PATCH] move batch directory creation to ecore_file. as suggested by raster, this could be abstracted into ecore-file and other applications could use it as well. SVN revision: 39965 --- legacy/ecore/configure.ac | 20 +++++ legacy/ecore/src/lib/ecore_file/Ecore_File.h | 1 + legacy/ecore/src/lib/ecore_file/ecore_file.c | 95 ++++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/legacy/ecore/configure.ac b/legacy/ecore/configure.ac index a8e84d236d..7a55f0b016 100644 --- a/legacy/ecore/configure.ac +++ b/legacy/ecore/configure.ac @@ -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 diff --git a/legacy/ecore/src/lib/ecore_file/Ecore_File.h b/legacy/ecore/src/lib/ecore_file/Ecore_File.h index cf656cc66d..c9c7c92ac2 100644 --- a/legacy/ecore/src/lib/ecore_file/Ecore_File.h +++ b/legacy/ecore/src/lib/ecore_file/Ecore_File.h @@ -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); diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file.c b/legacy/ecore/src/lib/ecore_file/ecore_file.c index 60b476c8a0..a34e004a93 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file.c +++ b/legacy/ecore/src/lib/ecore_file/ecore_file.c @@ -6,6 +6,7 @@ # include #endif +#include #include #include #include @@ -173,6 +174,100 @@ ecore_file_mkdirs(const char **dirs) return i; } +/** + * 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