summaryrefslogtreecommitdiff
path: root/apps/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugin.c')
-rw-r--r--apps/plugin.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index a1ffa3abe1..0d4d8ed0f6 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -63,6 +63,15 @@
63#define PREFIX 63#define PREFIX
64#endif 64#endif
65 65
66#if defined(HAVE_PLUGIN_CHECK_OPEN_CLOSE) && (MAX_OPEN_FILES>32)
67#warning "MAX_OPEN_FILES>32, disabling plugin file open/close checking"
68#undef HAVE_PLUGIN_CHECK_OPEN_CLOSE
69#endif
70
71#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
72static unsigned int open_files;
73#endif
74
66#ifdef SIMULATOR 75#ifdef SIMULATOR
67static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE]; 76static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE];
68void *sim_plugin_load(char *plugin, void **pd); 77void *sim_plugin_load(char *plugin, void **pd);
@@ -83,6 +92,13 @@ static char current_plugin[MAX_PATH];
83 92
84char *plugin_get_current_filename(void); 93char *plugin_get_current_filename(void);
85 94
95#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
96/* Some wrappers used to monitor open and close and detect leaks*/
97static int open_wrapper(const char* pathname, int flags);
98static int close_wrapper(int fd);
99static int creat_wrapper(const char *pathname);
100#endif
101
86static const struct plugin_api rockbox_api = { 102static const struct plugin_api rockbox_api = {
87 103
88 /* lcd */ 104 /* lcd */
@@ -276,11 +292,20 @@ static const struct plugin_api rockbox_api = {
276#endif /* HAVE_BUTTON_LIGHT */ 292#endif /* HAVE_BUTTON_LIGHT */
277 293
278 /* file */ 294 /* file */
295#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
296 (open_func)open_wrapper,
297 close_wrapper,
298#else
279 (open_func)PREFIX(open), 299 (open_func)PREFIX(open),
280 PREFIX(close), 300 PREFIX(close),
301 #endif
281 (read_func)PREFIX(read), 302 (read_func)PREFIX(read),
282 PREFIX(lseek), 303 PREFIX(lseek),
304#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
305 (creat_func)creat_wrapper,
306#else
283 (creat_func)PREFIX(creat), 307 (creat_func)PREFIX(creat),
308#endif
284 (write_func)PREFIX(write), 309 (write_func)PREFIX(write),
285 PREFIX(remove), 310 PREFIX(remove),
286 PREFIX(rename), 311 PREFIX(rename),
@@ -805,8 +830,12 @@ int plugin_load(const char* plugin, const void* parameter)
805 touchscreen_set_mode(TOUCHSCREEN_BUTTON); 830 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
806#endif 831#endif
807 832
833#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
834 open_files = 0;
835#endif
836
808 rc = hdr->entry_point(parameter); 837 rc = hdr->entry_point(parameter);
809 838
810 /* Go back to the global setting in case the plugin changed it */ 839 /* Go back to the global setting in case the plugin changed it */
811#ifdef HAVE_TOUCHSCREEN 840#ifdef HAVE_TOUCHSCREEN
812 touchscreen_set_mode(global_settings.touch_mode); 841 touchscreen_set_mode(global_settings.touch_mode);
@@ -850,6 +879,25 @@ int plugin_load(const char* plugin, const void* parameter)
850 if (pfn_tsr_exit == NULL) 879 if (pfn_tsr_exit == NULL)
851 plugin_loaded = false; 880 plugin_loaded = false;
852 881
882#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
883 if(open_files != 0 && !plugin_loaded)
884 {
885 int fd;
886 logf("Plugin '%s' leaks file handles", plugin);
887
888 static const char *lines[] =
889 { ID2P(LANG_PLUGIN_ERROR),
890 "#leak-file-handles" };
891 static const struct text_message message={ lines, 2 };
892 button_clear_queue(); /* Empty the keyboard buffer */
893 gui_syncyesno_run(&message, NULL, NULL);
894
895 for(fd=0; fd < MAX_OPEN_FILES; fd++)
896 if(open_files & (1<<fd))
897 close_wrapper(fd);
898 }
899#endif
900
853 sim_plugin_close(pd); 901 sim_plugin_close(pd);
854 902
855 if (rc == PLUGIN_ERROR) 903 if (rc == PLUGIN_ERROR)
@@ -926,3 +974,37 @@ char *plugin_get_current_filename(void)
926{ 974{
927 return current_plugin; 975 return current_plugin;
928} 976}
977
978#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
979static int open_wrapper(const char* pathname, int flags)
980{
981 int fd = PREFIX(open)(pathname,flags);
982
983 if(fd >= 0)
984 open_files |= 1<<fd;
985
986 return fd;
987}
988
989static int close_wrapper(int fd)
990{
991 if((~open_files) & (1<<fd))
992 {
993 logf("double close from plugin");
994 }
995 if(fd >= 0)
996 open_files &= (~(1<<fd));
997
998 return PREFIX(close)(fd);
999}
1000
1001static int creat_wrapper(const char *pathname)
1002{
1003 int fd = PREFIX(creat)(pathname);
1004
1005 if(fd >= 0)
1006 open_files |= (1<<fd);
1007
1008 return fd;
1009}
1010#endif /* HAVE_PLUGIN_CHECK_OPEN_CLOSE */