diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2020-12-12 02:22:06 +0000 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2020-12-12 02:22:06 +0000 |
commit | a43c2dad505dbce76b955422c41091fc5b0efc2b (patch) | |
tree | 4b994abfcf006e685b073e6a44d74af8494b5fd0 | |
parent | dc0173fdf6d586f9167643213850c8b08b8ff3fa (diff) |
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.
-rw-r--r-- | src/generic/evas/common/timeout.c | 11 | ||||
-rw-r--r-- | src/generic/evas/common/timeout.h | 1 | ||||
-rw-r--r-- | src/generic/evas/pdf/main.cpp | 79 |
3 files changed, 74 insertions, 17 deletions
diff --git a/src/generic/evas/common/timeout.c b/src/generic/evas/common/timeout.c index 844884c8e0..1b05a7db56 100644 --- a/src/generic/evas/common/timeout.c +++ b/src/generic/evas/common/timeout.c | |||
@@ -1,3 +1,6 @@ | |||
1 | #include <stdio.h> | ||
2 | static void (*timeout_func) (void) = NULL; | ||
3 | |||
1 | #ifdef _WIN32 | 4 | #ifdef _WIN32 |
2 | # include <stdio.h> | 5 | # include <stdio.h> |
3 | # include <windows.h> | 6 | # include <windows.h> |
@@ -8,6 +11,7 @@ _timeout(void *arg) | |||
8 | { | 11 | { |
9 | int s = (int)(uintptr_t)arg; | 12 | int s = (int)(uintptr_t)arg; |
10 | Sleep(s * 1000); | 13 | Sleep(s * 1000); |
14 | if (timeout_func) timeout_func(); | ||
11 | _Exit(-1); | 15 | _Exit(-1); |
12 | _endthreadex(0); | 16 | _endthreadex(0); |
13 | return 0; | 17 | return 0; |
@@ -26,6 +30,7 @@ timeout_init(int seconds) | |||
26 | static void | 30 | static void |
27 | _timeout(int val) | 31 | _timeout(int val) |
28 | { | 32 | { |
33 | if (timeout_func) timeout_func(); | ||
29 | _exit(-1); | 34 | _exit(-1); |
30 | if (val) return; | 35 | if (val) return; |
31 | } | 36 | } |
@@ -37,3 +42,9 @@ timeout_init(int seconds) | |||
37 | alarm(seconds); | 42 | alarm(seconds); |
38 | } | 43 | } |
39 | #endif | 44 | #endif |
45 | |||
46 | void | ||
47 | timeout_func_set(void (*func) (void)) | ||
48 | { | ||
49 | timeout_func = func; | ||
50 | } | ||
diff --git a/src/generic/evas/common/timeout.h b/src/generic/evas/common/timeout.h index 2ea039badf..5cd4c8b54d 100644 --- a/src/generic/evas/common/timeout.h +++ b/src/generic/evas/common/timeout.h | |||
@@ -6,6 +6,7 @@ extern "C" { | |||
6 | #endif | 6 | #endif |
7 | 7 | ||
8 | void timeout_init(int seconds); | 8 | void timeout_init(int seconds); |
9 | void timeout_func_set(void (*func) (void)); | ||
9 | 10 | ||
10 | #ifdef __cplusplus | 11 | #ifdef __cplusplus |
11 | } | 12 | } |
diff --git a/src/generic/evas/pdf/main.cpp b/src/generic/evas/pdf/main.cpp index c7c3ee13bd..5c70bfef21 100644 --- a/src/generic/evas/pdf/main.cpp +++ b/src/generic/evas/pdf/main.cpp | |||
@@ -18,6 +18,11 @@ | |||
18 | #include "shmfile.h" | 18 | #include "shmfile.h" |
19 | #include "timeout.h" | 19 | #include "timeout.h" |
20 | 20 | ||
21 | #ifndef _WIN32 | ||
22 | # include <unistd.h> | ||
23 | # include <signal.h> | ||
24 | #endif | ||
25 | |||
21 | #define DATA32 unsigned int | 26 | #define DATA32 unsigned int |
22 | typedef char RGB24[3]; | 27 | typedef char RGB24[3]; |
23 | 28 | ||
@@ -192,11 +197,43 @@ void poppler_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED) | |||
192 | delete renderer; | 197 | delete renderer; |
193 | } | 198 | } |
194 | 199 | ||
200 | static Eina_Tmpstr *tmpdir = NULL; | ||
201 | static Eina_Tmpstr *generated = NULL; | ||
202 | |||
203 | static void | ||
204 | tmp_cleanup(void) | ||
205 | { | ||
206 | if (tmpdir) | ||
207 | { | ||
208 | if (generated) | ||
209 | { | ||
210 | unlink(generated); | ||
211 | } | ||
212 | if (rmdir(tmpdir) < 0) | ||
213 | { | ||
214 | D("Failed to delete tmpdir %s\n", tmpdir); | ||
215 | } | ||
216 | eina_tmpstr_del(tmpdir); | ||
217 | tmpdir = NULL; | ||
218 | if (generated) | ||
219 | { | ||
220 | eina_tmpstr_del(generated); | ||
221 | generated = NULL; | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | static void | ||
227 | _crash(int val) | ||
228 | { | ||
229 | D("Crash\n"); | ||
230 | tmp_cleanup(); | ||
231 | _exit(-1 | val); | ||
232 | } | ||
233 | |||
195 | int | 234 | int |
196 | main(int argc, char **argv) | 235 | main(int argc, char **argv) |
197 | { | 236 | { |
198 | Eina_Tmpstr *tmpdir = NULL; | ||
199 | Eina_Tmpstr *generated = NULL; | ||
200 | char *extension; | 237 | char *extension; |
201 | char *dir; | 238 | char *dir; |
202 | char *file; | 239 | char *file; |
@@ -204,6 +241,7 @@ main(int argc, char **argv) | |||
204 | int size_w = 0, size_h = 0; | 241 | int size_w = 0, size_h = 0; |
205 | int head_only = 0; | 242 | int head_only = 0; |
206 | int page_num = 0; | 243 | int page_num = 0; |
244 | int ret = 0; | ||
207 | 245 | ||
208 | if (argc < 2) return -1; | 246 | if (argc < 2) return -1; |
209 | // file is ALWAYS first arg, other options come after | 247 | // file is ALWAYS first arg, other options come after |
@@ -247,6 +285,18 @@ main(int argc, char **argv) | |||
247 | dir = dirname(argv[0]); | 285 | dir = dirname(argv[0]); |
248 | if (extension && dir && strcmp(extension, ".pdf")) | 286 | if (extension && dir && strcmp(extension, ".pdf")) |
249 | { | 287 | { |
288 | #ifndef _WIN32 | ||
289 | signal(SIGSEGV, _crash); | ||
290 | signal(SIGBUS, _crash); | ||
291 | signal(SIGFPE, _crash); | ||
292 | signal(SIGABRT, _crash); | ||
293 | signal(SIGILL, _crash); | ||
294 | signal(SIGSYS, _crash); | ||
295 | signal(SIGINT, _crash); | ||
296 | signal(SIGTERM, _crash); | ||
297 | signal(SIGQUIT, _crash); | ||
298 | #endif | ||
299 | timeout_func_set(tmp_cleanup); | ||
250 | if (eina_file_mkdtemp("evas_generic_pdf_loaderXXXXXX", &tmpdir)) | 300 | if (eina_file_mkdtemp("evas_generic_pdf_loaderXXXXXX", &tmpdir)) |
251 | { | 301 | { |
252 | Eina_Strbuf *tmp; | 302 | Eina_Strbuf *tmp; |
@@ -270,6 +320,7 @@ main(int argc, char **argv) | |||
270 | pclose(cmd); | 320 | pclose(cmd); |
271 | 321 | ||
272 | filename = basename(file); | 322 | filename = basename(file); |
323 | |||
273 | generated = eina_tmpstr_add_length(filename, strlen(filename) - strlen(extension)); | 324 | generated = eina_tmpstr_add_length(filename, strlen(filename) - strlen(extension)); |
274 | 325 | ||
275 | eina_strbuf_append_printf(tmp, "%s/%s.pdf", tmpdir, generated); | 326 | eina_strbuf_append_printf(tmp, "%s/%s.pdf", tmpdir, generated); |
@@ -291,12 +342,15 @@ main(int argc, char **argv) | |||
291 | } | 342 | } |
292 | 343 | ||
293 | // Let's force a timeout if things go wrong | 344 | // Let's force a timeout if things go wrong |
294 | timeout_init(10); | 345 | timeout_init(30); |
295 | 346 | ||
296 | // Now process the pdf (or the generated pdf) | 347 | // Now process the pdf (or the generated pdf) |
297 | D("poppler_file_init\n"); | 348 | D("poppler_file_init\n"); |
298 | if (!poppler_init(file, page_num, size_w, size_h)) | 349 | if (!poppler_init(file, page_num, size_w, size_h)) |
299 | return -1; | 350 | { |
351 | goto cleanup; | ||
352 | ret = 1; | ||
353 | } | ||
300 | D("poppler_file_init done\n"); | 354 | D("poppler_file_init done\n"); |
301 | 355 | ||
302 | D("dpi2...: %f\n", dpi); | 356 | D("dpi2...: %f\n", dpi); |
@@ -338,18 +392,9 @@ main(int argc, char **argv) | |||
338 | printf("done\n"); | 392 | printf("done\n"); |
339 | 393 | ||
340 | poppler_shutdown(); | 394 | poppler_shutdown(); |
341 | 395 | cleanup: | |
342 | if (tmpdir) | 396 | timeout_func_set(NULL); |
343 | { | 397 | tmp_cleanup(); |
344 | if (generated) unlink(generated); | ||
345 | if (rmdir(tmpdir) < 0) | ||
346 | { | ||
347 | D("Failed to delete tmpdir %s\n", tmpdir); | ||
348 | } | ||
349 | |||
350 | eina_tmpstr_del(tmpdir); | ||
351 | eina_tmpstr_del(generated); | ||
352 | } | ||
353 | fflush(stdout); | 398 | fflush(stdout); |
354 | return 0; | 399 | return ret; |
355 | } | 400 | } |