#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
+#include <signal.h>
+#include <setjmp.h>
#include "tvheadend.h"
#include "queue.h"
}
}
+/*
+ * Recovery
+ */
+static sigjmp_buf epg_mmap_env;
+
+static void epg_mmap_sigbus (int sig, siginfo_t *siginfo, void *ptr)
+{
+ siglongjmp(epg_mmap_env, 1);
+}
+
/*
* Load data
*/
uint8_t *mem, *rp;
epggrab_stats_t stats;
int ver = EPG_DB_VERSION;
+ struct sigaction act, oldact;
char *sect = NULL;
/* Find the right file (and version) */
tvhlog(LOG_DEBUG, "epgdb", "database does not exist");
return;
}
+
+ memset (&act, 0, sizeof(act));
+ act.sa_sigaction = epg_mmap_sigbus;
+ act.sa_flags = SA_SIGINFO;
+ if (sigaction(SIGBUS, &act, &oldact)) {
+ tvhlog(LOG_ERR, "epgdb", "failed to install SIGBUS handler");
+ close(fd);
+ return;
+ }
/* Map file to memory */
if ( fstat(fd, &st) != 0 ) {
goto end;
}
+ if (sigsetjmp(epg_mmap_env, 1)) {
+ tvhlog(LOG_ERR, "epgdb", "failed to read from mapped file");
+ if (mem)
+ munmap(mem, st.st_size);
+ goto end;
+ }
+
/* Process */
memset(&stats, 0, sizeof(stats));
while ( remain > 4 ) {
/* Close file */
munmap(mem, st.st_size);
end:
+ sigaction(SIGBUS, &oldact, NULL);
close(fd);
}