2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
11 #include <sys/types.h>
20 #ifndef _FILE_OFFSET_BITS
21 # define _FILE_OFFSET_BITS 64
24 #ifdef HAVE_FEATURES_H
25 # include <features.h>
30 #include "ecore_file_private.h"
32 int _ecore_file_log_dom = -1;
33 static int _ecore_file_init_count = 0;
35 /* externally accessible functions */
37 * Initialize Ecore_File and the services it will use. Call this function
38 * once before you use any of the ecore file functions.
39 * @return Return the number howoften ecore_file_init() was call succesfully;
45 if (++_ecore_file_init_count != 1)
46 return _ecore_file_init_count;
47 _ecore_file_log_dom = eina_log_domain_register("EcoreFile", ECORE_FILE_DEFAULT_LOG_COLOR);
48 if(_ecore_file_log_dom < 0)
50 EINA_LOG_ERR("Impossible to create a log domain for the ecore file module.");
51 return --_ecore_file_init_count;
53 ecore_file_path_init();
54 ecore_file_monitor_init();
55 ecore_file_download_init();
57 /* FIXME: were the tests disabled for a good reason ? */
60 if (!ecore_file_monitor_init())
61 goto shutdown_ecore_file_path;
63 if (!ecore_file_download_init())
64 goto shutdown_ecore_file_monitor;
67 return _ecore_file_init_count;
70 shutdown_ecore_file_monitor:
71 ecore_file_monitor_shutdown();
72 shutdown_ecore_file_path:
73 ecore_file_path_shutdown();
75 return --_ecore_file_init_count;
80 * Shutdown the Ecore_File
81 * @return returns the number of libraries that still uses Ecore_File
86 if (--_ecore_file_init_count != 0)
87 return _ecore_file_init_count;
89 ecore_file_download_shutdown();
90 ecore_file_monitor_shutdown();
91 ecore_file_path_shutdown();
92 eina_log_domain_unregister(_ecore_file_log_dom);
93 _ecore_file_log_dom = -1;
94 return _ecore_file_init_count;
98 * Get the time of the last modification to the give file
99 * @param file The name of the file
100 * @return Return the time of the last data modification, if an error should
101 * occur it will return 0
104 ecore_file_mod_time(const char *file)
108 if (stat(file, &st) < 0) return 0;
113 * Get the size of the given file
114 * @param file The name of the file
115 * @return The size of the file in byte
118 ecore_file_size(const char *file)
122 if (stat(file, &st) < 0) return 0;
127 * Check if file exists
128 * @param file The name of the file
129 * @return 1 if file exists on local filesystem, 0 otherwise
132 ecore_file_exists(const char *file)
136 /*Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor*/
137 if (stat(file, &st) < 0 && strcmp(file, "/")) return 0;
142 * Check if file is a directory
143 * @param file The name of the file
144 * @return 1 if file exist and is a directory, 0 otherwise
147 ecore_file_is_dir(const char *file)
151 if (stat(file, &st) < 0) return 0;
152 if (S_ISDIR(st.st_mode)) return 1;
156 static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
159 * Create a new directory
160 * @param dir The name of the directory to create
161 * @return 1 on successfull creation, 0 on failure
163 * The directory is created with the mode: S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
166 ecore_file_mkdir(const char *dir)
168 if (mkdir(dir, default_mode) < 0) return 0;
173 * Create complete directory in a batch.
175 * @param dirs list of directories, null terminated.
176 * @return number of successfull directories created, -1 if dirs is NULL.
178 * @see ecore_file_mkdir() and ecore_file_mkpaths()
181 ecore_file_mkdirs(const char **dirs)
185 if (!dirs) return -1;
187 for (; *dirs != NULL; dirs++)
188 if (ecore_file_mkdir(*dirs))
194 * Create complete list of sub-directories in a batch (optimized).
196 * @param base the base directory to act on, will be created if does
198 * @param subdirs list of directories, null terminated. These are
199 * created similarly to ecore_file_mkdir(), so same mode and whole
200 * path to that point must exists. So if creating base/a/b/c,
201 * provide subdirs with "a", "a/b" and "a/b/c" in that order!
203 * @return number of successfull directories created, -1 if subdirs or
204 * base is NULL or invalid.
206 * @see ecore_file_mkdir() and ecore_file_mkpaths()
209 ecore_file_mksubdirs(const char *base, const char **subdirs)
211 #ifndef HAVE_ATFILE_SOURCE
220 if (!subdirs) return -1;
221 if ((!base) || (base[0] == '\0')) return -1;
223 if ((!ecore_file_is_dir(base)) && (!ecore_file_mkpath(base)))
226 #ifndef HAVE_ATFILE_SOURCE
227 baselen = eina_strlcpy(buf, base, sizeof(buf));
228 if ((baselen < 1) || (baselen + 1 >= (int)sizeof(buf)))
231 if (buf[baselen - 1] != '/')
244 for (; *subdirs != NULL; subdirs++)
248 #ifndef HAVE_ATFILE_SOURCE
249 eina_strlcpy(buf + baselen, *subdirs, sizeof(buf) - baselen);
250 if (stat(buf, &st) == 0)
252 if (fstatat(fd, *subdirs, &st, 0) == 0)
255 if (S_ISDIR(st.st_mode))
265 #ifndef HAVE_ATFILE_SOURCE
266 if (mkdir(buf, default_mode) == 0)
268 if (mkdirat(fd, *subdirs, default_mode) == 0)
278 #ifdef HAVE_ATFILE_SOURCE
286 * Delete the given dir
287 * @param dir The name of the directory to delete
288 * @return 1 on success, 0 on failure
291 ecore_file_rmdir(const char *dir)
293 if (rmdir(dir) < 0) return 0;
298 * Delete the given file
299 * @param file The name of the file to delete
300 * @return 1 on success, 0 on failure
303 ecore_file_unlink(const char *file)
305 if (unlink(file) < 0) return 0;
310 * Remove the given file or directory
311 * @param file The name of the file or directory to delete
312 * @return 1 on success, 0 on failure
315 ecore_file_remove(const char *file)
317 if (remove(file) < 0) return 0;
322 * Delete a directory and all its contents
323 * @param dir The name of the directory to delete
324 * @return 1 on success, 0 on failure
326 * If dir is a link only the link is removed
329 ecore_file_recursive_rm(const char *dir)
333 char path[PATH_MAX], buf[PATH_MAX];
337 if (readlink(dir, buf, sizeof(buf)) > 0)
338 return ecore_file_unlink(dir);
340 ret = stat(dir, &st);
341 if ((ret == 0) && (S_ISDIR(st.st_mode)))
344 if (stat(dir, &st) == -1) return 0;
348 while ((dp = readdir(dirp)))
350 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
352 snprintf(path, PATH_MAX, "%s/%s", dir, dp->d_name);
353 if (!ecore_file_recursive_rm(path))
359 if (!ecore_file_rmdir(dir)) ret = 0;
364 if (ret == -1) return 0;
365 return ecore_file_unlink(dir);
370 _ecore_file_mkpath_if_not_exists(const char *path)
374 if (stat(path, &st) < 0)
375 return ecore_file_mkdir(path);
376 else if (!S_ISDIR(st.st_mode))
383 * Create a complete path
384 * @param path The path to create
385 * @return 1 on success, 0 on failure
387 * @see ecore_file_mkpaths() and ecore_file_mkdir()
390 ecore_file_mkpath(const char *path)
395 if (ecore_file_is_dir(path))
398 for (i = 0; path[i] != '\0'; ss[i] = path[i], i++)
400 if (i == sizeof(ss) - 1) return 0;
401 if ((path[i] == '/') && (i > 0))
404 if (!_ecore_file_mkpath_if_not_exists(ss))
409 return _ecore_file_mkpath_if_not_exists(ss);
413 * Create complete paths in a batch.
415 * @param paths list of paths, null terminated.
416 * @return number of successfull paths created, -1 if paths is NULL.
418 * @see ecore_file_mkpath() and ecore_file_mkdirs()
421 ecore_file_mkpaths(const char **paths)
425 if (!paths) return -1;
427 for (; *paths != NULL; paths++)
428 if (ecore_file_mkpath(*paths))
435 * @param src The name of the source file
436 * @param dst The name of the destination file
437 * @return 1 on success, 0 on failure
440 ecore_file_cp(const char *src, const char *dst)
444 char realpath1[PATH_MAX], realpath2[PATH_MAX];
448 if (!realpath(src, realpath1)) return 0;
449 if (realpath(dst, realpath2) && !strcmp(realpath1, realpath2)) return 0;
451 f1 = fopen(src, "rb");
453 f2 = fopen(dst, "wb");
459 while ((num = fread(buf, 1, sizeof(buf), f1)) > 0)
461 if (fwrite(buf, 1, num, f2) != num) ret = 0;
470 * @param src The name of the source file
471 * @param dst The name of the destination file
472 * @return 1 on success, 0 on failure
475 ecore_file_mv(const char *src, const char *dst)
480 if (rename(src, dst))
482 // File cannot be moved directly because
483 // it resides on a different mount point.
488 // Make sure this is a regular file before
489 // we do anything fancy.
491 if (S_ISREG(st.st_mode))
495 dir = ecore_file_dir_get(dst);
496 // Since we can't directly rename, try to
497 // copy to temp file in the dst directory
499 snprintf(buf, sizeof(buf), "%s/.%s.tmp.XXXXXX",
500 dir, ecore_file_file_get(dst));
511 if (!ecore_file_cp(src, buf))
514 // Set file permissions of temp file to match src
515 chmod(buf, st.st_mode);
517 // Try to atomically move temp file to dst
518 if (rename(buf, dst))
520 // If we still cannot atomically move
521 // do a normal copy and hope for the best.
522 if (!ecore_file_cp(buf, dst))
526 // Delete temporary file and src
527 ecore_file_unlink(buf);
528 ecore_file_unlink(src);
543 * Create a symbolic link
544 * @param src The name of the file to link
545 * @param dest The name of link
546 * @return 1 on success, 0 on failure
549 ecore_file_symlink(const char *src, const char *dest)
551 if (!symlink(src, dest)) return 1;
557 * Get the canonicalized absolute pathname
558 * @param file The file path
559 * @return The canonicalized absolute pathname; on failure it will return
563 ecore_file_realpath(const char *file)
568 * Some implementations of realpath do not conform to the SUS.
569 * And as a result we must prevent a null arg from being passed.
571 if (!file) return strdup("");
572 if (!realpath(file, buf)) return strdup("");
578 * Get the filename from a give path
579 * @param path The complete path
580 * @return Only the file name
583 ecore_file_file_get(const char *path)
587 if (!path) return NULL;
588 if ((result = strrchr(path, '/'))) result++;
589 else result = (char *)path;
594 * Get the directory where file reside
595 * @param file The name of the file
596 * @return The directory name
599 ecore_file_dir_get(const char *file)
604 if (!file) return NULL;
605 strncpy(buf, file, PATH_MAX);
606 buf[PATH_MAX - 1] = 0;
612 * Check if file can be read
613 * @param file The name of the file
614 * @return 1 if the file is readable, 0 otherwise
617 ecore_file_can_read(const char *file)
620 if (!access(file, R_OK)) return 1;
625 * Check if file can be written
626 * @param file The name of the file
627 * @return 1 if the file is writable, 0 otherwise
630 ecore_file_can_write(const char *file)
633 if (!access(file, W_OK)) return 1;
638 * Check if file can be executed
639 * @param file The name of the file
640 * @return 1 if the file can be executed, 0 otherwise
643 ecore_file_can_exec(const char *file)
646 if (!access(file, X_OK)) return 1;
651 * Get the path pointed by link
652 * @param link The name of the link
653 * @return The path pointed by link or NULL
656 ecore_file_readlink(const char *link)
661 if ((count = readlink(link, buf, sizeof(buf))) < 0) return NULL;
667 * Get the list of the files and directories in a given directory. The list
668 * will be sorted with strcoll as compare function. That means that you may
669 * want to set the current locale for the category LC_COLLATE with setlocale().
670 * For more information see the manual pages of strcoll and setlocale.
671 * The list will not contain the directory entries for '.' and '..'.
672 * @param dir The name of the directory to list
673 * @return Return an Eina_List containing all the files in the directory;
674 * on failure it returns NULL.
677 ecore_file_ls(const char *dir)
682 Eina_List *list = NULL;
685 if (!dirp) return NULL;
687 while ((dp = readdir(dirp)))
689 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
691 f = strdup(dp->d_name);
692 list = eina_list_append(list, f);
697 list = eina_list_sort(list, eina_list_count(list), EINA_COMPARE_CB(strcoll));
703 * FIXME: To be documented.
706 ecore_file_app_exe_get(const char *app)
708 char *p, *pp, *exe1 = NULL, *exe2 = NULL;
710 int in_quot_dbl = 0, in_quot_sing = 0, restart = 0;
712 if (!app) return NULL;
716 while ((*p) && (isspace(*p))) p++;
725 else if (in_quot_dbl)
736 if ((isspace(*p)) && (!((p > app) && (p[-1] != '\\'))))
742 if (exe2 == exe1) return NULL;
751 homedir = getenv("HOME");
752 if (!homedir) return NULL;
753 len = strlen(homedir);
755 exe = malloc(len + exe2 - exe1 + 2);
756 if (!exe) return NULL;
760 strcpy(exe, homedir);
762 if (*(pp - 1) != '/')
772 exe = malloc(exe2 - exe1 + 1);
773 if (!exe) return NULL;
792 else if (in_quot_dbl)
798 /* techcincally this is wrong. double quotes also accept
809 /* technically we should handle special chars:
813 if ((p > exe1) && (p[-1] == '\\'))
821 else if ((p > exe1) && (*p == '='))
831 else if (isspace(*p))
851 * Add the escape sequence ('\\') to the given filename
852 * @param filename The file name
853 * @return The file name with special characters escaped; if the length of the
854 * resulting string is longer than PATH_MAX it will return NULL
857 ecore_file_escape_name(const char *filename)
867 if ((q - buf) > (PATH_MAX - 6)) return NULL;
869 (*p == ' ') || (*p == '\t') || (*p == '\n') ||
870 (*p == '\\') || (*p == '\'') || (*p == '\"') ||
871 (*p == ';') || (*p == '!') || (*p == '#') ||
872 (*p == '$') || (*p == '%') || (*p == '&') ||
873 (*p == '*') || (*p == '(') || (*p == ')') ||
874 (*p == '[') || (*p == ']') || (*p == '{') ||
875 (*p == '}') || (*p == '|') || (*p == '<') ||
876 (*p == '>') || (*p == '?')
891 * Remove the extension from a given path
892 * @param path The name of the file
893 * @return A newly allocated string with the extension stripped out or NULL on errors
896 ecore_file_strip_ext(const char *path)
898 char *p, *file = NULL;
900 p = strrchr(path, '.');
905 file = malloc(((p - path) + 1) * sizeof(char));
908 memcpy(file, path, (p - path));
917 * Check if the given directory is empty. The '.' and '..' files will be ignored.
918 * @param dir The name of the directory to check
919 * @return 1 if directory is empty, 0 if it has at least one file or -1 in case of errors
922 ecore_file_dir_is_empty(const char *dir)
928 if (!dirp) return -1;
930 while ((dp = readdir(dirp)))
932 if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))