forked from enlightenment/efl
evas generic pdf - handle cleanupp on crashes in poppler and other errors
if poppler_init fails or it crashes in poppler or a timeout we didnt clean up the tmpdir... this forces a cleanuo and ups timeout to 30sec.
This commit is contained in:
parent
dc0173fdf6
commit
a43c2dad50
|
@ -1,3 +1,6 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
static void (*timeout_func) (void) = NULL;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
@ -8,6 +11,7 @@ _timeout(void *arg)
|
||||||
{
|
{
|
||||||
int s = (int)(uintptr_t)arg;
|
int s = (int)(uintptr_t)arg;
|
||||||
Sleep(s * 1000);
|
Sleep(s * 1000);
|
||||||
|
if (timeout_func) timeout_func();
|
||||||
_Exit(-1);
|
_Exit(-1);
|
||||||
_endthreadex(0);
|
_endthreadex(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -26,6 +30,7 @@ timeout_init(int seconds)
|
||||||
static void
|
static void
|
||||||
_timeout(int val)
|
_timeout(int val)
|
||||||
{
|
{
|
||||||
|
if (timeout_func) timeout_func();
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
if (val) return;
|
if (val) return;
|
||||||
}
|
}
|
||||||
|
@ -37,3 +42,9 @@ timeout_init(int seconds)
|
||||||
alarm(seconds);
|
alarm(seconds);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
timeout_func_set(void (*func) (void))
|
||||||
|
{
|
||||||
|
timeout_func = func;
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void timeout_init(int seconds);
|
void timeout_init(int seconds);
|
||||||
|
void timeout_func_set(void (*func) (void));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,11 @@
|
||||||
#include "shmfile.h"
|
#include "shmfile.h"
|
||||||
#include "timeout.h"
|
#include "timeout.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DATA32 unsigned int
|
#define DATA32 unsigned int
|
||||||
typedef char RGB24[3];
|
typedef char RGB24[3];
|
||||||
|
|
||||||
|
@ -192,11 +197,43 @@ void poppler_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED)
|
||||||
delete renderer;
|
delete renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Tmpstr *tmpdir = NULL;
|
||||||
|
static Eina_Tmpstr *generated = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
tmp_cleanup(void)
|
||||||
|
{
|
||||||
|
if (tmpdir)
|
||||||
|
{
|
||||||
|
if (generated)
|
||||||
|
{
|
||||||
|
unlink(generated);
|
||||||
|
}
|
||||||
|
if (rmdir(tmpdir) < 0)
|
||||||
|
{
|
||||||
|
D("Failed to delete tmpdir %s\n", tmpdir);
|
||||||
|
}
|
||||||
|
eina_tmpstr_del(tmpdir);
|
||||||
|
tmpdir = NULL;
|
||||||
|
if (generated)
|
||||||
|
{
|
||||||
|
eina_tmpstr_del(generated);
|
||||||
|
generated = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_crash(int val)
|
||||||
|
{
|
||||||
|
D("Crash\n");
|
||||||
|
tmp_cleanup();
|
||||||
|
_exit(-1 | val);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Eina_Tmpstr *tmpdir = NULL;
|
|
||||||
Eina_Tmpstr *generated = NULL;
|
|
||||||
char *extension;
|
char *extension;
|
||||||
char *dir;
|
char *dir;
|
||||||
char *file;
|
char *file;
|
||||||
|
@ -204,6 +241,7 @@ main(int argc, char **argv)
|
||||||
int size_w = 0, size_h = 0;
|
int size_w = 0, size_h = 0;
|
||||||
int head_only = 0;
|
int head_only = 0;
|
||||||
int page_num = 0;
|
int page_num = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (argc < 2) return -1;
|
if (argc < 2) return -1;
|
||||||
// file is ALWAYS first arg, other options come after
|
// file is ALWAYS first arg, other options come after
|
||||||
|
@ -247,6 +285,18 @@ main(int argc, char **argv)
|
||||||
dir = dirname(argv[0]);
|
dir = dirname(argv[0]);
|
||||||
if (extension && dir && strcmp(extension, ".pdf"))
|
if (extension && dir && strcmp(extension, ".pdf"))
|
||||||
{
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
signal(SIGSEGV, _crash);
|
||||||
|
signal(SIGBUS, _crash);
|
||||||
|
signal(SIGFPE, _crash);
|
||||||
|
signal(SIGABRT, _crash);
|
||||||
|
signal(SIGILL, _crash);
|
||||||
|
signal(SIGSYS, _crash);
|
||||||
|
signal(SIGINT, _crash);
|
||||||
|
signal(SIGTERM, _crash);
|
||||||
|
signal(SIGQUIT, _crash);
|
||||||
|
#endif
|
||||||
|
timeout_func_set(tmp_cleanup);
|
||||||
if (eina_file_mkdtemp("evas_generic_pdf_loaderXXXXXX", &tmpdir))
|
if (eina_file_mkdtemp("evas_generic_pdf_loaderXXXXXX", &tmpdir))
|
||||||
{
|
{
|
||||||
Eina_Strbuf *tmp;
|
Eina_Strbuf *tmp;
|
||||||
|
@ -270,6 +320,7 @@ main(int argc, char **argv)
|
||||||
pclose(cmd);
|
pclose(cmd);
|
||||||
|
|
||||||
filename = basename(file);
|
filename = basename(file);
|
||||||
|
|
||||||
generated = eina_tmpstr_add_length(filename, strlen(filename) - strlen(extension));
|
generated = eina_tmpstr_add_length(filename, strlen(filename) - strlen(extension));
|
||||||
|
|
||||||
eina_strbuf_append_printf(tmp, "%s/%s.pdf", tmpdir, generated);
|
eina_strbuf_append_printf(tmp, "%s/%s.pdf", tmpdir, generated);
|
||||||
|
@ -291,12 +342,15 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's force a timeout if things go wrong
|
// Let's force a timeout if things go wrong
|
||||||
timeout_init(10);
|
timeout_init(30);
|
||||||
|
|
||||||
// Now process the pdf (or the generated pdf)
|
// Now process the pdf (or the generated pdf)
|
||||||
D("poppler_file_init\n");
|
D("poppler_file_init\n");
|
||||||
if (!poppler_init(file, page_num, size_w, size_h))
|
if (!poppler_init(file, page_num, size_w, size_h))
|
||||||
return -1;
|
{
|
||||||
|
goto cleanup;
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
D("poppler_file_init done\n");
|
D("poppler_file_init done\n");
|
||||||
|
|
||||||
D("dpi2...: %f\n", dpi);
|
D("dpi2...: %f\n", dpi);
|
||||||
|
@ -338,18 +392,9 @@ main(int argc, char **argv)
|
||||||
printf("done\n");
|
printf("done\n");
|
||||||
|
|
||||||
poppler_shutdown();
|
poppler_shutdown();
|
||||||
|
cleanup:
|
||||||
if (tmpdir)
|
timeout_func_set(NULL);
|
||||||
{
|
tmp_cleanup();
|
||||||
if (generated) unlink(generated);
|
|
||||||
if (rmdir(tmpdir) < 0)
|
|
||||||
{
|
|
||||||
D("Failed to delete tmpdir %s\n", tmpdir);
|
|
||||||
}
|
|
||||||
|
|
||||||
eina_tmpstr_del(tmpdir);
|
|
||||||
eina_tmpstr_del(generated);
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue