summaryrefslogtreecommitdiffstats
path: root/usbmuxd
diff options
context:
space:
mode:
Diffstat (limited to 'usbmuxd')
-rw-r--r--usbmuxd/main.c77
1 files changed, 64 insertions, 13 deletions
diff --git a/usbmuxd/main.c b/usbmuxd/main.c
index 88c31da..579a21f 100644
--- a/usbmuxd/main.c
+++ b/usbmuxd/main.c
@@ -47,11 +47,12 @@ static const char *lockfile = "/var/run/usbmuxd.lock";
47 47
48int should_exit; 48int should_exit;
49 49
50struct sigaction sa_old;
51
52static int verbose = 0; 50static int verbose = 0;
53static int foreground = 0; 51static int foreground = 0;
54static int drop_privileges = 0; 52static int drop_privileges = 0;
53static int opt_udev = 0;
54static int opt_exit = 0;
55static int exit_signal = 0;
55 56
56int create_socket(void) { 57int create_socket(void) {
57 struct sockaddr_un bind_addr; 58 struct sockaddr_un bind_addr;
@@ -89,13 +90,19 @@ int create_socket(void) {
89 90
90void handle_signal(int sig) 91void handle_signal(int sig)
91{ 92{
92 if(sig == SIGINT) { 93 if (sig == SIGTERM) {
93 usbmuxd_log(LL_NOTICE,"Caught SIGINT"); 94 should_exit = 1;
94 } else { 95 } else {
95 usbmuxd_log(LL_NOTICE,"Caught unknown signal %d", sig); 96 usbmuxd_log(LL_NOTICE,"Caught signal %d", sig);
97 usbmuxd_log(LL_INFO, "Checking if we can terminate (no more devices attached)...");
98 if (device_get_count() > 0) {
99 // we can't quit, there are still devices attached.
100 usbmuxd_log(LL_NOTICE, "Refusing to terminate, there are still devices attached. Kill me with signal 15 (TERM) to force quit.");
101 } else {
102 // it's safe to quit
103 should_exit = 1;
104 }
96 } 105 }
97 should_exit = 1;
98 sigaction(SIGINT, &sa_old, NULL);
99} 106}
100 107
101void set_signal_handlers(void) 108void set_signal_handlers(void)
@@ -103,7 +110,9 @@ void set_signal_handlers(void)
103 struct sigaction sa; 110 struct sigaction sa;
104 memset(&sa, 0, sizeof(struct sigaction)); 111 memset(&sa, 0, sizeof(struct sigaction));
105 sa.sa_handler = handle_signal; 112 sa.sa_handler = handle_signal;
106 sigaction(SIGINT, &sa, &sa_old); 113 sigaction(SIGINT, &sa, NULL);
114 sigaction(SIGQUIT, &sa, NULL);
115 sigaction(SIGTERM, &sa, NULL);
107} 116}
108 117
109int main_loop(int listenfd) 118int main_loop(int listenfd)
@@ -228,6 +237,10 @@ static void usage()
228 printf("\t-v|--verbose Be verbose (use twice or more to increase).\n"); 237 printf("\t-v|--verbose Be verbose (use twice or more to increase).\n");
229 printf("\t-f|--foreground Do not daemonize (implies a verbosity of 4).\n"); 238 printf("\t-f|--foreground Do not daemonize (implies a verbosity of 4).\n");
230 printf("\t-d|--drop-privileges Drop privileges after startup.\n"); 239 printf("\t-d|--drop-privileges Drop privileges after startup.\n");
240 printf("\t-u|--udev Run in udev operation mode.\n");
241 printf("\t-x|--exit Tell a running instance to exit.\n");
242 printf("\t-X|--force-exit Tell a running instance to exit, even if\n");
243 printf("\t there are still devices connected.\n");
231 printf("\n"); 244 printf("\n");
232} 245}
233 246
@@ -238,12 +251,15 @@ static void parse_opts(int argc, char **argv)
238 {"foreground", 0, NULL, 'f'}, 251 {"foreground", 0, NULL, 'f'},
239 {"verbose", 0, NULL, 'v'}, 252 {"verbose", 0, NULL, 'v'},
240 {"drop-privileges", 0, NULL, 'd'}, 253 {"drop-privileges", 0, NULL, 'd'},
254 {"udev", 0, NULL, 'u'},
255 {"exit", 0, NULL, 'x'},
256 {"force-exit", 0, NULL, 'X'},
241 {NULL, 0, NULL, 0} 257 {NULL, 0, NULL, 0}
242 }; 258 };
243 int c; 259 int c;
244 260
245 while (1) { 261 while (1) {
246 c = getopt_long(argc, argv, "hfvd", longopts, (int *) 0); 262 c = getopt_long(argc, argv, "hfvduxX", longopts, (int *) 0);
247 if (c == -1) { 263 if (c == -1) {
248 break; 264 break;
249 } 265 }
@@ -261,11 +277,24 @@ static void parse_opts(int argc, char **argv)
261 case 'd': 277 case 'd':
262 drop_privileges = 1; 278 drop_privileges = 1;
263 break; 279 break;
280 case 'u':
281 opt_udev = 1;
282 break;
283 case 'x':
284 opt_exit = 1;
285 exit_signal = SIGQUIT;
286 break;
287 case 'X':
288 opt_exit = 1;
289 exit_signal = SIGTERM;
290 break;
264 default: 291 default:
265 usage(); 292 usage();
266 exit(2); 293 exit(2);
267 } 294 }
268 } 295 }
296 if (opt_udev)
297 foreground = 0;
269} 298}
270 299
271int main(int argc, char *argv[]) 300int main(int argc, char *argv[])
@@ -303,13 +332,35 @@ int main(int argc, char *argv[])
303 fcntl(fileno(lfd), F_GETLK, &lock); 332 fcntl(fileno(lfd), F_GETLK, &lock);
304 fclose(lfd); 333 fclose(lfd);
305 if (lock.l_type != F_UNLCK) { 334 if (lock.l_type != F_UNLCK) {
306 usbmuxd_log(LL_NOTICE, 335 if (opt_exit) {
307 "another instance is already running (pid %d). exiting.", lock.l_pid); 336 if (lock.l_pid && !kill(lock.l_pid, 0)) {
308 res = -1; 337 usbmuxd_log(LL_NOTICE, "sending signal %d to instance with pid %d", exit_signal, lock.l_pid);
309 goto terminate; 338 if (kill(lock.l_pid, exit_signal) < 0) {
339 usbmuxd_log(LL_ERROR, "Error: could not deliver signal %d to pid %d", exit_signal, lock.l_pid);
340 }
341 res = 0;
342 goto terminate;
343 } else {
344 usbmuxd_log(LL_ERROR, "Error: could not determine pid of the other running instance!");
345 res = -1;
346 goto terminate;
347 }
348 } else {
349 usbmuxd_log(LL_NOTICE,
350 "another instance is already running (pid %d). exiting.", lock.l_pid);
351 if (!opt_udev) {
352 res = -1;
353 }
354 goto terminate;
355 }
310 } 356 }
311 } 357 }
312 358
359 if (opt_exit) {
360 usbmuxd_log(LL_NOTICE, "no running instance found, none killed. exiting.");
361 goto terminate;
362 }
363
313 usbmuxd_log(LL_INFO, "Creating socket"); 364 usbmuxd_log(LL_INFO, "Creating socket");
314 listenfd = create_socket(); 365 listenfd = create_socket();
315 if(listenfd < 0) 366 if(listenfd < 0)