13 #ifndef _FILE_OFFSET_BITS
14 # define _FILE_OFFSET_BITS 64
17 #ifdef HAVE_FEATURES_H
18 # include <features.h>
23 #include "ecore_file_private.h"
25 int _ecore_file_log_dom = -1;
26 static int _ecore_file_init_count = 0;
28 /* externally accessible functions */
30 * Initialize Ecore_File and the services it will use. Call this function
31 * once before you use any of the ecore file functions.
32 * @return Return the number howoften ecore_file_init() was call succesfully;
38 if (++_ecore_file_init_count != 1)
39 return _ecore_file_init_count;
40 _ecore_file_log_dom = eina_log_domain_register("EcoreFile", ECORE_FILE_DEFAULT_LOG_COLOR);
41 if(_ecore_file_log_dom < 0)
43 EINA_LOG_ERR("Impossible to create a log domain for the ecore file module.");
44 return --_ecore_file_init_count;
46 ecore_file_path_init();
47 ecore_file_monitor_init();
48 ecore_file_download_init();
50 /* FIXME: were the tests disabled for a good reason ? */
53 if (!ecore_file_monitor_init())
54 goto shutdown_ecore_file_path;
56 if (!ecore_file_download_init())
57 goto shutdown_ecore_file_monitor;
60 return _ecore_file_init_count;
63 shutdown_ecore_file_monitor:
64 ecore_file_monitor_shutdown();
65 shutdown_ecore_file_path:
66 ecore_file_path_shutdown();
68 return --_ecore_file_init_count;
73 * Shutdown the Ecore_File
74 * @return returns the number of libraries that still uses Ecore_File
79 if (--_ecore_file_init_count != 0)
80 return _ecore_file_init_count;
82 ecore_file_download_shutdown();
83 ecore_file_monitor_shutdown();
84 ecore_file_path_shutdown();
85 eina_log_domain_unregister(_ecore_file_log_dom);
86 _ecore_file_log_dom = -1;
87 return _ecore_file_init_count;
91 * Get the time of the last modification to the give file
92 * @param file The name of the file
93 * @return Return the time of the last data modification, if an error should
94 * occur it will return 0
97 ecore_file_mod_time(const char *file)
101 if (stat(file, &st) < 0) return 0;
106 * Get the size of the given file
107 * @param file The name of the file
108 * @return The size of the file in byte
111 ecore_file_size(const char *file)
115 if (stat(file, &st) < 0) return 0;
120 * Check if file exists
121 * @param file The name of the file
122 * @return EINA_TRUE if file exists on local filesystem, EINA_FALSE otherwise
125 ecore_file_exists(const char *file)
129 /*Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor*/
130 if (stat(file, &st) < 0 && strcmp(file, "/")) return EINA_FALSE;
135 * Check if file is a directory
136 * @param file The name of the file
137 * @return EINA_TRUE if file exist and is a directory, EINA_FALSE otherwise
140 ecore_file_is_dir(const char *file)
144 if (stat(file, &st) < 0) return EINA_FALSE;
145 if (S_ISDIR(st.st_mode)) return EINA_TRUE;
149 static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
152 * Create a new directory
153 * @param dir The name of the directory to create
154 * @return EINA_TRUE on successfull creation, EINA_FALSE on failure
156 * The directory is created with the mode: S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
159 ecore_file_mkdir(const char *dir)
161 if (mkdir(dir, default_mode) < 0) return EINA_FALSE;
166 * Create complete directory in a batch.
168 * @param dirs list of directories, null terminated.
169 * @return number of successfull directories created, -1 if dirs is NULL.
171 * @see ecore_file_mkdir() and ecore_file_mkpaths()
174 ecore_file_mkdirs(const char **dirs)
178 if (!dirs) return -1;
180 for (; *dirs; dirs++)
181 if (ecore_file_mkdir(*dirs))
187 * Create complete list of sub-directories in a batch (optimized).
189 * @param base the base directory to act on, will be created if does
191 * @param subdirs list of directories, null terminated. These are
192 * created similarly to ecore_file_mkdir(), so same mode and whole
193 * path to that point must exists. So if creating base/a/b/c,
194 * provide subdirs with "a", "a/b" and "a/b/c" in that order!
196 * @return number of successfull directories created, -1 if subdirs or
197 * base is NULL or invalid.
199 * @see ecore_file_mkdir() and ecore_file_mkpaths()
202 ecore_file_mksubdirs(const char *base, const char **subdirs)
204 #ifndef HAVE_ATFILE_SOURCE
213 if (!subdirs) return -1;
214 if ((!base) || (base[0] == '\0')) return -1;
216 if ((!ecore_file_is_dir(base)) && (!ecore_file_mkpath(base)))
219 #ifndef HAVE_ATFILE_SOURCE
220 baselen = eina_strlcpy(buf, base, sizeof(buf));
221 if ((baselen < 1) || (baselen + 1 >= (int)sizeof(buf)))
224 if (buf[baselen - 1] != '/')
237 for (; *subdirs; subdirs++)
241 #ifndef HAVE_ATFILE_SOURCE
242 eina_strlcpy(buf + baselen, *subdirs, sizeof(buf) - baselen);
243 if (stat(buf, &st) == 0)
245 if (fstatat(fd, *subdirs, &st, 0) == 0)
248 if (S_ISDIR(st.st_mode))
258 #ifndef HAVE_ATFILE_SOURCE
259 if (mkdir(buf, default_mode) == 0)
261 if (mkdirat(fd, *subdirs, default_mode) == 0)
271 #ifdef HAVE_ATFILE_SOURCE
279 * Delete the given dir
280 * @param dir The name of the directory to delete
281 * @return EINA_TRUE on success, EINA_FALSE on failure
284 ecore_file_rmdir(const char *dir)
286 if (rmdir(dir) < 0) return EINA_FALSE;
291 * Delete the given file
292 * @param file The name of the file to delete
293 * @return EINA_TRUE on success, EINA_FALSE on failure
296 ecore_file_unlink(const char *file)
298 if (unlink(file) < 0) return EINA_FALSE;
303 * Remove the given file or directory
304 * @param file The name of the file or directory to delete
305 * @return EINA_TRUE on success, EINA_FALSE on failure
308 ecore_file_remove(const char *file)
310 if (remove(file) < 0) return EINA_FALSE;
315 * Delete a directory and all its contents
316 * @param dir The name of the directory to delete
317 * @return EINA_TRUE on success, EINA_FALSE on failure
319 * If dir is a link only the link is removed
322 ecore_file_recursive_rm(const char *dir)
326 char path[PATH_MAX], buf[PATH_MAX];
330 if (readlink(dir, buf, sizeof(buf)) > 0)
331 return ecore_file_unlink(dir);
333 ret = stat(dir, &st);
334 if ((ret == 0) && (S_ISDIR(st.st_mode)))
337 if (stat(dir, &st) == -1) return EINA_FALSE;
341 while ((dp = readdir(dirp)))
343 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
345 snprintf(path, PATH_MAX, "%s/%s", dir, dp->d_name);
346 if (!ecore_file_recursive_rm(path))
352 if (!ecore_file_rmdir(dir)) ret = 0;
360 if (ret == -1) return EINA_FALSE;
361 return ecore_file_unlink(dir);
365 static inline Eina_Bool
366 _ecore_file_mkpath_if_not_exists(const char *path)
370 if (stat(path, &st) < 0)
371 return ecore_file_mkdir(path);
372 else if (!S_ISDIR(st.st_mode))
379 * Create a complete path
380 * @param path The path to create
381 * @return EINA_TRUE on success, EINA_FALSE on failure
383 * @see ecore_file_mkpaths() and ecore_file_mkdir()
386 ecore_file_mkpath(const char *path)
391 if (ecore_file_is_dir(path))
394 for (i = 0; path[i] != '\0'; ss[i] = path[i], i++)
396 if (i == sizeof(ss) - 1) return EINA_FALSE;
397 if ((path[i] == '/') && (i > 0))
400 if (!_ecore_file_mkpath_if_not_exists(ss))
405 return _ecore_file_mkpath_if_not_exists(ss);
409 * Create complete paths in a batch.
411 * @param paths list of paths, null terminated.
412 * @return number of successfull paths created, -1 if paths is NULL.
414 * @see ecore_file_mkpath() and ecore_file_mkdirs()
417 ecore_file_mkpaths(const char **paths)
421 if (!paths) return -1;
423 for (; *paths; paths++)
424 if (ecore_file_mkpath(*paths))
431 * @param src The name of the source file
432 * @param dst The name of the destination file
433 * @return EINA_TRUE on success, EINA_FALSE on failure
436 ecore_file_cp(const char *src, const char *dst)
440 char realpath1[PATH_MAX], realpath2[PATH_MAX];
442 Eina_Bool ret = EINA_TRUE;
444 if (!realpath(src, realpath1)) return EINA_FALSE;
445 if (realpath(dst, realpath2) && !strcmp(realpath1, realpath2)) return EINA_FALSE;
447 f1 = fopen(src, "rb");
448 if (!f1) return EINA_FALSE;
449 f2 = fopen(dst, "wb");
455 while ((num = fread(buf, 1, sizeof(buf), f1)) > 0)
457 if (fwrite(buf, 1, num, f2) != num) ret = EINA_FALSE;
466 * @param src The name of the source file
467 * @param dst The name of the destination file
468 * @return EINA_TRUE on success, EINA_FALSE on failure
471 ecore_file_mv(const char *src, const char *dst)
476 if (rename(src, dst))
478 // File cannot be moved directly because
479 // it resides on a different mount point.
484 // Make sure this is a regular file before
485 // we do anything fancy.
487 if (S_ISREG(st.st_mode))
491 dir = ecore_file_dir_get(dst);
492 // Since we can't directly rename, try to
493 // copy to temp file in the dst directory
495 snprintf(buf, sizeof(buf), "%s/.%s.tmp.XXXXXX",
496 dir, ecore_file_file_get(dst));
507 if (!ecore_file_cp(src, buf))
510 // Set file permissions of temp file to match src
511 chmod(buf, st.st_mode);
513 // Try to atomically move temp file to dst
514 if (rename(buf, dst))
516 // If we still cannot atomically move
517 // do a normal copy and hope for the best.
518 if (!ecore_file_cp(buf, dst))
522 // Delete temporary file and src
523 ecore_file_unlink(buf);
524 ecore_file_unlink(src);
539 * Create a symbolic link
540 * @param src The name of the file to link
541 * @param dest The name of link
542 * @return EINA_TRUE on success, EINA_FALSE on failure
545 ecore_file_symlink(const char *src, const char *dest)
547 if (!symlink(src, dest)) return EINA_TRUE;
553 * Get the canonicalized absolute pathname
554 * @param file The file path
555 * @return The canonicalized absolute pathname; on failure it will return
559 ecore_file_realpath(const char *file)
564 * Some implementations of realpath do not conform to the SUS.
565 * And as a result we must prevent a null arg from being passed.
567 if (!file) return strdup("");
568 if (!realpath(file, buf)) return strdup("");
574 * Get the filename from a give path
575 * @param path The complete path
576 * @return Only the file name
579 ecore_file_file_get(const char *path)
583 if (!path) return NULL;
584 if ((result = strrchr(path, '/'))) result++;
585 else result = (char *)path;
590 * Get the directory where file reside
591 * @param file The name of the file
592 * @return The directory name
595 ecore_file_dir_get(const char *file)
600 if (!file) return NULL;
601 strncpy(buf, file, PATH_MAX);
602 buf[PATH_MAX - 1] = 0;
608 * Check if file can be read
609 * @param file The name of the file
610 * @return EINA_TRUE if the file is readable, EINA_FALSE otherwise
613 ecore_file_can_read(const char *file)
615 if (!file) return EINA_FALSE;
616 if (!access(file, R_OK)) return EINA_TRUE;
621 * Check if file can be written
622 * @param file The name of the file
623 * @return EINA_TRUE if the file is writable, EINA_FALSE otherwise
626 ecore_file_can_write(const char *file)
628 if (!file) return EINA_FALSE;
629 if (!access(file, W_OK)) return EINA_TRUE;
634 * Check if file can be executed
635 * @param file The name of the file
636 * @return EINA_TRUE if the file can be executed, EINA_FALSE otherwise
639 ecore_file_can_exec(const char *file)
641 if (!file) return EINA_FALSE;
642 if (!access(file, X_OK)) return EINA_TRUE;
647 * Get the path pointed by link
648 * @param link The name of the link
649 * @return The path pointed by link or NULL
652 ecore_file_readlink(const char *link)
657 if ((count = readlink(link, buf, sizeof(buf) - 1)) < 0) return NULL;
663 * Get the list of the files and directories in a given directory. The list
664 * will be sorted with strcoll as compare function. That means that you may
665 * want to set the current locale for the category LC_COLLATE with setlocale().
666 * For more information see the manual pages of strcoll and setlocale.
667 * The list will not contain the directory entries for '.' and '..'.
668 * @param dir The name of the directory to list
669 * @return Return an Eina_List containing all the files in the directory;
670 * on failure it returns NULL.
673 ecore_file_ls(const char *dir)
678 Eina_List *list = NULL;
681 if (!dirp) return NULL;
683 while ((dp = readdir(dirp)))
685 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
687 f = strdup(dp->d_name);
688 list = eina_list_append(list, f);
693 list = eina_list_sort(list, eina_list_count(list), EINA_COMPARE_CB(strcoll));
699 * FIXME: To be documented.
702 ecore_file_app_exe_get(const char *app)
704 char *p, *pp, *exe1 = NULL, *exe2 = NULL;
706 int in_quot_dbl = 0, in_quot_sing = 0, restart = 0;
708 if (!app) return NULL;
712 while ((*p) && (isspace(*p))) p++;
721 else if (in_quot_dbl)
732 if ((isspace(*p)) && (!((p > app) && (p[-1] != '\\'))))
738 if (exe2 == exe1) return NULL;
747 homedir = getenv("HOME");
748 if (!homedir) return NULL;
749 len = strlen(homedir);
751 exe = malloc(len + exe2 - exe1 + 2);
752 if (!exe) return NULL;
756 strcpy(exe, homedir);
758 if (*(pp - 1) != '/')
768 exe = malloc(exe2 - exe1 + 1);
769 if (!exe) return NULL;
788 else if (in_quot_dbl)
794 /* techcincally this is wrong. double quotes also accept
805 /* technically we should handle special chars:
809 if ((p > exe1) && (p[-1] == '\\'))
817 else if ((p > exe1) && (*p == '='))
827 else if (isspace(*p))
847 * Add the escape sequence ('\\') to the given filename
848 * @param filename The file name
849 * @return The file name with special characters escaped; if the length of the
850 * resulting string is longer than PATH_MAX it will return NULL
853 ecore_file_escape_name(const char *filename)
863 if ((q - buf) > (PATH_MAX - 6)) return NULL;
865 (*p == ' ') || (*p == '\t') || (*p == '\n') ||
866 (*p == '\\') || (*p == '\'') || (*p == '\"') ||
867 (*p == ';') || (*p == '!') || (*p == '#') ||
868 (*p == '$') || (*p == '%') || (*p == '&') ||
869 (*p == '*') || (*p == '(') || (*p == ')') ||
870 (*p == '[') || (*p == ']') || (*p == '{') ||
871 (*p == '}') || (*p == '|') || (*p == '<') ||
872 (*p == '>') || (*p == '?')
887 * Remove the extension from a given path
888 * @param path The name of the file
889 * @return A newly allocated string with the extension stripped out or NULL on errors
892 ecore_file_strip_ext(const char *path)
894 char *p, *file = NULL;
896 p = strrchr(path, '.');
901 file = malloc(((p - path) + 1) * sizeof(char));
904 memcpy(file, path, (p - path));
913 * Check if the given directory is empty. The '.' and '..' files will be ignored.
914 * @param dir The name of the directory to check
915 * @return 1 if directory is empty, 0 if it has at least one file or -1 in case of errors
918 ecore_file_dir_is_empty(const char *dir)
924 if (!dirp) return -1;
926 while ((dp = readdir(dirp)))
928 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))