change argv[0] to match quicklanch process name. much better for debugging!
authorCarsten Haitzler <raster@rasterman.com>
Thu, 26 Feb 2009 06:20:41 +0000 (06:20 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Thu, 26 Feb 2009 06:20:41 +0000 (06:20 +0000)
SVN revision: 39235

src/bin/quicklaunch.c
src/lib/Elementary.h.in
src/lib/elm_main.c

index c828434..7ef131c 100644 (file)
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <signal.h>
+#include <sys/wait.h>
 
 static double restart_time = 0.0;
 
 #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
 
+static struct sigaction old_sigint;
+static struct sigaction old_sigterm;
+static struct sigaction old_sigquit;
+static struct sigaction old_sigalrm;
+static struct sigaction old_sigusr1;
+static struct sigaction old_sigusr2;
+static struct sigaction old_sighup;
+static struct sigaction old_sigchld;
+static struct sigaction old_sigsegv;
+static struct sigaction old_sigill;
+static struct sigaction old_sigfpe;
+static struct sigaction old_sigbus;
+static struct sigaction old_sigabrt;
+
+static void
+post_fork(void *data)
+{
+   sigaction(SIGINT, &old_sigint, NULL);
+   sigaction(SIGTERM, &old_sigterm, NULL);
+   sigaction(SIGQUIT, &old_sigquit, NULL);
+   sigaction(SIGALRM, &old_sigalrm, NULL);
+   sigaction(SIGUSR1, &old_sigusr1, NULL);
+   sigaction(SIGUSR2, &old_sigusr2, NULL);
+   sigaction(SIGHUP, &old_sighup, NULL);
+   sigaction(SIGCHLD, &old_sigchld, NULL);
+   sigaction(SIGSEGV, &old_sigsegv, NULL);
+   sigaction(SIGILL, &old_sigill, NULL);
+   sigaction(SIGFPE, &old_sigfpe, NULL);
+   sigaction(SIGBUS, &old_sigbus, NULL);
+   sigaction(SIGABRT, &old_sigabrt, NULL);
+}
+
+static void
+child_handler(int x, siginfo_t *info, void *data)
+{
+   int status;
+   pid_t pid;
+   
+   while ((pid = waitpid(-1, &status, WNOHANG)) > 0);
+}
+
+static void
+crash_handler(int x, siginfo_t *info, void *data)
+{
+   double t;
+   
+   EINA_ERROR_PERR("elementary_quicklaunch: crash detected. restarting.\n");
+   t = ecore_time_get();
+   if ((t - restart_time) <= 2.0)
+     {
+        EINA_ERROR_PERR("elementary_quicklaunch: crash too fast - less than 2 seconds. abort restart\n");
+        exit(-1);
+     }
+   ecore_app_restart();
+}
+
 static void
 handle_run(int fd, unsigned long bytes)
 {
@@ -36,32 +93,10 @@ handle_run(int fd, unsigned long bytes)
    for (i = 0; i < argc; i++) argv[i] = buf + (unsigned long)argv[i];
    cwd = argv[argc - 1] + strlen(argv[argc - 1]) + 1;
    elm_quicklaunch_prepare(argc, argv);
-   elm_quicklaunch_fork(argc, argv, cwd);
+   elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL);
    elm_quicklaunch_cleanup();
 }
 
-static void
-child_handler(int n)
-{
-   int status;
-   wait(&status);
-}
-
-EAPI void
-crash_handler(int x, siginfo_t *info, void *data)
-{
-   double t;
-   
-   EINA_ERROR_PERR("elementary_quicklaunch: crash detected. restarting.\n");
-   t = ecore_time_get();
-   if ((t - restart_time) <= 2.0)
-     {
-        EINA_ERROR_PERR("elementary_quicklaunch: crash too fast - less than 2 seconds. abort restart\n");
-        exit(-1);
-     }
-   ecore_app_restart();
-}
-
 int
 main(int argc, char **argv)
 {
@@ -117,41 +152,98 @@ main(int argc, char **argv)
         exit(-1);
      }
    elm_quicklaunch_init(argc, argv);
