]> code.delx.au - pulseaudio/blob - src/daemon/main.c
Merge branch 'master' into dbus-work
[pulseaudio] / src / daemon / main.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <unistd.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <signal.h>
33 #include <stddef.h>
34 #include <ltdl.h>
35 #include <limits.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <locale.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41
42 #include <liboil/liboil.h>
43
44 #ifdef HAVE_SYS_MMAN_H
45 #include <sys/mman.h>
46 #endif
47
48 #ifdef HAVE_SYS_IOCTL_H
49 #include <sys/ioctl.h>
50 #endif
51
52 #ifdef HAVE_PWD_H
53 #include <pwd.h>
54 #endif
55 #ifdef HAVE_GRP_H
56 #include <grp.h>
57 #endif
58
59 #ifdef HAVE_LIBWRAP
60 #include <syslog.h>
61 #include <tcpd.h>
62 #endif
63
64 #ifdef HAVE_DBUS
65 #include <dbus/dbus.h>
66 #endif
67
68 #include <pulse/mainloop.h>
69 #include <pulse/mainloop-signal.h>
70 #include <pulse/timeval.h>
71 #include <pulse/xmalloc.h>
72 #include <pulse/i18n.h>
73
74 #include <pulsecore/lock-autospawn.h>
75 #include <pulsecore/winsock.h>
76 #include <pulsecore/core-error.h>
77 #include <pulsecore/core-rtclock.h>
78 #include <pulsecore/core.h>
79 #include <pulsecore/memblock.h>
80 #include <pulsecore/module.h>
81 #include <pulsecore/cli-command.h>
82 #include <pulsecore/log.h>
83 #include <pulsecore/core-util.h>
84 #include <pulsecore/sioman.h>
85 #include <pulsecore/cli-text.h>
86 #include <pulsecore/pid.h>
87 #include <pulsecore/namereg.h>
88 #include <pulsecore/random.h>
89 #include <pulsecore/macro.h>
90 #include <pulsecore/mutex.h>
91 #include <pulsecore/thread.h>
92 #include <pulsecore/once.h>
93 #include <pulsecore/shm.h>
94 #include <pulsecore/memtrap.h>
95 #ifdef HAVE_DBUS
96 #include <pulsecore/dbus-shared.h>
97 #endif
98
99 #include "cmdline.h"
100 #include "cpulimit.h"
101 #include "daemon-conf.h"
102 #include "dumpmodules.h"
103 #include "caps.h"
104 #include "ltdl-bind-now.h"
105 #include "server-lookup.h"
106
107 #ifdef HAVE_LIBWRAP
108 /* Only one instance of these variables */
109 int allow_severity = LOG_INFO;
110 int deny_severity = LOG_WARNING;
111 #endif
112
113 #ifdef HAVE_OSS
114 /* padsp looks for this symbol in the running process and disables
115 * itself if it finds it and it is set to 7 (which is actually a bit
116 * mask). For details see padsp. */
117 int __padsp_disabled__ = 7;
118 #endif
119
120 #ifdef OS_IS_WIN32
121
122 static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval *tv, void *userdata) {
123 MSG msg;
124 struct timeval tvnext;
125
126 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
127 if (msg.message == WM_QUIT)
128 raise(SIGTERM);
129 else {
130 TranslateMessage(&msg);
131 DispatchMessage(&msg);
132 }
133 }
134
135 pa_timeval_add(pa_gettimeofday(&tvnext), 100000);
136 a->rtclock_time_restart(e, &tvnext);
137 }
138
139 #endif
140
141 static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
142 pa_log_info(_("Got signal %s."), pa_sig2str(sig));
143
144 switch (sig) {
145 #ifdef SIGUSR1
146 case SIGUSR1:
147 pa_module_load(userdata, "module-cli", NULL);
148 break;
149 #endif
150
151 #ifdef SIGUSR2
152 case SIGUSR2:
153 pa_module_load(userdata, "module-cli-protocol-unix", NULL);
154 break;
155 #endif
156
157 #ifdef SIGHUP
158 case SIGHUP: {
159 char *c = pa_full_status_string(userdata);
160 pa_log_notice("%s", c);
161 pa_xfree(c);
162 return;
163 }
164 #endif
165
166 case SIGINT:
167 case SIGTERM:
168 default:
169 pa_log_info(_("Exiting."));
170 m->quit(m, 1);
171 break;
172 }
173 }
174
175 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
176
177 static int change_user(void) {
178 struct passwd *pw;
179 struct group * gr;
180 int r;
181
182 /* This function is called only in system-wide mode. It creates a
183 * runtime dir in /var/run/ with proper UID/GID and drops privs
184 * afterwards. */
185
186 if (!(pw = getpwnam(PA_SYSTEM_USER))) {
187 pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER);
188 return -1;
189 }
190
191 if (!(gr = getgrnam(PA_SYSTEM_GROUP))) {
192 pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP);
193 return -1;
194 }
195
196 pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."),
197 PA_SYSTEM_USER, (unsigned long) pw->pw_uid,
198 PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid);
199
200 if (pw->pw_gid != gr->gr_gid) {
201 pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP);
202 return -1;
203 }
204
205 if (strcmp(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH) != 0)
206 pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
207
208 if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) {
209 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
210 return -1;
211 }
212
213 if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) {
214 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
215 return -1;
216 }
217
218 /* We don't create the config dir here, because we don't need to write to it */
219
220 if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) {
221 pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno));
222 return -1;
223 }
224
225 #if defined(HAVE_SETRESGID)
226 r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid);
227 #elif defined(HAVE_SETEGID)
228 if ((r = setgid(gr->gr_gid)) >= 0)
229 r = setegid(gr->gr_gid);
230 #elif defined(HAVE_SETREGID)
231 r = setregid(gr->gr_gid, gr->gr_gid);
232 #else
233 #error "No API to drop privileges"
234 #endif
235
236 if (r < 0) {
237 pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno));
238 return -1;
239 }
240
241 #if defined(HAVE_SETRESUID)
242 r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
243 #elif defined(HAVE_SETEUID)
244 if ((r = setuid(pw->pw_uid)) >= 0)
245 r = seteuid(pw->pw_uid);
246 #elif defined(HAVE_SETREUID)
247 r = setreuid(pw->pw_uid, pw->pw_uid);
248 #else
249 #error "No API to drop privileges"
250 #endif
251
252 if (r < 0) {
253 pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno));
254 return -1;
255 }
256
257 pa_set_env("USER", PA_SYSTEM_USER);
258 pa_set_env("USERNAME", PA_SYSTEM_USER);
259 pa_set_env("LOGNAME", PA_SYSTEM_USER);
260 pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH);
261
262 /* Relevant for pa_runtime_path() */
263 pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH);
264 pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH);
265 pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
266
267 pa_log_info(_("Successfully dropped root privileges."));
268
269 return 0;
270 }
271
272 #else /* HAVE_PWD_H && HAVE_GRP_H */
273
274 static int change_user(void) {
275 pa_log(_("System wide mode unsupported on this platform."));
276 return -1;
277 }
278
279 #endif /* HAVE_PWD_H && HAVE_GRP_H */
280
281 #ifdef HAVE_SYS_RESOURCE_H
282
283 static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
284 struct rlimit rl;
285 pa_assert(r);
286
287 if (!r->is_set)
288 return 0;
289
290 rl.rlim_cur = rl.rlim_max = r->value;
291
292 if (setrlimit(resource, &rl) < 0) {
293 pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
294 return -1;
295 }
296
297 return 0;
298 }
299
300 static void set_all_rlimits(const pa_daemon_conf *conf) {
301 set_one_rlimit(&conf->rlimit_fsize, RLIMIT_FSIZE, "RLIMIT_FSIZE");
302 set_one_rlimit(&conf->rlimit_data, RLIMIT_DATA, "RLIMIT_DATA");
303 set_one_rlimit(&conf->rlimit_stack, RLIMIT_STACK, "RLIMIT_STACK");
304 set_one_rlimit(&conf->rlimit_core, RLIMIT_CORE, "RLIMIT_CORE");
305 #ifdef RLIMIT_RSS
306 set_one_rlimit(&conf->rlimit_rss, RLIMIT_RSS, "RLIMIT_RSS");
307 #endif
308 #ifdef RLIMIT_NPROC
309 set_one_rlimit(&conf->rlimit_nproc, RLIMIT_NPROC, "RLIMIT_NPROC");
310 #endif
311 #ifdef RLIMIT_NOFILE
312 set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
313 #endif
314 #ifdef RLIMIT_MEMLOCK
315 set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
316 #endif
317 #ifdef RLIMIT_AS
318 set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
319 #endif
320 #ifdef RLIMIT_LOCKS
321 set_one_rlimit(&conf->rlimit_locks, RLIMIT_LOCKS, "RLIMIT_LOCKS");
322 #endif
323 #ifdef RLIMIT_SIGPENDING
324 set_one_rlimit(&conf->rlimit_sigpending, RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING");
325 #endif
326 #ifdef RLIMIT_MSGQUEUE
327 set_one_rlimit(&conf->rlimit_msgqueue, RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE");
328 #endif
329 #ifdef RLIMIT_NICE
330 set_one_rlimit(&conf->rlimit_nice, RLIMIT_NICE, "RLIMIT_NICE");
331 #endif
332 #ifdef RLIMIT_RTPRIO
333 set_one_rlimit(&conf->rlimit_rtprio, RLIMIT_RTPRIO, "RLIMIT_RTPRIO");
334 #endif
335 #ifdef RLIMIT_RTTIME
336 set_one_rlimit(&conf->rlimit_rttime, RLIMIT_RTTIME, "RLIMIT_RTTIME");
337 #endif
338 }
339 #endif
340
341 #ifdef HAVE_DBUS
342 static pa_dbus_connection *register_dbus_name(pa_core *c, DBusBusType bus, const char* name) {
343 DBusError error;
344 pa_dbus_connection *conn;
345
346 dbus_error_init(&error);
347
348 if (!(conn = pa_dbus_bus_get(c, bus, &error)) || dbus_error_is_set(&error)) {
349 pa_log_warn("Unable to contact D-Bus: %s: %s", error.name, error.message);
350 goto fail;
351 }
352
353 if (dbus_bus_request_name(pa_dbus_connection_get(conn), name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
354 pa_log_debug("Got %s!", name);
355 return conn;
356 }
357
358 if (dbus_error_is_set(&error))
359 pa_log_error("Failed to acquire %s: %s: %s", name, error.name, error.message);
360 else
361 pa_log_error("D-Bus name %s already taken. Weird shit!", name);
362
363 /* PA cannot be started twice by the same user and hence we can
364 * ignore mostly the case that a name is already taken. */
365
366 fail:
367 if (conn)
368 pa_dbus_connection_unref(conn);
369
370 dbus_error_free(&error);
371 return NULL;
372 }
373 #endif
374
375 int main(int argc, char *argv[]) {
376 pa_core *c = NULL;
377 pa_strbuf *buf = NULL;
378 pa_daemon_conf *conf = NULL;
379 pa_mainloop *mainloop = NULL;
380 char *s;
381 int r = 0, retval = 1, d = 0;
382 pa_bool_t valid_pid_file = FALSE;
383 pa_bool_t ltdl_init = FALSE;
384 int passed_fd = -1;
385 const char *e;
386 #ifdef HAVE_FORK
387 int daemon_pipe[2] = { -1, -1 };
388 #endif
389 #ifdef OS_IS_WIN32
390 pa_time_event *win32_timer;
391 struct timeval win32_tv;
392 #endif
393 int autospawn_fd = -1;
394 pa_bool_t autospawn_locked = FALSE;
395 #ifdef HAVE_DBUS
396 pa_dbusobj_server_lookup *server_lookup = NULL; /* /org/pulseaudio/server_lookup */
397 pa_dbus_connection *lookup_service_bus = NULL; /* Always the user bus. */
398 pa_dbus_connection *server_bus = NULL; /* The bus where we reserve org.pulseaudio.Server, either the user or the system bus. */
399 pa_bool_t start_server;
400 #endif
401
402 pa_log_set_ident("pulseaudio");
403 pa_log_set_level(PA_LOG_NOTICE);
404 pa_log_set_flags(PA_LOG_COLORS|PA_LOG_PRINT_FILE|PA_LOG_PRINT_LEVEL, PA_LOG_RESET);
405
406 #if defined(__linux__) && defined(__OPTIMIZE__)
407 /*
408 Disable lazy relocations to make usage of external libraries
409 more deterministic for our RT threads. We abuse __OPTIMIZE__ as
410 a check whether we are a debug build or not.
411 */
412
413 if (!getenv("LD_BIND_NOW")) {
414 char *rp;
415
416 /* We have to execute ourselves, because the libc caches the
417 * value of $LD_BIND_NOW on initialization. */
418
419 pa_set_env("LD_BIND_NOW", "1");
420
421 if ((rp = pa_readlink("/proc/self/exe")))
422 pa_assert_se(execv(rp, argv) == 0);
423 else
424 pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
425 }
426 #endif
427
428 if ((e = getenv("PULSE_PASSED_FD"))) {
429 passed_fd = atoi(e);
430
431 if (passed_fd <= 2)
432 passed_fd = -1;
433 }
434
435 /* We might be autospawned, in which case have no idea in which
436 * context we have been started. Let's cleanup our execution
437 * context as good as possible */
438 pa_drop_root();
439 pa_close_all(passed_fd, -1);
440 pa_reset_sigs(-1);
441 pa_unblock_sigs(-1);
442
443 setlocale(LC_ALL, "");
444 pa_init_i18n();
445
446 conf = pa_daemon_conf_new();
447
448 if (pa_daemon_conf_load(conf, NULL) < 0)
449 goto finish;
450
451 if (pa_daemon_conf_env(conf) < 0)
452 goto finish;
453
454 if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
455 pa_log(_("Failed to parse command line."));
456 goto finish;
457 }
458
459 pa_log_set_level(conf->log_level);
460 pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target);
461 if (conf->log_meta)
462 pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
463 if (conf->log_time)
464 pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
465 pa_log_set_show_backtrace(conf->log_backtrace);
466
467 #ifdef HAVE_DBUS
468 /* conf->system_instance and conf->local_server_type control almost the
469 * same thing; make them agree about what is requested. */
470 switch (conf->local_server_type) {
471 case PA_SERVER_TYPE_UNSET:
472 conf->local_server_type = conf->system_instance ? PA_SERVER_TYPE_SYSTEM : PA_SERVER_TYPE_USER;
473 break;
474 case PA_SERVER_TYPE_USER:
475 case PA_SERVER_TYPE_NONE:
476 conf->system_instance = FALSE;
477 break;
478 case PA_SERVER_TYPE_SYSTEM:
479 conf->system_instance = TRUE;
480 break;
481 default:
482 pa_assert_not_reached();
483 }
484
485 start_server = conf->local_server_type == PA_SERVER_TYPE_USER || (getuid() == 0 && conf->local_server_type == PA_SERVER_TYPE_SYSTEM);
486
487 if (!start_server && conf->local_server_type == PA_SERVER_TYPE_SYSTEM) {
488 pa_log_notice(_("System mode refused for non-root user. Only starting the D-Bus server lookup service."));
489 conf->system_instance = FALSE;
490 }
491 #endif
492
493 LTDL_SET_PRELOADED_SYMBOLS();
494 pa_ltdl_init();
495 ltdl_init = TRUE;
496
497 if (conf->dl_search_path)
498 lt_dlsetsearchpath(conf->dl_search_path);
499
500 #ifdef OS_IS_WIN32
501 {
502 WSADATA data;
503 WSAStartup(MAKEWORD(2, 0), &data);
504 }
505 #endif
506
507 pa_random_seed();
508
509 switch (conf->cmd) {
510 case PA_CMD_DUMP_MODULES:
511 pa_dump_modules(conf, argc-d, argv+d);
512 retval = 0;
513 goto finish;
514
515 case PA_CMD_DUMP_CONF: {
516 s = pa_daemon_conf_dump(conf);
517 fputs(s, stdout);
518 pa_xfree(s);
519 retval = 0;
520 goto finish;
521 }
522
523 case PA_CMD_DUMP_RESAMPLE_METHODS: {
524 int i;
525
526 for (i = 0; i < PA_RESAMPLER_MAX; i++)
527 if (pa_resample_method_supported(i))
528 printf("%s\n", pa_resample_method_to_string(i));
529
530 retval = 0;
531 goto finish;
532 }
533
534 case PA_CMD_HELP :
535 pa_cmdline_help(argv[0]);
536 retval = 0;
537 goto finish;
538
539 case PA_CMD_VERSION :
540 printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
541 retval = 0;
542 goto finish;
543
544 case PA_CMD_CHECK: {
545 pid_t pid;
546
547 if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
548 pa_log_info(_("Daemon not running"));
549 else {
550 pa_log_info(_("Daemon running as PID %u"), pid);
551 retval = 0;
552 }
553
554 goto finish;
555
556 }
557 case PA_CMD_KILL:
558
559 if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
560 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
561 else
562 retval = 0;
563
564 goto finish;
565
566 case PA_CMD_CLEANUP_SHM:
567
568 if (pa_shm_cleanup() >= 0)
569 retval = 0;
570
571 goto finish;
572
573 default:
574 pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
575 }
576
577 if (getuid() == 0 && !conf->system_instance)
578 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
579 #ifndef HAVE_DBUS /* A similar, only a notice worthy check was done earlier, if D-Bus is enabled. */
580 else if (getuid() != 0 && conf->system_instance) {
581 pa_log(_("Root privileges required."));
582 goto finish;
583 }
584 #endif
585
586 if (conf->cmd == PA_CMD_START && conf->system_instance) {
587 pa_log(_("--start not supported for system instances."));
588 goto finish;
589 }
590
591 if (conf->system_instance && !conf->disallow_exit)
592 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
593
594 if (conf->system_instance && !conf->disallow_module_loading)
595 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
596
597 if (conf->system_instance && !conf->disable_shm) {
598 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
599 conf->disable_shm = TRUE;
600 }
601
602 if (conf->system_instance && conf->exit_idle_time >= 0) {
603 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
604 conf->exit_idle_time = -1;
605 }
606
607 if (conf->cmd == PA_CMD_START) {
608 /* If we shall start PA only when it is not running yet, we
609 * first take the autospawn lock to make things
610 * synchronous. */
611
612 if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
613 pa_log("Failed to initialize autospawn lock");
614 goto finish;
615 }
616
617 if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
618 pa_log("Failed to acquire autospawn lock");
619 goto finish;
620 }
621
622 autospawn_locked = TRUE;
623 }
624
625 if (conf->daemonize) {
626 pid_t child;
627 int tty_fd;
628
629 if (pa_stdio_acquire() < 0) {
630 pa_log(_("Failed to acquire stdio."));
631 goto finish;
632 }
633
634 #ifdef HAVE_FORK
635 if (pipe(daemon_pipe) < 0) {
636 pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
637 goto finish;
638 }
639
640 if ((child = fork()) < 0) {
641 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
642 goto finish;
643 }
644
645 if (child != 0) {
646 ssize_t n;
647 /* Father */
648
649 pa_assert_se(pa_close(daemon_pipe[1]) == 0);
650 daemon_pipe[1] = -1;
651
652 if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
653
654 if (n < 0)
655 pa_log(_("read() failed: %s"), pa_cstrerror(errno));
656
657 retval = 1;
658 }
659
660 if (retval)
661 pa_log(_("Daemon startup failed."));
662 else
663 pa_log_info(_("Daemon startup successful."));
664
665 goto finish;
666 }
667
668 if (autospawn_fd >= 0) {
669 /* The lock file is unlocked from the parent, so we need
670 * to close it in the child */
671
672 pa_autospawn_lock_release();
673 pa_autospawn_lock_done(TRUE);
674
675 autospawn_locked = FALSE;
676 autospawn_fd = -1;
677 }
678
679 pa_assert_se(pa_close(daemon_pipe[0]) == 0);
680 daemon_pipe[0] = -1;
681 #endif
682
683 if (conf->auto_log_target)
684 pa_log_set_target(PA_LOG_SYSLOG);
685
686 #ifdef HAVE_SETSID
687 setsid();
688 #endif
689 #ifdef HAVE_SETPGID
690 setpgid(0,0);
691 #endif
692
693 #ifndef OS_IS_WIN32
694 pa_close(0);
695 pa_close(1);
696 pa_close(2);
697
698 pa_assert_se(open("/dev/null", O_RDONLY) == 0);
699 pa_assert_se(open("/dev/null", O_WRONLY) == 1);
700 pa_assert_se(open("/dev/null", O_WRONLY) == 2);
701 #else
702 FreeConsole();
703 #endif
704
705 #ifdef SIGTTOU
706 signal(SIGTTOU, SIG_IGN);
707 #endif
708 #ifdef SIGTTIN
709 signal(SIGTTIN, SIG_IGN);
710 #endif
711 #ifdef SIGTSTP
712 signal(SIGTSTP, SIG_IGN);
713 #endif
714
715 #ifdef TIOCNOTTY
716 if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
717 ioctl(tty_fd, TIOCNOTTY, (char*) 0);
718 pa_assert_se(pa_close(tty_fd) == 0);
719 }
720 #endif
721 }
722
723 pa_set_env("PULSE_INTERNAL", "1");
724 pa_assert_se(chdir("/") == 0);
725 umask(0022);
726
727 #ifdef HAVE_SYS_RESOURCE_H
728 set_all_rlimits(conf);
729 #endif
730 pa_rtclock_hrtimer_enable();
731
732 pa_raise_priority(conf->nice_level);
733
734 if (conf->system_instance)
735 if (change_user() < 0)
736 goto finish;
737
738 pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
739
740 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
741 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
742 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
743
744 s = pa_uname_string();
745 pa_log_debug(_("Running on host: %s"), s);
746 pa_xfree(s);
747
748 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
749
750 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
751
752 #ifdef HAVE_VALGRIND_MEMCHECK_H
753 pa_log_debug(_("Compiled with Valgrind support: yes"));
754 #else
755 pa_log_debug(_("Compiled with Valgrind support: no"));
756 #endif
757
758 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
759
760 #ifdef __OPTIMIZE__
761 pa_log_debug(_("Optimized build: yes"));
762 #else
763 pa_log_debug(_("Optimized build: no"));
764 #endif
765
766 #ifdef NDEBUG
767 pa_log_debug(_("NDEBUG defined, all asserts disabled."));
768 #elif defined(FASTPATH)
769 pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
770 #else
771 pa_log_debug(_("All asserts enabled."));
772 #endif
773
774 if (!(s = pa_machine_id())) {
775 pa_log(_("Failed to get machine ID"));
776 goto finish;
777 }
778 pa_log_info(_("Machine ID is %s."), s);
779 pa_xfree(s);
780
781 if ((s = pa_session_id())) {
782 pa_log_info(_("Session ID is %s."), s);
783 pa_xfree(s);
784 }
785
786 if (!(s = pa_get_runtime_dir()))
787 goto finish;
788 pa_log_info(_("Using runtime directory %s."), s);
789 pa_xfree(s);
790
791 if (!(s = pa_get_state_dir()))
792 goto finish;
793 pa_log_info(_("Using state directory %s."), s);
794 pa_xfree(s);
795
796 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
797
798 if (pa_in_system_mode())
799 pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
800 "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
801 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
802
803 if (conf->use_pid_file) {
804 int z;
805
806 if ((z = pa_pid_file_create("pulseaudio")) != 0) {
807
808 if (conf->cmd == PA_CMD_START && z > 0) {
809 /* If we are already running and with are run in
810 * --start mode, then let's return this as success. */
811
812 retval = 0;
813 goto finish;
814 }
815
816 pa_log(_("pa_pid_file_create() failed."));
817 goto finish;
818 }
819
820 valid_pid_file = TRUE;
821 }
822
823 pa_disable_sigpipe();
824
825 if (pa_rtclock_hrtimer())
826 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
827 else
828 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
829
830 if (conf->lock_memory) {
831 #ifdef HAVE_SYS_MMAN_H
832 if (mlockall(MCL_FUTURE) < 0)
833 pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
834 else
835 pa_log_info("Sucessfully locked process into memory.");
836 #else
837 pa_log_warn("Memory locking requested but not supported on platform.");
838 #endif
839 }
840
841 pa_memtrap_install();
842
843 pa_assert_se(mainloop = pa_mainloop_new());
844
845 if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
846 pa_log(_("pa_core_new() failed."));
847 goto finish;
848 }
849
850 c->default_sample_spec = conf->default_sample_spec;
851 c->default_channel_map = conf->default_channel_map;
852 c->default_n_fragments = conf->default_n_fragments;
853 c->default_fragment_size_msec = conf->default_fragment_size_msec;
854 c->exit_idle_time = conf->exit_idle_time;
855 c->scache_idle_time = conf->scache_idle_time;
856 c->resample_method = conf->resample_method;
857 c->realtime_priority = conf->realtime_priority;
858 c->realtime_scheduling = !!conf->realtime_scheduling;
859 c->disable_remixing = !!conf->disable_remixing;
860 c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
861 c->running_as_daemon = !!conf->daemonize;
862 c->disallow_exit = conf->disallow_exit;
863 c->flat_volumes = conf->flat_volumes;
864 #ifdef HAVE_DBUS
865 c->server_type = conf->local_server_type;
866 #endif
867
868 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
869 pa_signal_new(SIGINT, signal_callback, c);
870 pa_signal_new(SIGTERM, signal_callback, c);
871 #ifdef SIGUSR1
872 pa_signal_new(SIGUSR1, signal_callback, c);
873 #endif
874 #ifdef SIGUSR2
875 pa_signal_new(SIGUSR2, signal_callback, c);
876 #endif
877 #ifdef SIGHUP
878 pa_signal_new(SIGHUP, signal_callback, c);
879 #endif
880
881 #ifdef OS_IS_WIN32
882 win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
883 #endif
884
885 oil_init();
886
887 if (!conf->no_cpu_limit)
888 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
889
890 buf = pa_strbuf_new();
891
892 #ifdef HAVE_DBUS
893 if (start_server) {
894 #endif
895 if (conf->load_default_script_file) {
896 FILE *f;
897
898 if ((f = pa_daemon_conf_open_default_script_file(conf))) {
899 r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
900 fclose(f);
901 }
902 }
903
904 if (r >= 0)
905 r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
906
907 pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
908 pa_xfree(s);
909
910 if (r < 0 && conf->fail) {
911 pa_log(_("Failed to initialize daemon."));
912 goto finish;
913 }
914
915 if (!c->modules || pa_idxset_size(c->modules) == 0) {
916 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
917 goto finish;
918 }
919 #ifdef HAVE_DBUS
920 } else {
921 /* When we just provide the D-Bus server lookup service, we don't want
922 * any modules to be loaded. We haven't loaded any so far, so one might
923 * think there's no way to contact the server, but receiving certain
924 * signals could still cause modules to load. */
925 conf->disallow_module_loading = TRUE;
926 }
927 #endif
928
929 /* We completed the initial module loading, so let's disable it
930 * from now on, if requested */
931 c->disallow_module_loading = !!conf->disallow_module_loading;
932
933 #ifdef HAVE_FORK
934 if (daemon_pipe[1] >= 0) {
935 int ok = 0;
936 pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
937 pa_close(daemon_pipe[1]);
938 daemon_pipe[1] = -1;
939 }
940 #endif
941
942 #ifdef HAVE_DBUS
943 if (!conf->system_instance) {
944 if (!(server_lookup = pa_dbusobj_server_lookup_new(c)))
945 goto finish;
946 if (!(lookup_service_bus = register_dbus_name(c, DBUS_BUS_SESSION, "org.pulseaudio.PulseAudio")))
947 goto finish;
948 }
949
950 if (start_server && !(server_bus = register_dbus_name(c, conf->system_instance ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, "org.pulseaudio.Server")))
951 goto finish;
952 #endif
953
954 pa_log_info(_("Daemon startup complete."));
955
956 retval = 0;
957 if (pa_mainloop_run(mainloop, &retval) < 0)
958 goto finish;
959
960 pa_log_info(_("Daemon shutdown initiated."));
961
962 finish:
963 #ifdef HAVE_DBUS
964 if (server_bus)
965 pa_dbus_connection_unref(server_bus);
966 if (lookup_service_bus)
967 pa_dbus_connection_unref(lookup_service_bus);
968 if (server_lookup)
969 pa_dbusobj_server_lookup_free(server_lookup);
970 #endif
971
972 if (autospawn_fd >= 0) {
973 if (autospawn_locked)
974 pa_autospawn_lock_release();
975
976 pa_autospawn_lock_done(FALSE);
977 }
978
979 #ifdef OS_IS_WIN32
980 if (win32_timer)
981 pa_mainloop_get_api(mainloop)->time_free(win32_timer);
982 #endif
983
984 if (c) {
985 pa_core_unref(c);
986 pa_log_info(_("Daemon terminated."));
987 }
988
989 if (!conf->no_cpu_limit)
990 pa_cpu_limit_done();
991
992 pa_signal_done();
993
994 #ifdef HAVE_FORK
995 if (daemon_pipe[1] >= 0)
996 pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
997
998 pa_close_pipe(daemon_pipe);
999 #endif
1000
1001 if (mainloop)
1002 pa_mainloop_free(mainloop);
1003
1004 if (conf)
1005 pa_daemon_conf_free(conf);
1006
1007 if (valid_pid_file)
1008 pa_pid_file_remove();
1009
1010 #ifdef OS_IS_WIN32
1011 WSACleanup();
1012 #endif
1013
1014 if (ltdl_init)
1015 pa_ltdl_done();
1016
1017 #ifdef HAVE_DBUS
1018 dbus_shutdown();
1019 #endif
1020
1021 return retval;
1022 }