From b17640ba62a6b52044970b58057858adb8da46c4 Mon Sep 17 00:00:00 2001 From: Sebastian Dransfeld Date: Thu, 10 Feb 2011 14:25:23 +0000 Subject: [PATCH] Pass dirs to desktop cache process as arguments And store the extra dirs in the desktop eet cache. SVN revision: 56910 --- legacy/efreet/ChangeLog | 1 + .../src/bin/efreet_desktop_cache_create.c | 145 +++++++++++------- legacy/efreet/src/lib/efreet_cache.c | 90 ++++++++--- legacy/efreet/src/lib/efreet_cache_private.h | 1 + legacy/efreet/src/lib/efreet_desktop.c | 136 +--------------- legacy/efreet/src/lib/efreet_private.h | 6 +- 6 files changed, 171 insertions(+), 208 deletions(-) diff --git a/legacy/efreet/ChangeLog b/legacy/efreet/ChangeLog index 63e7d58a49..218652045f 100644 --- a/legacy/efreet/ChangeLog +++ b/legacy/efreet/ChangeLog @@ -73,3 +73,4 @@ * Free hashes on init error * efreet_cache_icon -> efreet_icon for functions in efreet_icon.c * Fix memleak in desktop cache create + * Pass dirs to desktop cache process as arguments diff --git a/legacy/efreet/src/bin/efreet_desktop_cache_create.c b/legacy/efreet/src/bin/efreet_desktop_cache_create.c index 2b5df70f06..83a275c575 100644 --- a/legacy/efreet/src/bin/efreet_desktop_cache_create.c +++ b/legacy/efreet/src/bin/efreet_desktop_cache_create.c @@ -44,7 +44,7 @@ static int verbose = 0; static int strcmplen(const void *data1, const void *data2) { - return strncmp(data1, data2, eina_stringshare_strlen(data2)); + return strncmp(data1, data2, eina_stringshare_strlen(data1)); } static int @@ -223,17 +223,21 @@ main(int argc, char **argv) */ Efreet_Cache_Hash hash; Efreet_Cache_Version version; - Eina_List *dirs = NULL, *user_dirs = NULL; + Eina_List *dirs = NULL; + Eina_List *scanned = NULL; + Efreet_Cache_Array_String *user_dirs = NULL; + Eina_List *extra_dirs = NULL; + Eina_List *store_dirs = NULL; int priority = 0; char *dir = NULL; char *path; - int lockfd = -1, tmpfd, dirsfd = -1; - struct stat st; + int lockfd = -1, tmpfd; int changed = 0; int i; char file[PATH_MAX] = { '\0' }; char util_file[PATH_MAX] = { '\0' }; + if (!eina_init()) goto eina_error; for (i = 1; i < argc; i++) { @@ -244,12 +248,19 @@ main(int argc, char **argv) (!strcmp(argv[i], "--help"))) { printf("Options:\n"); - printf(" -v Verbose mode\n"); + printf(" -v Verbose mode\n"); + printf(" -d dir1 dir2 Extra dirs\n"); exit(0); } + else if (!strcmp(argv[i], "-d")) + { + while ((i < (argc - 1)) && (argv[(i + 1)][0] != '-')) + extra_dirs = eina_list_append(extra_dirs, argv[++i]); + } } + extra_dirs = eina_list_sort(extra_dirs, -1, EINA_COMPARE_CB(strcmp)); + /* init external subsystems */ - if (!eina_init()) goto eina_error; if (!eet_init()) goto eet_error; if (!ecore_init()) goto ecore_error; @@ -272,6 +283,14 @@ main(int argc, char **argv) edd = efreet_desktop_edd(); if (!edd) goto edd_error; + /* read user dirs from old cache */ + ef = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ); + if (ef) + { + user_dirs = eet_data_read(ef, efreet_array_string_edd(), EFREET_CACHE_DESKTOP_DIRS); + eet_close(ef); + } + /* create cache */ snprintf(file, sizeof(file), "%s.XXXXXX", efreet_desktop_cache_file()); tmpfd = mkstemp(file); @@ -312,66 +331,74 @@ main(int argc, char **argv) "applications"); if (!dirs) goto error; - dirsfd = open(efreet_desktop_cache_dirs(), O_APPEND | O_RDWR, S_IRUSR | S_IWUSR); - if (dirsfd >= 0) - { - if ((fstat(dirsfd, &st) == 0) && (st.st_size > 0)) - { - char *p; - char *map; - - map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, dirsfd, 0); - if (map == MAP_FAILED) goto error; - p = map; - while (p < map + st.st_size) - { - unsigned int size = *(unsigned int *)p; - p += sizeof(unsigned int); - user_dirs = eina_list_append(user_dirs, eina_stringshare_add(p)); - p += size; - } - munmap(map, st.st_size); - } - close(dirsfd); - dirsfd = -1; - unlink(efreet_desktop_cache_dirs()); - } - EINA_LIST_FREE(dirs, path) { char file_id[PATH_MAX] = { '\0' }; - Eina_List *l; if (!cache_scan(path, file_id, priority++, 1, &changed)) goto error; - l = eina_list_search_unsorted_list(user_dirs, strcmplen, path); - if (l) - { - eina_stringshare_del(eina_list_data_get(l)); - user_dirs = eina_list_remove_list(user_dirs, l); - } - eina_stringshare_del(path); + scanned = eina_list_append(scanned, path); } + if (user_dirs) { - dirsfd = open(efreet_desktop_cache_dirs(), O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR); - if (dirsfd < 0) goto error; - efreet_fsetowner(dirsfd); - EINA_LIST_FREE(user_dirs, dir) + unsigned int j; + + for (j = 0; j < user_dirs->array_count; j++) { - unsigned int size = strlen(dir) + 1; - size_t count; + Eina_List *l; - count = write(dirsfd, &size, sizeof(int)); - count += write(dirsfd, dir, size); + l = eina_list_search_unsorted_list(scanned, strcmplen, user_dirs->array[j]); + if (l) continue; + if (!ecore_file_is_dir(user_dirs->array[j])) continue; + if (!cache_scan(user_dirs->array[j], NULL, priority, 0, &changed)) goto error; + scanned = eina_list_append(scanned, eina_stringshare_add(user_dirs->array[j])); - if (count != sizeof (int) + size) - printf("Didn't write all data on dirsfd"); - - if (!cache_scan(dir, NULL, priority, 0, &changed)) goto error; - eina_stringshare_del(dir); + store_dirs = eina_list_append(store_dirs, user_dirs->array[j]); } - close(dirsfd); - dirsfd = -1; + store_dirs = eina_list_sort(store_dirs, -1, EINA_COMPARE_CB(strcmp)); + } + + if (extra_dirs) + { + Eina_List *l; + + EINA_LIST_FOREACH(extra_dirs, l, path) + { + Eina_List *ll; + + ll = eina_list_search_unsorted_list(scanned, strcmplen, path); + if (ll) continue; + if (!ecore_file_is_dir(path)) continue; + + /* If we scan a passed dir, we must have changed */ + changed = 1; + if (!cache_scan(path, NULL, priority, 0, &changed)) goto error; + + store_dirs = eina_list_append(store_dirs, path); + } + store_dirs = eina_list_sort(store_dirs, -1, EINA_COMPARE_CB(strcmp)); + } + + if (user_dirs) + { + IF_FREE(user_dirs->array); + free(user_dirs); + } + + /* store user dirs */ + if (store_dirs) + { + Eina_List *l; + + user_dirs = NEW(Efreet_Cache_Array_String, 1); + user_dirs->array = NEW(char *, eina_list_count(store_dirs)); + user_dirs->array_count = 0; + EINA_LIST_FOREACH(store_dirs, l, path) + user_dirs->array[user_dirs->array_count++] = path; + + eet_data_write(ef, efreet_array_string_edd(), EFREET_CACHE_DESKTOP_DIRS, user_dirs, 1); + IF_FREE(user_dirs->array); + free(user_dirs); } /* store util */ @@ -473,6 +500,10 @@ main(int argc, char **argv) if (write(tmpfd, "a", 1) != 1) perror("write"); close(tmpfd); } + EINA_LIST_FREE(scanned, dir) + eina_stringshare_del(dir); + eina_list_free(extra_dirs); + eina_list_free(store_dirs); efreet_shutdown(); ecore_shutdown(); eet_shutdown(); @@ -480,15 +511,19 @@ main(int argc, char **argv) close(lockfd); return 0; error: - if (dirsfd >= 0) close(dirsfd); IF_FREE(dir); edd_error: + if (user_dirs) efreet_cache_array_string_free(user_dirs); efreet_shutdown(); efreet_error: ecore_shutdown(); ecore_error: eet_shutdown(); eet_error: + EINA_LIST_FREE(scanned, dir) + eina_stringshare_del(dir); + eina_list_free(extra_dirs); + eina_list_free(store_dirs); eina_shutdown(); eina_error: if (lockfd >= 0) close(lockfd); diff --git a/legacy/efreet/src/lib/efreet_cache.c b/legacy/efreet/src/lib/efreet_cache.c index 006241a3a4..d8a63e9783 100644 --- a/legacy/efreet/src/lib/efreet_cache.c +++ b/legacy/efreet/src/lib/efreet_cache.c @@ -7,6 +7,7 @@ * browsing. */ +#include #include #include #include @@ -61,8 +62,8 @@ static Eet_Data_Descriptor *hash_array_string_edd = NULL; static Eet_Data_Descriptor *array_string_edd = NULL; static Eet_Data_Descriptor *hash_string_edd = NULL; +static Efreet_Cache_Array_String *desktop_dirs = NULL; static Eet_File *desktop_cache = NULL; -static const char *desktop_cache_dirs = NULL; static const char *desktop_cache_file = NULL; static Ecore_File_Monitor *cache_monitor = NULL; @@ -175,9 +176,10 @@ efreet_cache_shutdown(void) IF_FREE_HASH(icons); IF_FREE_HASH(fallbacks); + efreet_cache_array_string_free(desktop_dirs); + desktop_dirs = NULL; desktop_cache = efreet_cache_close(desktop_cache); IF_RELEASE(desktop_cache_file); - IF_RELEASE(desktop_cache_dirs); if (cache_exe_handler) ecore_event_handler_del(cache_exe_handler); cache_exe_handler = NULL; @@ -401,22 +403,6 @@ efreet_desktop_cache_file(void) return desktop_cache_file; } -/* - * Needs EAPI because of helper binaries - */ -EAPI const char * -efreet_desktop_cache_dirs(void) -{ - char tmp[PATH_MAX] = { '\0' }; - - if (desktop_cache_dirs) return desktop_cache_dirs; - - snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_dirs.cache", efreet_cache_home_get()); - - desktop_cache_dirs = eina_stringshare_add(tmp); - return desktop_cache_dirs; -} - #define EDD_SHUTDOWN(Edd) \ if (Edd) eet_data_descriptor_free(Edd); \ Edd = NULL; @@ -825,6 +811,55 @@ efreet_cache_desktop_free(Efreet_Desktop *desktop) } } +void +efreet_cache_desktop_add(Efreet_Desktop *desktop) +{ + char buf[PATH_MAX]; + char *p; + Efreet_Cache_Array_String *arr; + const char **tmp; + + /* + * Read file from disk, save path in cache so it will be included in next + * cache update + */ + strncpy(buf, desktop->orig_path, PATH_MAX); + buf[PATH_MAX - 1] = '\0'; + p = dirname(buf); + arr = efreet_cache_desktop_dirs(); + if (arr) + { + unsigned int i; + + for (i = 0; i < arr->array_count; i++) + { + /* Check if we already have this dir in cache */ + if (!strcmp(p, arr->array[i])) + return; + } + } + /* TODO: We leak this data, remember and clean up on shutdown */ + if (!arr) + desktop_dirs = arr = NEW(Efreet_Cache_Array_String, 1); + tmp = realloc(arr->array, sizeof (char *) * (arr->array_count + 1)); + if (!tmp) return; + arr->array = tmp; + arr->array[arr->array_count++] = strdup(p); + + efreet_cache_desktop_update(); +} + +Efreet_Cache_Array_String * +efreet_cache_desktop_dirs(void) +{ + if (desktop_dirs) return desktop_dirs; + + if (!efreet_cache_check(&desktop_cache, efreet_desktop_cache_file(), EFREET_DESKTOP_CACHE_MAJOR)) return NULL; + + desktop_dirs = eet_data_read(desktop_cache, efreet_array_string_edd(), EFREET_CACHE_DESKTOP_DIRS); + return desktop_dirs; +} + void efreet_cache_desktop_update(void) { @@ -991,6 +1026,8 @@ cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__, d->ef = desktop_cache; old_desktop_caches = eina_list_append(old_desktop_caches, d); + efreet_cache_array_string_free(desktop_dirs); + desktop_dirs = NULL; efreet_desktop_cache = eina_hash_string_superfast_new(NULL); desktop_cache = NULL; @@ -1066,8 +1103,6 @@ desktop_cache_update_cache_job(void *data __UNUSED__) /* TODO: Retry update cache later */ if (desktop_cache_exe_lock > 0) return; - if (!efreet_desktop_write_cache_dirs_file()) return; - snprintf(file, sizeof(file), "%s/efreet/desktop_exec.lock", efreet_cache_home_get()); desktop_cache_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); @@ -1079,7 +1114,20 @@ desktop_cache_update_cache_job(void *data __UNUSED__) if (fcntl(desktop_cache_exe_lock, F_SETLK, &fl) < 0) goto error; prio = ecore_exe_run_priority_get(); ecore_exe_run_priority_set(19); - desktop_cache_exe = ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_desktop_cache_create", NULL); + eina_strlcpy(file, PACKAGE_LIB_DIR "/efreet/efreet_desktop_cache_create", sizeof(file)); + if (desktop_dirs && desktop_dirs->array_count > 0) + { + unsigned int i; + + eina_strlcat(file, " -d", sizeof(file)); + for (i = 0; i < desktop_dirs->array_count; i++) + { + eina_strlcat(file, " ", sizeof(file)); + eina_strlcat(file, desktop_dirs->array[i], sizeof(file)); + } + } + printf("Run desktop cache creation: %s\n", file); + desktop_cache_exe = ecore_exe_run(file, NULL); ecore_exe_run_priority_set(prio); if (!desktop_cache_exe) goto error; diff --git a/legacy/efreet/src/lib/efreet_cache_private.h b/legacy/efreet/src/lib/efreet_cache_private.h index 72711f3f9f..811d29da87 100644 --- a/legacy/efreet/src/lib/efreet_cache_private.h +++ b/legacy/efreet/src/lib/efreet_cache_private.h @@ -11,6 +11,7 @@ #define EFREET_CACHE_VERSION "__efreet//version" #define EFREET_CACHE_ICON_FALLBACK "__efreet_fallback" +#define EFREET_CACHE_DESKTOP_DIRS "__efreet//desktop_dirs" EAPI const char *efreet_desktop_util_cache_file(void); EAPI const char *efreet_desktop_cache_file(void); diff --git a/legacy/efreet/src/lib/efreet_desktop.c b/legacy/efreet/src/lib/efreet_desktop.c index a0ae66dede..a21b0c0762 100644 --- a/legacy/efreet/src/lib/efreet_desktop.c +++ b/legacy/efreet/src/lib/efreet_desktop.c @@ -20,7 +20,6 @@ extern "C" void *alloca (size_t); #endif -#include #include #include #include @@ -52,11 +51,6 @@ Eina_Hash *efreet_desktop_cache = NULL; */ static const char *desktop_environment = NULL; -/** - * A cache of all unknown desktop dirs - */ -static Eina_List *efreet_desktop_dirs = NULL; - /** * A list of the desktop types available */ @@ -164,14 +158,11 @@ void efreet_desktop_shutdown(void) { Efreet_Desktop_Type_Info *info; - char *dir; IF_RELEASE(desktop_environment); IF_FREE_HASH(efreet_desktop_cache); EINA_LIST_FREE(efreet_desktop_types, info) efreet_desktop_type_info_free(info); - EINA_LIST_FREE(efreet_desktop_dirs, dir) - eina_stringshare_del(dir); IF_FREE_HASH(change_monitors); #ifdef HAVE_EVIL evil_sockets_shutdown(); @@ -223,21 +214,7 @@ efreet_desktop_get(const char *file) if (!desktop) return NULL; if (!desktop->eet) - { - char buf[PATH_MAX]; - char *p; - - /* - * Read file from disk, save path in cache so it will be included in next - * cache update - */ - strncpy(buf, desktop->orig_path, PATH_MAX); - buf[PATH_MAX - 1] = '\0'; - p = dirname(buf); - if (!eina_list_search_unsorted(efreet_desktop_dirs, EINA_COMPARE_CB(strcmp), p)) - efreet_desktop_dirs = eina_list_append(efreet_desktop_dirs, eina_stringshare_add(p)); - efreet_cache_desktop_update(); - } + efreet_cache_desktop_add(desktop); if (efreet_desktop_cache) eina_hash_direct_add(efreet_desktop_cache, desktop->orig_path, desktop); desktop->cached = 1; @@ -777,83 +754,6 @@ efreet_desktop_string_list_join(Eina_List *list) return string; } -int -efreet_desktop_write_cache_dirs_file(void) -{ - char file[PATH_MAX]; - int fd = -1; - int cachefd = -1; - char *dir; - struct stat st; - struct flock fl; - - if (!efreet_desktop_dirs) return 1; - - snprintf(file, sizeof(file), "%s/desktop_data.lock", efreet_cache_home_get()); - fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - if (fd < 0) return 0; - efreet_fsetowner(fd); - /* TODO: Retry update cache later */ - memset(&fl, 0, sizeof(struct flock)); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - if (fcntl(fd, F_SETLK, &fl) < 0) goto error; - - cachefd = open(efreet_desktop_cache_dirs(), O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR); - if (cachefd < 0) goto error; - efreet_fsetowner(cachefd); - if (fstat(cachefd, &st) < 0) goto error; - if (st.st_size > 0) - { - Eina_List *l, *ln; - char *p; - char *map; - - map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, cachefd, 0); - if (map == MAP_FAILED) goto error; - p = map; - while (p < map + st.st_size) - { - unsigned int size = *(unsigned int *)p; - p += sizeof(unsigned int); - EINA_LIST_FOREACH_SAFE(efreet_desktop_dirs, l, ln, dir) - { - if (!strcmp(dir, p)) - { - efreet_desktop_dirs = eina_list_remove_list(efreet_desktop_dirs, l); - eina_stringshare_del(dir); - break; - } - } - p += size; - } - munmap(map, st.st_size); - } - EINA_LIST_FREE(efreet_desktop_dirs, dir) - { - unsigned int size = strlen(dir) + 1; - size_t count; - - count = write(cachefd, &size, sizeof(int)); - count += write(cachefd, dir, size); - - if (count != sizeof(int) + size) - DBG("Didn't write all data on cachefd"); - - efreet_desktop_changes_monitor_add(dir); - eina_stringshare_del(dir); - } - efreet_desktop_dirs = NULL; - if (fd >= 0) close(fd); - if (cachefd >= 0) close(cachefd); - return 1; - -error: - if (fd >= 0) close(fd); - if (cachefd >= 0) close(cachefd); - return 0; -} - /** * @internal * @param desktop The desktop to check @@ -1267,10 +1167,9 @@ efreet_desktop_environment_check(Efreet_Desktop *desktop) static void efreet_desktop_changes_listen(void) { - int dirsfd = -1; + Efreet_Cache_Array_String *arr; Eina_List *dirs; - char *path; - struct stat st; + const char *path; if (!efreet_cache_update) return; @@ -1287,33 +1186,14 @@ efreet_desktop_changes_listen(void) eina_stringshare_del(path); } - dirsfd = open(efreet_desktop_cache_dirs(), O_RDONLY, S_IRUSR | S_IWUSR); - if (dirsfd >= 0) + arr = efreet_cache_desktop_dirs(); + if (arr) { - if ((fstat(dirsfd, &st) == 0) && (st.st_size > 0)) - { - char *p; - char *map; + unsigned int i; - map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, dirsfd, 0); - if (map == MAP_FAILED) goto error; - p = map; - while (p < map + st.st_size) - { - unsigned int size = *(unsigned int *)p; - p += sizeof(unsigned int); - if (ecore_file_is_dir(p)) - efreet_desktop_changes_monitor_add(p); - p += size; - } - munmap(map, st.st_size); - } - close(dirsfd); + for (i = 0; i < arr->array_count; i++) + efreet_desktop_changes_monitor_add(arr->array[i]); } - - return; -error: - if (dirsfd >= 0) close(dirsfd); } static void diff --git a/legacy/efreet/src/lib/efreet_private.h b/legacy/efreet/src/lib/efreet_private.h index 2613a88851..ff73e322cf 100644 --- a/legacy/efreet/src/lib/efreet_private.h +++ b/legacy/efreet/src/lib/efreet_private.h @@ -180,15 +180,13 @@ size_t efreet_array_cat(char *buffer, size_t size, const char *strs[]); const char *efreet_desktop_environment_get(void); -/* TODO: Find the best placement for these */ -EAPI const char *efreet_desktop_cache_dirs(void); -int efreet_desktop_write_cache_dirs_file(void); - void efreet_cache_desktop_update(void); void efreet_cache_icon_update(void); Efreet_Desktop *efreet_cache_desktop_find(const char *file); void efreet_cache_desktop_free(Efreet_Desktop *desktop); +void efreet_cache_desktop_add(Efreet_Desktop *desktop); +Efreet_Cache_Array_String *efreet_cache_desktop_dirs(void); Efreet_Cache_Icon *efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon); Efreet_Cache_Fallback_Icon *efreet_cache_icon_fallback_find(const char *icon);