1 #include <Elementary.h>
3 # include "elementary_config.h"
10 #include <sys/socket.h>
18 static double restart_time = 0.0;
20 #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
22 static struct sigaction old_sigint;
23 static struct sigaction old_sigterm;
24 static struct sigaction old_sigquit;
25 static struct sigaction old_sigalrm;
26 static struct sigaction old_sigusr1;
27 static struct sigaction old_sigusr2;
28 static struct sigaction old_sighup;
29 static struct sigaction old_sigchld;
30 static struct sigaction old_sigsegv;
31 static struct sigaction old_sigill;
32 static struct sigaction old_sigfpe;
33 static struct sigaction old_sigbus;
34 static struct sigaction old_sigabrt;
35 static int _log_dom = -1;
37 #define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
38 #define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
39 #define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
40 #define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
41 #define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
44 post_fork(void *data __UNUSED__)
46 sigaction(SIGINT, &old_sigint, NULL);
47 sigaction(SIGTERM, &old_sigterm, NULL);
48 sigaction(SIGQUIT, &old_sigquit, NULL);
49 sigaction(SIGALRM, &old_sigalrm, NULL);
50 sigaction(SIGUSR1, &old_sigusr1, NULL);
51 sigaction(SIGUSR2, &old_sigusr2, NULL);
52 sigaction(SIGHUP, &old_sighup, NULL);
53 sigaction(SIGCHLD, &old_sigchld, NULL);
54 sigaction(SIGSEGV, &old_sigsegv, NULL);
55 sigaction(SIGILL, &old_sigill, NULL);
56 sigaction(SIGFPE, &old_sigfpe, NULL);
57 sigaction(SIGBUS, &old_sigbus, NULL);
58 sigaction(SIGABRT, &old_sigabrt, NULL);
59 if ((_log_dom > -1) && (_log_dom != EINA_LOG_DOMAIN_GLOBAL))
61 eina_log_domain_unregister(_log_dom);
67 child_handler(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
70 while (waitpid(-1, &status, WNOHANG) > 0);
74 crash_handler(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
78 ERR("crash detected. restarting.");
80 if ((t - restart_time) <= 2.0)
82 CRITICAL("crash too fast - less than 2 seconds. abort restart");
89 handle_run(int fd, unsigned long bytes)
91 unsigned char *buf = NULL;
98 if (read(fd, buf, bytes) <= 0)
104 argc = ((unsigned long *)(buf))[0];
105 argv = (char **)(&(((unsigned long *)(buf))[1]));
106 for (i = 0; i < argc; i++) argv[i] = (char *)(buf + (unsigned long)argv[i]);
107 cwd = argv[argc - 1] + strlen(argv[argc - 1]) + 1;
108 elm_quicklaunch_prepare(argc, argv);
109 elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL);
110 elm_quicklaunch_cleanup();
114 main(int argc, char **argv)
116 int sock, socket_unix_len;
118 struct sockaddr_un socket_unix;
121 struct sigaction action;
125 fprintf(stderr, "ERROR: failed to init eina.");
128 _log_dom = eina_log_domain_register
129 ("elementary_quicklaunch", EINA_COLOR_CYAN);
132 EINA_LOG_ERR("could not register elementary_quicklaunch log domain.");
133 _log_dom = EINA_LOG_DOMAIN_GLOBAL;
136 if (!getenv("DISPLAY"))
138 CRITICAL("DISPLAY env var not set");
141 snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i", getuid());
142 if (stat(buf, &st) < 0) mkdir(buf, S_IRUSR | S_IWUSR | S_IXUSR);
143 snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), getenv("DISPLAY"));
145 sock = socket(AF_UNIX, SOCK_STREAM, 0);
148 CRITICAL("cannot create socket for socket for '%s': %s",
149 buf, strerror(errno));
152 if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0)
154 CRITICAL("cannot set close on exec socket for '%s' (fd=%d): %s",
155 buf, sock, strerror(errno));
160 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0)
162 CRITICAL("cannot set linger for socket for '%s' (fd=%d): %s",
163 buf, sock, strerror(errno));
166 socket_unix.sun_family = AF_UNIX;
167 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
168 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
169 if (bind(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
171 CRITICAL("cannot bind socket for '%s' (fd=%d): %s",
172 buf, sock, strerror(errno));
175 if (listen(sock, 4096) < 0)
177 CRITICAL("listen(sock=%d, 4096): %s", sock, strerror(errno));
180 elm_quicklaunch_mode_set(EINA_TRUE);
181 elm_quicklaunch_init(argc, argv);
182 restart_time = ecore_time_get();
184 memset(&action, 0, sizeof(struct sigaction));
185 action.sa_handler = SIG_DFL;
186 action.sa_sigaction = NULL;
187 action.sa_flags = SA_RESTART | SA_SIGINFO;
188 sigemptyset(&action.sa_mask);
189 sigaction(SIGINT, &action, &old_sigint);
191 action.sa_handler = SIG_DFL;
192 action.sa_sigaction = NULL;
193 action.sa_flags = SA_RESTART | SA_SIGINFO;
194 sigemptyset(&action.sa_mask);
195 sigaction(SIGTERM, &action, &old_sigterm);
197 action.sa_handler = SIG_DFL;
198 action.sa_sigaction = NULL;
199 action.sa_flags = SA_RESTART | SA_SIGINFO;
200 sigemptyset(&action.sa_mask);
201 sigaction(SIGQUIT, &action, &old_sigquit);
203 action.sa_handler = SIG_DFL;
204 action.sa_sigaction = NULL;
205 action.sa_flags = SA_RESTART | SA_SIGINFO;
206 sigemptyset(&action.sa_mask);
207 sigaction(SIGALRM, &action, &old_sigalrm);
209 action.sa_handler = SIG_DFL;
210 action.sa_sigaction = NULL;
211 action.sa_flags = SA_RESTART | SA_SIGINFO;
212 sigemptyset(&action.sa_mask);
213 sigaction(SIGUSR1, &action, &old_sigusr1);
215 action.sa_handler = SIG_DFL;
216 action.sa_sigaction = NULL;
217 action.sa_flags = SA_RESTART | SA_SIGINFO;
218 sigemptyset(&action.sa_mask);
219 sigaction(SIGUSR2, &action, &old_sigusr2);
221 action.sa_handler = SIG_DFL;
222 action.sa_sigaction = NULL;
223 action.sa_flags = SA_RESTART | SA_SIGINFO;
224 sigemptyset(&action.sa_mask);
225 sigaction(SIGHUP, &action, &old_sighup);
227 action.sa_handler = NULL;
228 action.sa_sigaction = child_handler;
229 action.sa_flags = SA_RESTART | SA_SIGINFO;
230 sigemptyset(&action.sa_mask);
231 sigaction(SIGCHLD, &action, &old_sigchld);
233 action.sa_handler = NULL;
234 action.sa_sigaction = crash_handler;
235 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
236 sigemptyset(&action.sa_mask);
237 sigaction(SIGSEGV, &action, &old_sigsegv);
239 action.sa_handler = NULL;
240 action.sa_sigaction = crash_handler;
241 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
242 sigemptyset(&action.sa_mask);
243 sigaction(SIGILL, &action, &old_sigill);
245 action.sa_handler = NULL;
246 action.sa_sigaction = crash_handler;
247 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
248 sigemptyset(&action.sa_mask);
249 sigaction(SIGFPE, &action, &old_sigfpe);
251 action.sa_handler = NULL;
252 action.sa_sigaction = crash_handler;
253 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
254 sigemptyset(&action.sa_mask);
255 sigaction(SIGBUS, &action, &old_sigbus);
257 action.sa_handler = NULL;
258 action.sa_sigaction = crash_handler;
259 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
260 sigemptyset(&action.sa_mask);
261 sigaction(SIGABRT, &action, &old_sigabrt);
266 struct sockaddr_un client;
269 len = sizeof(struct sockaddr_un);
270 fd = accept(sock, (struct sockaddr *)&client, &len);
271 elm_quicklaunch_sub_init(argc, argv);
272 // don't seed since we are doing this AFTER launch request
273 // elm_quicklaunch_seed();
279 num = read(fd, &bytes, sizeof(unsigned long));
280 if (num == sizeof(unsigned long))
282 ecore_app_args_set(argc, (const char **)argv);
283 handle_run(fd, bytes);
286 while (elm_quicklaunch_sub_shutdown() > 0);
288 elm_quicklaunch_shutdown();
290 if ((_log_dom > -1) && (_log_dom != EINA_LOG_DOMAIN_GLOBAL))
292 eina_log_domain_unregister(_log_dom);