-   signal(SIGINT, SIG_DFL);
-   signal(SIGTERM, SIG_DFL);
-   signal(SIGQUIT, SIG_DFL);
-   signal(SIGALRM, SIG_DFL);
-   signal(SIGUSR1, SIG_DFL);
-   signal(SIGUSR2, SIG_DFL);
-   signal(SIGHUP, SIG_DFL);
-   signal(SIGCHLD, child_handler);
-
    restart_time = ecore_time_get();
+
+   action.sa_handler = SIG_DFL;
+   action.sa_restorer = NULL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGINT, &action, &old_sigint);
+   
+   action.sa_handler = SIG_DFL;
+   action.sa_restorer = NULL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGTERM, &action, &old_sigterm);
+   
+   action.sa_handler = SIG_DFL;
+   action.sa_restorer = NULL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGQUIT, &action, &old_sigquit);
+   
+   action.sa_handler = SIG_DFL;
+   action.sa_restorer = NULL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGALRM, &action, &old_sigalrm);
    
+   action.sa_handler = SIG_DFL;
+   action.sa_restorer = NULL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGUSR1, &action, &old_sigusr1);
+   
+   action.sa_handler = SIG_DFL;
+   action.sa_restorer = NULL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGUSR2, &action, &old_sigusr2);
+   
+   action.sa_handler = SIG_DFL;
+   action.sa_restorer = NULL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGHUP, &action, &old_sighup);
+   
+   action.sa_handler = NULL;
+   action.sa_restorer = NULL;
+   action.sa_sigaction = child_handler;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGCHLD, &action, &old_sigchld);
+
+   action.sa_handler = NULL;
+   action.sa_restorer = NULL;
    action.sa_sigaction = crash_handler;
    action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
    sigemptyset(&action.sa_mask);
-   sigaction(SIGSEGV, &action, NULL);
+   sigaction(SIGSEGV, &action, &old_sigsegv);
    
+   action.sa_handler = NULL;
+   action.sa_restorer = NULL;
    action.sa_sigaction = crash_handler;
    action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
    sigemptyset(&action.sa_mask);
-   sigaction(SIGILL, &action, NULL);
+   sigaction(SIGILL, &action, &old_sigill);
    
+   action.sa_handler = NULL;
+   action.sa_restorer = NULL;
    action.sa_sigaction = crash_handler;
    action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
    sigemptyset(&action.sa_mask);
-   sigaction(SIGFPE, &action, NULL);
+   sigaction(SIGFPE, &action, &old_sigfpe);
    
+   action.sa_handler = NULL;
+   action.sa_restorer = NULL;
    action.sa_sigaction = crash_handler;
    action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
    sigemptyset(&action.sa_mask);
-   sigaction(SIGBUS, &action, NULL);
+   sigaction(SIGBUS, &action, &old_sigbus);
    
+   action.sa_handler = NULL;
+   action.sa_restorer = NULL;
    action.sa_sigaction = crash_handler;
    action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
    sigemptyset(&action.sa_mask);
-   sigaction(SIGABRT, &action, NULL);
+   sigaction(SIGABRT, &action, &old_sigabrt);
    
    for (;;)
      {
@@ -169,6 +261,7 @@ main(int argc, char **argv)
              char line[4096];
 
              read(fd, &bytes, sizeof(unsigned long));
+             ecore_app_args_set(argc, (const char **)argv);
              handle_run(fd, bytes);
           }
         elm_quicklaunch_sub_shutdown();
