2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
11 #include <sys/types.h>
17 #ifndef _FILE_OFFSET_BITS
18 # define _FILE_OFFSET_BITS 64
21 #ifdef HAVE_FEATURES_H
22 # include <features.h>
27 #include "ecore_file_private.h"
29 int _ecore_file_log_dom = -1;
30 static int _ecore_file_init_count = 0;
32 /* externally accessible functions */
34 * Initialize Ecore_File and the services it will use. Call this function
35 * once before you use any of the ecore file functions.
36 * @return Return the number howoften ecore_file_init() was call succesfully;
42 if (++_ecore_file_init_count != 1)
43 return _ecore_file_init_count;
44 _ecore_file_log_dom = eina_log_domain_register("EcoreFile", ECORE_FILE_DEFAULT_LOG_COLOR);
45 if(_ecore_file_log_dom < 0)
47 EINA_LOG_ERR("Impossible to create a log domain for the ecore file module.");
48 return --_ecore_file_init_count;
50 ecore_file_path_init();
51 ecore_file_monitor_init();
52 ecore_file_download_init();
54 /* FIXME: were the tests disabled for a good reason ? */
57 if (!ecore_file_monitor_init())
58 goto shutdown_ecore_file_path;
60 if (!ecore_file_download_init())
61 goto shutdown_ecore_file_monitor;
64 return _ecore_file_init_count;
67 shutdown_ecore_file_monitor:
68 ecore_file_monitor_shutdown();
69 shutdown_ecore_file_path:
70 ecore_file_path_shutdown();
72 return --_ecore_file_init_count;
77 * Shutdown the Ecore_File
78 * @return returns the number of libraries that still uses Ecore_File
83 if (--_ecore_file_init_count != 0)
84 return _ecore_file_init_count;
86 ecore_file_download_shutdown();
87 ecore_file_monitor_shutdown();
88 ecore_file_path_shutdown();
89 eina_log_domain_unregister(_ecore_file_log_dom);
90 _ecore_file_log_dom = -1;
91 return _ecore_file_init_count;
95 * Get the time of the last modification to the give file
96 * @param file The name of the file
97 * @return Return the time of the last data modification, if an error should
98 * occur it will return 0
101 ecore_file_mod_time(const char *file)
105 if (stat(file, &st) < 0) return 0;
110 * Get the size of the given file
111 * @param file The name of the file
112 * @return The size of the file in byte
115 ecore_file_size(const char *file)
119 if (stat(file, &st) < 0) return 0;
124 * Check if file exists
125 * @param file The name of the file
126 * @return 1 if file exists on local filesystem, 0 otherwise
129 ecore_file_exists(const char *file)
133 /*Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor*/
134 if (stat(file, &st) < 0 && strcmp(file, "/")) return 0;
139 * Check if file is a directory
140 * @param file The name of the file
141 * @return 1 if file exist and is a directory, 0 otherwise
144 ecore_file_is_dir(const char *file)
148 if (stat(file, &st) < 0) return 0;
149 if (S_ISDIR(st.st_mode)) return 1;
153 static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
156 * Create a new directory
157 * @param dir The name of the directory to create
158 * @return 1 on successfull creation, 0 on failure
160 * The directory is created with the mode: S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
163 ecore_file_mkdir(const char *dir)
165 if (mkdir(dir, default_mode) < 0) return 0;
170 * Create complete directory in a batch.
172 * @param dirs list of directories, null terminated.
173 * @return number of successfull directories created, -1 if dirs is NULL.
175 * @see ecore_file_mkdir() and ecore_file_mkpaths()
178 ecore_file_mkdirs(const char **dirs)
180 if (!dirs) return -1;
184 for (; *dirs != NULL; dirs++)
185 if (ecore_file_mkdir(*dirs))
191 * Create complete list of sub-directories in a batch (optimized).
193 * @param base the base directory to act on, will be created if does
195 * @param subdirs list of directories, null terminated. These are
196 * created similarly to ecore_file_mkdir(), so same mode and whole
197 * path to that point must exists. So if creating base/a/b/c,
198 * provide subdirs with "a", "a/b" and "a/b/c" in that order!
200 * @return number of successfull directories created, -1 if subdirs or
201 * base is NULL or invalid.
203 * @see ecore_file_mkdir() and ecore_file_mkpaths()
206 ecore_file_mksubdirs(const char *base, const char **subdirs)
208 #ifndef HAVE_ATFILE_SOURCE
217 if (!subdirs) return -1;
218 if ((!base) || (base[0] == '\0')) return -1;
220 if ((!ecore_file_is_dir(base)) && (!ecore_file_mkpath(base)))
223 #ifndef HAVE_ATFILE_SOURCE
224 baselen = eina_strlcpy(buf, base, sizeof(buf));
225 if ((baselen < 1) || (baselen + 1 >= (int)sizeof(buf)))
228 if (buf[baselen - 1] != '/')
241 for (; *subdirs != NULL; subdirs++)
245 #ifndef HAVE_ATFILE_SOURCE
246 eina_strlcpy(buf + baselen, *subdirs, sizeof(buf) - baselen);
247 if (stat(buf, &st) == 0)
249 if (fstatat(fd, *subdirs, &st, 0) == 0)
252 if (S_ISDIR(st.st_mode))
262 #ifndef HAVE_ATFILE_SOURCE
263 if (mkdir(buf, default_mode) == 0)
265 if (mkdirat(fd, *subdirs, default_mode) == 0)
275 #ifdef HAVE_ATFILE_SOURCE
283 * Delete the given dir
284 * @param dir The name of the directory to delete
285 * @return 1 on success, 0 on failure
288 ecore_file_rmdir(const char *dir)
290 if (rmdir(dir) < 0) return 0;
295 * Delete the given file
296 * @param file The name of the file to delete
297 * @return 1 on success, 0 on failure
300 ecore_file_unlink(const char *file)
302 if (unlink(file) < 0) return 0;
307 * Remove the given file or directory
308 * @param file The name of the file or directory to delete
309 * @return 1 on success, 0 on failure
312 ecore_file_remove(const char *file)
314 if (remove(file) < 0) return 0;
319 * Delete a directory and all its contents
320 * @param dir The name of the directory to delete
321 * @return 1 on success, 0 on failure
323 * If dir is a link only the link is removed
326 ecore_file_recursive_rm(const char *dir)
330 char path[PATH_MAX], buf[PATH_MAX];
334 if (readlink(dir, buf, sizeof(buf)) > 0)
335 return ecore_file_unlink(dir);
337 ret = stat(dir, &st);
338 if ((ret == 0) && (S_ISDIR(st.st_mode)))
341 if (stat(dir, &st) == -1) return 0;
345 while ((dp = readdir(dirp)))
347 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
349 snprintf(path, PATH_MAX, "%s/%s", dir, dp->d_name);
350 if (!ecore_file_recursive_rm(path))
356 if (!ecore_file_rmdir(dir)) ret = 0;
361 if (ret == -1) return 0;
362 return ecore_file_unlink(dir);
367 _ecore_file_mkpath_if_not_exists(const char *path)
371 if (stat(path, &st) < 0)
372 return ecore_file_mkdir(path);
373 else if (!S_ISDIR(st.st_mode))
380 * Create a complete path
381 * @param path The path to create
382 * @return 1 on success, 0 on failure
384 * @see ecore_file_mkpaths() and ecore_file_mkdir()
387 ecore_file_mkpath(const char *path)
392 if (ecore_file_is_dir(path))
395 for (i = 0; path[i] != '\0'; ss[i] = path[i], i++)
397 if (i == sizeof(ss) - 1) return 0;
398 if ((path[i] == '/') && (i > 0))
401 if (!_ecore_file_mkpath_if_not_exists(ss))
406 return _ecore_file_mkpath_if_not_exists(ss);
410 * Create complete paths in a batch.
412 * @param paths list of paths, null terminated.
413 * @return number of successfull paths created, -1 if paths is NULL.
415 * @see ecore_file_mkpath() and ecore_file_mkdirs()
418 ecore_file_mkpaths(const char **paths)
421 if (!paths) return -1;
425 for (; *paths != NULL; paths++)
426 if (ecore_file_mkpath(*paths))
433 * @param src The name of the source file
434 * @param dst The name of the destination file
435 * @return 1 on success, 0 on failure
438 ecore_file_cp(const char *src, const char *dst)
442 char realpath1[PATH_MAX], realpath2[PATH_MAX];
446 if (!realpath(src, realpath1)) return 0;
447 if (realpath(dst, realpath2) && !strcmp(realpath1, realpath2)) return 0;
449 f1 = fopen(src, "rb");
451 f2 = fopen(dst, "wb");
457 while ((num = fread(buf, 1, sizeof(buf), f1)) > 0)
459 if (fwrite(buf, 1, num, f2) != num) ret = 0;
468 * @param src The name of the source file
469 * @param dst The name of the destination file
470 * @return 1 on success, 0 on failure
473 ecore_file_mv(const char *src, const char *dst)
478 if (rename(src, dst))
480 // File cannot be moved directly because
481 // it resides on a different mount point.
486 // Make sure this is a regular file before
487 // we do anything fancy.
489 if (S_ISREG(st.st_mode))
493 dir = ecore_file_dir_get(dst);
494 // Since we can't directly rename, try to
495 // copy to temp file in the dst directory
497 snprintf(buf, sizeof(buf), "%s/.%s.tmp.XXXXXX",
498 dir, ecore_file_file_get(dst));
509 if (!ecore_file_cp(src, buf))
512 // Set file permissions of temp file to match src
513 chmod(buf, st.st_mode);
515 // Try to atomically move temp file to dst
516 if (rename(buf, dst))
518 // If we still cannot atomically move
519 // do a normal copy and hope for the best.
520 if (!ecore_file_cp(buf, dst))
524 // Delete temporary file and src
525 ecore_file_unlink(buf);
526 ecore_file_unlink(src);
541 * Create a symbolic link
542 * @param src The name of the file to link
543 * @param dest The name of link
544 * @return 1 on success, 0 on failure
547 ecore_file_symlink(const char *src, const char *dest)
549 if (!symlink(src, dest)) return 1;
555 * Get the canonicalized absolute pathname
556 * @param file The file path
557 * @return The canonicalized absolute pathname; on failure it will return
561 ecore_file_realpath(const char *file)
566 * Some implementations of realpath do not conform to the SUS.
567 * And as a result we must prevent a null arg from being passed.
569 if (!file) return strdup("");
570 if (!realpath(file, buf)) return strdup("");
576 * Get the filename from a give path
577 * @param path The complete path
578 * @return Only the file name
581 ecore_file_file_get(const char *path)
585 if (!path) return NULL;
586 if ((result = strrchr(path, '/'))) result++;
587 else result = (char *)path;
592 * Get the directory where file reside
593 * @param file The name of the file
594 * @return The directory name
597 ecore_file_dir_get(const char *file)
602 if (!file) return NULL;
603 strncpy(buf, file, PATH_MAX);
604 buf[PATH_MAX - 1] = 0;
610 * Check if file can be read
611 * @param file The name of the file
612 * @return 1 if the file is readable, 0 otherwise
615 ecore_file_can_read(const char *file)
618 if (!access(file, R_OK)) return 1;
623 * Check if file can be written
624 * @param file The name of the file
625 * @return 1 if the file is writable, 0 otherwise
628 ecore_file_can_write(const char *file)
631 if (!access(file, W_OK)) return 1;
636 * Check if file can be executed
637 * @param file The name of the file
638 * @return 1 if the file can be executed, 0 otherwise
641 ecore_file_can_exec(const char *file)
644 if (!access(file, X_OK)) return 1;
649 * Get the path pointed by link
650 * @param link The name of the link
651 * @return The path pointed by link or NULL
654 ecore_file_readlink(const char *link)
659 if ((count = readlink(link, buf, sizeof(buf))) < 0) return NULL;
665 * Get the list of the files and directories in a given directory. The list
666 * will be sorted with strcoll as compare function. That means that you may
667 * want to set the current locale for the category LC_COLLATE with setlocale().
668 * For more information see the manual pages of strcoll and setlocale.
669 * The list will not contain the directory entries for '.' and '..'.
670 * @param dir The name of the directory to list
671 * @return Return an Eina_List containing all the files in the directory;
672 * on failure it returns NULL.
675 ecore_file_ls(const char *dir)
680 Eina_List *list = NULL;
683 if (!dirp) return NULL;
685 while ((dp = readdir(dirp)))
687 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
689 f = strdup(dp->d_name);
690 list = eina_list_append(list, f);
695 list = eina_list_sort(list, eina_list_count(list), EINA_COMPARE_CB(strcoll));
701 * FIXME: To be documented.
704 ecore_file_app_exe_get(const char *app)
706 char *p, *pp, *exe1 = NULL, *exe2 = NULL;
708 int in_quot_dbl = 0, in_quot_sing = 0, restart = 0;
710 if (!app) return NULL;
714 while ((*p) && (isspace(*p))) p++;
723 else if (in_quot_dbl)
734 if ((isspace(*p)) && (!((p > app) && (p[-1] != '\\'))))
740 if (exe2 == exe1) return NULL;
749 homedir = getenv("HOME");
750 if (!homedir) return NULL;
751 len = strlen(homedir);
753 exe = malloc(len + exe2 - exe1 + 2);
754 if (!exe) return NULL;
758 strcpy(exe, homedir);
760 if (*(pp - 1) != '/')
770 exe = malloc(exe2 - exe1 + 1);
771 if (!exe) return NULL;
790 else if (in_quot_dbl)
796 /* techcincally this is wrong. double quotes also accept
807 /* technically we should handle special chars:
811 if ((p > exe1) && (p[-1] == '\\'))
819 else if ((p > exe1) && (*p == '='))
829 else if (isspace(*p))
849 * Add the escape sequence ('\\') to the given filename
850 * @param filename The file name
851 * @return The file name with special characters escaped; if the length of the
852 * resulting string is longer than PATH_MAX it will return NULL
855 ecore_file_escape_name(const char *filename)
865 if ((q - buf) > (PATH_MAX - 6)) return NULL;
867 (*p == ' ') || (*p == '\t') || (*p == '\n') ||
868 (*p == '\\') || (*p == '\'') || (*p == '\"') ||
869 (*p == ';') || (*p == '!') || (*p == '#') ||
870 (*p == '$') || (*p == '%') || (*p == '&') ||
871 (*p == '*') || (*p == '(') || (*p == ')') ||
872 (*p == '[') || (*p == ']') || (*p == '{') ||
873 (*p == '}') || (*p == '|') || (*p == '<') ||
874 (*p == '>') || (*p == '?')
889 * Remove the extension from a given path
890 * @param path The name of the file
891 * @return A newly allocated string with the extension stripped out or NULL on errors
894 ecore_file_strip_ext(const char *path)
896 char *p, *file = NULL;
898 p = strrchr(path, '.');
903 file = malloc(((p - path) + 1) * sizeof(char));
906 memcpy(file, path, (p - path));
915 * Check if the given directory is empty. The '.' and '..' files will be ignored.
916 * @param dir The name of the directory to check
917 * @return 1 if directory is empty, 0 if it has at least one file or -1 in case of errors
920 ecore_file_dir_is_empty(const char *dir)
926 if (!dirp) return -1;
928 while ((dp = readdir(dirp)))
930 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))