# HG changeset patch # User nadvornik # Date 1233252341 0 # Node ID 1267d17986f33af9c88d472e77f04b5c53c47144 # Parent 0b94f0e6e3d0b6b7956075e29e34215a39b7802c added SIGBUS handler diff -r 0b94f0e6e3d0 -r 1267d17986f3 src/main.c --- a/src/main.c Mon Jan 26 21:08:05 2009 +0000 +++ b/src/main.c Thu Jan 29 18:05:41 2009 +0000 @@ -34,6 +34,8 @@ #include /* for keyboard values */ +#include +#include #include #ifdef G_OS_UNIX @@ -661,6 +663,39 @@ exit_program_final(); } + + +/* This code is supposed to handle situation when a file mmaped by image_loader + * or by exif loader is truncated by some other process. + * This is probably not completely correct according to posix, because + * mmap is not in the list of calls that can be used safely in signal handler, + * but anyway, the handler is called in situation when the application would + * crash otherwise. + * Ideas for improvement are welcome ;) + */ +/* FIXME: this probably needs some better ifdefs. Please report any compilation problems */ + +#ifdef SIGBUS +static void sigbus_handler_cb(int signum, siginfo_t *info, void *context) +{ + unsigned long pagesize = sysconf(_SC_PAGE_SIZE); + DEBUG_1("SIGBUS %p", info->si_addr); + mmap((void *)(((unsigned long)info->si_addr / pagesize) * pagesize), pagesize, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +} +#endif + +static void setup_sigbus_handler(void) +{ +#ifdef SIGBUS + struct sigaction sigbus_action; + sigfillset(&sigbus_action.sa_mask); + sigbus_action.sa_sigaction = sigbus_handler_cb; + sigbus_action.sa_flags = SA_SIGINFO; + + sigaction(SIGBUS, &sigbus_action, NULL); +#endif +} + gint main(gint argc, gchar *argv[]) { LayoutWindow *lw; @@ -699,6 +734,8 @@ log_printf("%s %s, This is an alpha release.\n", GQ_APPNAME, VERSION); #endif + setup_sigbus_handler(); + /* register global notify functions */ file_data_register_notify_func(cache_notify_cb, NULL, NOTIFY_PRIORITY_HIGH); file_data_register_notify_func(thumb_notify_cb, NULL, NOTIFY_PRIORITY_HIGH);