index 03e19db..a8809d9 100644 (file)
@@ -155,7 +155,7 @@ extern "C" {
    EAPI void         elm_quicklaunch_shutdown(void);
    EAPI void         elm_quicklaunch_seed(void);
    EAPI Evas_Bool    elm_quicklaunch_prepare(int argc, char **argv);
-   EAPI Evas_Bool    elm_quicklaunch_fork(int argc, char **argv, char *cwd);
+   EAPI Evas_Bool    elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (void *data), void *postfork_data);
    EAPI void         elm_quicklaunch_cleanup(void);
    EAPI int          elm_quicklaunch_fallback(int argc, char **argv);
    EAPI char        *elm_quicklaunch_exe_path_get(const char *exe);
index 6ada9b7..67b6cf3 100644 (file)
@@ -278,28 +278,6 @@ elm_quicklaunch_init(int argc, char **argv)
      (double)_elm_config->finger_size * _elm_config->scale;
    if (elm_finger_size)
      _elm_config->finger_size = atoi(elm_finger_size);
-   
-   /* FIXME: implement quickstart below */
-   /* if !quickstart return
-    * else
-    *  set up fast-start-fifo (in $ELM_FAST_START_FIFO)
-    *  sit on blocking read
-    *  read 2 bytes == length of data in bytes including nulls
-    *  read N bytes (must be < (page_size - 2))
-    *  format: exename\0exepath\0[arg1\0][arg2\0][...]
-    *  dlopen exepath
-    *  dlsym elm_main in exe
-    *  if (elm_main ! exists)
-    *   ecore_exe exename
-    *  else
-    *   fork()
-    *   [child]
-    *    call exit(elm_main());
-    *   [parent]
-    *    close x fd the nasty way (with close())
-    *    ecore_x_shutdown()
-    *    ecore_x_init() etc. etc. loop back to blocking on fifo read
-    */
 }
 
 EAPI void
@@ -326,7 +304,6 @@ elm_quicklaunch_sub_init(int argc, char **argv)
                                ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
         _elm_event_property_change = ecore_event_handler_add
           (ECORE_X_EVENT_WINDOW_PROPERTY, _elm_window_property_change, NULL);
-        /* FIXME if quickstart this happens in child */
        if (ecore_x_window_prop_card32_get(ecore_x_window_root_first_get(),
                                           _elm_atom_enlightenment_scale,
                                           &val, 1) > 0)
@@ -465,8 +442,30 @@ elm_quicklaunch_prepare(int argc, char **argv)
    return 1;
 }
 
+static void
+save_env(void)
+{
+   int i, size;
+   extern char **environ;
+   char **oldenv, **p;
+   
+   oldenv = environ;
+   
+   for (i = 0, size = 0; environ[i] != NULL; i++)
+     size += strlen(environ[i]) + 1;
+   
+   p = malloc((i + 1) * sizeof(char *));
+   if (!p) return;
+   
+   environ = p;
+      
+   for (i = 0; oldenv[i] != NULL; i++)
+     environ[i] = strdup(oldenv[i]);
+   environ[i] = NULL;
+}
+
 EAPI Evas_Bool
-elm_quicklaunch_fork(int argc, char **argv, char *cwd)
+elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (void *data), void *postfork_data)
 {
    pid_t child;
    int ret;
@@ -503,9 +502,25 @@ elm_quicklaunch_fork(int argc, char **argv, char *cwd)
        perror("could not fork");
        return 0;
      }
+   if (postfork_func) postfork_func(postfork_data);
+
    setsid();
    if (chdir(cwd) != 0)
      perror("could not chdir");
+   // FIXME: this is very linux specific. it changes argv[0] of the process
+   // so ps etc. report what you'd expect. for other unixes and os's this
+   // may just not work
+   save_env();
+   if (real_argv)
+     {
+        char *lastarg, *p;
+
+        ecore_app_args_get(&real_argc, &real_argv);
+        lastarg = real_argv[real_argc - 1] + strlen(real_argv[real_argc - 1]);
+        for (p = real_argv[0]; p < lastarg; p++) *p = 0;
+        strcpy(real_argv[0], argv[0]);
+     }
+   ecore_app_args_set(argc, (const char **)argv);
    ret = qr_main(argc, argv);
    exit(ret);
 }