summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jpeg@videolan.org>2013-11-08 16:56:28 +0900
committerCedric Bail <cedric.bail@samsung.com>2013-11-08 16:58:28 +0900
commit9637b07ec761f02a734d48c832a25db4d35649f4 (patch)
treeaa976ba22c9f82e101c746ce5cf7bf0ea5fcc3c2
parentd208517a079b157d00c8e2315015a8a6e29f4f56 (diff)
e/cserve2: add restart code for cserve2
Summary: If cserve2 crashes, enlightenment_start will respawn it again. Test Plan: Start E18 (in Xephyr maybe) with E_CSERVE set. Randomly kill evas_cserve2 and enlightenment, and log out from E. I need review for this patch as I'm not sure about all the ptrace stuff lying around. Reviewers: cedric CC: raster, zmike Differential Revision: https://phab.enlightenment.org/D287 Signed-off-by: Cedric Bail <cedric.bail@samsung.com>
-rw-r--r--src/bin/e_start_main.c104
1 files changed, 81 insertions, 23 deletions
diff --git a/src/bin/e_start_main.c b/src/bin/e_start_main.c
index 3cd7122f4..26291556a 100644
--- a/src/bin/e_start_main.c
+++ b/src/bin/e_start_main.c
@@ -22,6 +22,10 @@
22#include <Eina.h> 22#include <Eina.h>
23#include <Evas.h> 23#include <Evas.h>
24 24
25#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
26# define E_CSERVE
27#endif
28
25static Eina_Bool stop_ptrace = EINA_FALSE; 29static Eina_Bool stop_ptrace = EINA_FALSE;
26 30
27static void env_set(const char *var, const char *val); 31static void env_set(const char *var, const char *val);
@@ -235,6 +239,32 @@ _sigusr1(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
235 sigaction(SIGUSR1, &action, NULL); 239 sigaction(SIGUSR1, &action, NULL);
236} 240}
237 241
242#ifdef E_CSERVE
243static pid_t
244_cserve2_start()
245{
246 pid_t cs_child;
247 cs_child = fork();
248 if (cs_child == 0)
249 {
250 char *cs_args[2] = { NULL, NULL };
251
252 cs_args[0] = (char *)evas_cserve_path_get();
253 execv(cs_args[0], cs_args);
254 exit(-1);
255 }
256 else if (cs_child > 0)
257 {
258 putenv("EVAS_CSERVE2=1");
259 }
260 else
261 {
262 unsetenv("EVAS_CSERVE2");
263 }
264 return cs_child;
265}
266#endif
267
238int 268int
239main(int argc, char **argv) 269main(int argc, char **argv)
240{ 270{
@@ -247,8 +277,9 @@ main(int argc, char **argv)
247 Eina_Bool really_know = EINA_FALSE; 277 Eina_Bool really_know = EINA_FALSE;
248 struct sigaction action; 278 struct sigaction action;
249 pid_t child = -1; 279 pid_t child = -1;
250#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8) 280#ifdef E_CSERVE
251 pid_t cs_child = -1; 281 pid_t cs_child = -1;
282 Eina_Bool cs_use = EINA_FALSE;
252#endif 283#endif
253#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \ 284#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
254 !defined(__FreeBSD_kernel__) && !(defined (__MACH__) && defined (__APPLE__)) 285 !defined(__FreeBSD_kernel__) && !(defined (__MACH__) && defined (__APPLE__))
@@ -424,31 +455,19 @@ main(int argc, char **argv)
424 455
425#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \ 456#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
426 !defined(__FreeBSD_kernel__) && !(defined (__MACH__) && defined (__APPLE__)) 457 !defined(__FreeBSD_kernel__) && !(defined (__MACH__) && defined (__APPLE__))
458
459#ifdef E_CSERVE
460 if (getenv("E_CSERVE"))
461 {
462 cs_use = EINA_TRUE;
463 cs_child = _cserve2_start();
464 }
465#endif
466
427 /* Now looping until */ 467 /* Now looping until */
428 while (restart) 468 while (restart)
429 { 469 {
430 stop_ptrace = EINA_FALSE; 470 stop_ptrace = EINA_FALSE;
431#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
432 if (getenv("E_CSERVE"))
433 {
434 if (cs_child < 0)
435 {
436 cs_child = fork();
437 if (cs_child == 0)
438 {
439 char *cs_args[2] = { NULL, NULL };
440
441 cs_args[0] = (char *)evas_cserve_path_get();
442 execv(cs_args[0], cs_args);
443 exit(-1);
444 }
445 else if (cs_child > 0)
446 {
447 putenv("EVAS_CSERVE2=1");
448 }
449 }
450 }
451#endif
452 471
453 child = fork(); 472 child = fork();
454 473
@@ -487,7 +506,12 @@ main(int argc, char **argv)
487 Eina_Bool remember_sigill = EINA_FALSE; 506 Eina_Bool remember_sigill = EINA_FALSE;
488 Eina_Bool remember_sigusr1 = EINA_FALSE; 507 Eina_Bool remember_sigusr1 = EINA_FALSE;
489 508
490 result = waitpid(child, &status, 0); 509 result = waitpid(child, &status, WNOHANG);
510 if (!result)
511 {
512 /* Wait for evas_cserve2 and E */
513 result = waitpid(-1, &status, 0);
514 }
491 515
492 if (result == child) 516 if (result == child)
493 { 517 {
@@ -609,11 +633,45 @@ main(int argc, char **argv)
609 } 633 }
610 } 634 }
611 } 635 }
636#ifdef E_CSERVE
637 else if (cs_use && (result == cs_child))
638 {
639 if (WIFSIGNALED(status))
640 {
641 printf("E - cserve2 terminated with signal %d\n",
642 WTERMSIG(status));
643 cs_child = _cserve2_start();
644 }
645 else if (WIFEXITED(status))
646 {
647 printf("E - cserve2 exited with code %d\n",
648 WEXITSTATUS(status));
649 cs_child = -1;
650 }
651 }
652#endif
612 } 653 }
613 } 654 }
614 } 655 }
615#endif 656#endif
616 657
658#ifdef E_CSERVE
659 if (cs_child > 0)
660 {
661 pid_t result;
662 int status;
663
664 alarm(2);
665 kill(cs_child, SIGINT);
666 result = waitpid(cs_child, &status, 0);
667 if (result != cs_child)
668 {
669 printf("E - cserve2 did not shutdown in 2 seconds, killing!\n");
670 kill(cs_child, SIGKILL);
671 }
672 }
673#endif
674
617 return -1; 675 return -1;
618} 676}
619 677