Store unknown .desktop file dirs

SVN revision: 46829
This commit is contained in:
Sebastian Dransfeld 2010-03-03 12:28:21 +00:00
parent c196b7d701
commit d07a67ad63
2 changed files with 97 additions and 0 deletions

View File

@ -10,6 +10,10 @@
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <libgen.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/mman.h>
#ifdef _WIN32
# include <winsock2.h>
@ -39,11 +43,21 @@ static Eina_Hash *efreet_desktop_cache = NULL;
*/
static Eina_List *efreet_desktop_types = NULL;
/**
* A cache of all unknown desktop dirs
*/
static Eina_List *efreet_desktop_dirs = NULL;
/**
* A unique id for each tmp file created while building a command
*/
static int efreet_desktop_command_file_id = 0;
/**
* A job pointer for cache updates
*/
static Ecore_Job *efreet_desktop_job = NULL;
static char *cache_file = NULL;
static Eet_File *cache = NULL;
static Eet_Data_Descriptor *desktop_edd = NULL;
@ -137,6 +151,8 @@ static void efreet_desktop_type_info_free(Efreet_Desktop_Type_Info *info);
static int efreet_desktop_command_flags_get(Efreet_Desktop *desktop);
static void *efreet_desktop_command_execs_process(Efreet_Desktop_Command *command, Eina_List *execs);
static void efreet_desktop_update_cache_dirs(void *data);
/**
* @internal
* @return Returns > 0 on success or 0 on failure
@ -198,6 +214,7 @@ void
efreet_desktop_shutdown(void)
{
Efreet_Desktop_Type_Info *info;
char *dir;
IF_RELEASE(desktop_environment);
IF_FREE_HASH(efreet_desktop_cache);
@ -208,11 +225,15 @@ efreet_desktop_shutdown(void)
efreet_desktop_types = eina_list_remove_list(efreet_desktop_types,
efreet_desktop_types);
}
EINA_LIST_FREE(efreet_desktop_dirs, dir)
free(dir);
if (cache) eet_close(cache);
efreet_desktop_edd_shutdown(desktop_edd);
ecore_file_shutdown();
eina_log_domain_unregister(_efreet_desktop_log_dom);
IF_FREE(cache_file);
if (efreet_desktop_job) ecore_job_del(efreet_desktop_job);
efreet_desktop_job = NULL;
}
/*
@ -359,6 +380,8 @@ efreet_desktop_new(const char *file)
/* TODO: Need file monitor on file and events to notify change */
Efreet_Desktop *desktop = NULL;
char *rp = NULL;
char *p;
char buf[PATH_MAX];
rp = ecore_file_realpath(file);
if (cache)
@ -389,6 +412,16 @@ efreet_desktop_new(const char *file)
desktop->ref = 1;
strncpy(buf, rp, 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, strdup(p));
if (efreet_desktop_job) ecore_job_del(efreet_desktop_job);
efreet_desktop_job = ecore_job_add(efreet_desktop_update_cache_dirs, NULL);
}
return desktop;
error:
if (desktop) efreet_desktop_free(desktop);
@ -2012,3 +2045,64 @@ efreet_desktop_edd_shutdown(Eet_Data_Descriptor *edd)
eet_data_descriptor_free(edd);
}
static void
efreet_desktop_update_cache_dirs(void *data __UNUSED__)
{
char file[PATH_MAX];
int fd = -1;
int cachefd = -1;
char *map = MAP_FAILED;
char *dir;
struct stat st;
snprintf(file, sizeof(file), "%s/.efreet", efreet_home_dir_get());
if (!ecore_file_mkpath(file)) return;
snprintf(file, sizeof(file), "%s/.efreet/lock", efreet_home_dir_get());
fd = open(file, O_CREAT | O_TRUNC | O_RDONLY, S_IRUSR | S_IWUSR);
if (fd < 0) return;
/* TODO: Retry update cache later */
if (flock(fd, LOCK_EX | LOCK_NB) < 0) goto error;
snprintf(file, sizeof(file), "%s/.efreet/desktop_dirs.cache", efreet_home_dir_get());
cachefd = open(file, O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR);
if (cachefd < 0) goto error;
if (fstat(cachefd, &st) < 0) goto error;
if (st.st_size > 0)
{
Eina_List *l, *ln;
char *p;
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);
free(dir);
break;
}
}
p += size;
}
}
EINA_LIST_FREE(efreet_desktop_dirs, dir)
{
unsigned int size = strlen(dir) + 1;
write(cachefd, &size, sizeof(int));
write(cachefd, dir, size);
}
efreet_desktop_dirs = NULL;
error:
if (map != MAP_FAILED) munmap(map, st.st_size);
if (fd > 0) close(fd);
if (cachefd > 0) close(cachefd);
efreet_desktop_job = NULL;
}

View File

@ -129,6 +129,8 @@ check(void)
}
printf("time: %.3f\n", (ecore_time_get() - start));
desktop = efreet_desktop_get("/opt/google/chrome/google-chrome.desktop");
if (desktop) efreet_desktop_free(desktop);
}
int
@ -137,6 +139,7 @@ main(int argc __UNUSED__, char **argv __UNUSED__)
if (!efreet_init()) return 1;
if (!efreet_util_init()) return 1;
check();
ecore_main_loop_begin();
efreet_util_shutdown();
efreet_shutdown();
return 0;