#include "config.h" #include "e_precache.h" static void *lib_eina = NULL; static void *lib_ecore = NULL; static void *lib_ecore_file = NULL; static void *lib_ecore_x = NULL; static void *lib_evas = NULL; static void *lib_edje = NULL; static void *lib_eet = NULL; static int *e_precache_end = NULL; /* internal calls */ static int log_fd = -1; static int do_log = 0; static void log_open(void) { char buf[4096] = "DUMMY", *home; if (log_fd != -1) return; if (!e_precache_end) { #ifdef HAVE_UNSETENV unsetenv("LD_PRELOAD"); #else if (getenv("LD_PRELOAD")) putenv("LD_PRELOAD"); #endif e_precache_end = dlsym(NULL, "e_precache_end"); } if (!e_precache_end) return; if (*e_precache_end) return; home = getenv("HOME"); if (home) snprintf(buf, sizeof(buf), "%s/.e-precache", home); else snprintf(buf, sizeof(buf), "/tmp/.e-precache"); log_fd = open(buf, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); if (log_fd) do_log = 1; } static void log_close(void) { if (log_fd >= 0) { close(log_fd); log_fd = -1; } do_log = 0; } static void log_write(const char *type, const char *file) { static Eina_Hash *s_hash = NULL; static Eina_Hash *o_hash = NULL; static Eina_Hash *d_hash = NULL; char buf[2]; if ((e_precache_end) && (*e_precache_end)) { log_close(); return; } if (type[0] == 's') { if (eina_hash_find(s_hash, file)) return; if (!s_hash) s_hash = eina_hash_string_superfast_new(NULL); eina_hash_add(s_hash, file, (void *)1); } else if (type[0] == 'o') { if (eina_hash_find(o_hash, file)) return; if (!o_hash) o_hash = eina_hash_string_superfast_new(NULL); eina_hash_add(o_hash, file, (void *)1); } else if (type[0] == 'd') { if (eina_hash_find(d_hash, file)) return; if (!d_hash) d_hash = eina_hash_string_superfast_new(NULL); eina_hash_add(d_hash, file, (void *)1); } buf[0] = type[0]; buf[1] = ' '; write(log_fd, buf, 2); write(log_fd, file, strlen(file)); write(log_fd, "\n", 1); } static void * lib_func(const char *lib1, const char *lib2, const char *fname, const char *libname, void **lib) { void *func; if (!*lib) *lib = dlopen(lib1, RTLD_GLOBAL | RTLD_LAZY); if (!*lib) *lib = dlopen(lib2, RTLD_GLOBAL | RTLD_LAZY); func = dlsym(*lib, fname); if (!func) { printf("ABORT: Can't find %s() in %s or %s (%s = %p)\n", fname, lib1, lib2, libname, *lib); abort(); } log_open(); return func; } /* intercepts */ Eina_Module * eina_module_find(const Eina_Array *array, const char *module) { static Eina_Module *(*func) (const Eina_Array *array, const char *module) = NULL; if (!func) func = lib_func("libeina.so", "libeina.so.1", "eina_module_find", "lib_eina", &lib_eina); if (do_log) log_write("o", module); return (*func) (array, module); } void ecore_app_args_set(int argc, const char **argv) { static void (*func) (int argc, const char **argv) = NULL; if (!func) func = lib_func("libecore.so", "libecore.so.1", "ecore_app_args_set", "lib_ecore", &lib_ecore); if (do_log) log_write("o", (const char *)argv); (*func) (argc, argv); } long long ecore_file_mod_time(const char *file) { static long long (*func) (const char *file) = NULL; if (!func) func = lib_func("libecore_file.so", "libecore_file.so.1", "ecore_file_mod_time", "lib_ecore_file", &lib_ecore_file); if (do_log) log_write("s", file); return (*func) (file); } long long ecore_file_size(const char *file) { static int (*func) (const char *file) = NULL; if (!func) func = lib_func("libecore_file.so", "libecore_file.so.1", "ecore_file_size", "lib_ecore_file", &lib_ecore_file); if (do_log) log_write("s", file); return (*func) (file); } Eina_Bool ecore_file_exists(const char *file) { static int (*func) (const char *file) = NULL; if (!func) func = lib_func("libecore_file.so", "libecore_file.so.1", "ecore_file_exists", "lib_ecore_file", &lib_ecore_file); if (do_log) log_write("s", file); return (*func) (file); } Eina_Bool ecore_file_is_dir(const char *file) { static int (*func) (const char *file) = NULL; if (!func) func = lib_func("libecore_file.so", "libecore_file.so.1", "ecore_file_is_dir", "lib_ecore_file", &lib_ecore_file); if (do_log) log_write("s", file); return (*func) (file); } Eina_Bool ecore_file_can_read(const char *file) { static int (*func) (const char *file) = NULL; if (!func) func = lib_func("libecore_file.so", "libecore_file.so.1", "ecore_file_can_read", "lib_ecore_file", &lib_ecore_file); if (do_log) log_write("s", file); return (*func) (file); } Eina_Bool ecore_file_can_write(const char *file) { static int (*func) (const char *file) = NULL; if (!func) func = lib_func("libecore_file.so", "libecore_file.so.1", "ecore_file_can_write", "lib_ecore_file", &lib_ecore_file); if (do_log) log_write("s", file); return (*func) (file); } Eina_Bool ecore_file_can_exec(const char *file) { static int (*func) (const char *file) = NULL; if (!func) func = lib_func("libecore_file.so", "libecore_file.so.1", "ecore_file_can_exec", "lib_ecore_file", &lib_ecore_file); if (do_log) log_write("s", file); return (*func) (file); } Eina_List * ecore_file_ls(const char *file) { static Eina_List * (*func) (const char *file) = NULL; if (!func) func = lib_func("libecore_file.so", "libecore_file.so.1", "ecore_file_ls", "lib_ecore_file", &lib_ecore_file); if (do_log) log_write("d", file); return (*func) (file); } int ecore_x_init(const char *name) { static int (*func) (const char *name) = NULL; if (!func) func = lib_func("libecore_x.so", "libecore_x.so.1", "ecore_x_init", "lib_ecore_x", &lib_ecore_x); if (do_log) log_write("o", name); return (*func) (name); } void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) { static void (*func) (Evas_Object *obj, const char *file, const char *key) = NULL; if (!func) func = lib_func("libevas.so", "libevas.so.1", "evas_object_image_file_set", "lib_evas", &lib_evas); if (do_log) log_write("o", file); (*func) (obj, file, key); } /* edje */ Eina_Bool edje_object_file_set(Evas_Object *obj, const char *file, const char *group) { static Eina_Bool (*func) (Evas_Object *obj, const char *file, const char *group) = NULL; if (!func) func = lib_func("libedje.so", "libedje.so.1", "edje_object_file_set", "lib_edje", &lib_edje); if (do_log) log_write("o", file); return (*func) (obj, file, group); } Eet_File * eet_open(const char *file, Eet_File_Mode mode) { static Eet_File * (*func) (const char *file, Eet_File_Mode mode) = NULL; if (!func) func = lib_func("libeet.so", "libeet.so.0", "eet_open", "lib_eet", &lib_eet); if (do_log) log_write("o", file); return (*func) (file, mode); }