summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-12-12 02:22:06 +0000
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-12-12 02:22:06 +0000
commita43c2dad505dbce76b955422c41091fc5b0efc2b (patch)
tree4b994abfcf006e685b073e6a44d74af8494b5fd0
parentdc0173fdf6d586f9167643213850c8b08b8ff3fa (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.c11
-rw-r--r--src/generic/evas/common/timeout.h1
-rw-r--r--src/generic/evas/pdf/main.cpp79
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>
2static 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)
26static void 30static 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
46void
47timeout_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
8void timeout_init(int seconds); 8void timeout_init(int seconds);
9void 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
22typedef char RGB24[3]; 27typedef 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
200static Eina_Tmpstr *tmpdir = NULL;
201static Eina_Tmpstr *generated = NULL;
202
203static void
204tmp_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
226static void
227_crash(int val)
228{
229 D("Crash\n");
230 tmp_cleanup();
231 _exit(-1 | val);
232}
233
195int 234int
196main(int argc, char **argv) 235main(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 395cleanup:
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}