daemon: during startup say whether we run in a VM
[pulseaudio-mirror.git] / src / daemon / main.c
blob0a8e57d3cb83b5592d5ca2aacbb34a235aaf73f9
1 /***
2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
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.
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.
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 ***/
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
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>
42 #ifdef HAVE_SYS_MMAN_H
43 #include <sys/mman.h>
44 #endif
46 #ifdef HAVE_SYS_IOCTL_H
47 #include <sys/ioctl.h>
48 #endif
50 #ifdef HAVE_PWD_H
51 #include <pwd.h>
52 #endif
53 #ifdef HAVE_GRP_H
54 #include <grp.h>
55 #endif
57 #ifdef HAVE_LIBWRAP
58 #include <syslog.h>
59 #include <tcpd.h>
60 #endif
62 #ifdef HAVE_DBUS
63 #include <dbus/dbus.h>
64 #endif
66 #include <pulse/mainloop.h>
67 #include <pulse/mainloop-signal.h>
68 #include <pulse/timeval.h>
69 #include <pulse/xmalloc.h>
70 #include <pulse/i18n.h>
72 #include <pulsecore/lock-autospawn.h>
73 #include <pulsecore/winsock.h>
74 #include <pulsecore/core-error.h>
75 #include <pulsecore/core-rtclock.h>
76 #include <pulsecore/core.h>
77 #include <pulsecore/memblock.h>
78 #include <pulsecore/module.h>
79 #include <pulsecore/cli-command.h>
80 #include <pulsecore/log.h>
81 #include <pulsecore/core-util.h>
82 #include <pulsecore/sioman.h>
83 #include <pulsecore/cli-text.h>
84 #include <pulsecore/pid.h>
85 #include <pulsecore/namereg.h>
86 #include <pulsecore/random.h>
87 #include <pulsecore/macro.h>
88 #include <pulsecore/mutex.h>
89 #include <pulsecore/thread.h>
90 #include <pulsecore/once.h>
91 #include <pulsecore/shm.h>
92 #include <pulsecore/memtrap.h>
93 #ifdef HAVE_DBUS
94 #include <pulsecore/dbus-shared.h>
95 #endif
96 #include <pulsecore/cpu-arm.h>
97 #include <pulsecore/cpu-x86.h>
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"
106 #ifdef HAVE_LIBWRAP
107 /* Only one instance of these variables */
108 int allow_severity = LOG_INFO;
109 int deny_severity = LOG_WARNING;
110 #endif
112 #ifdef HAVE_OSS_WRAPPER
113 /* padsp looks for this symbol in the running process and disables
114 * itself if it finds it and it is set to 7 (which is actually a bit
115 * mask). For details see padsp. */
116 int __padsp_disabled__ = 7;
117 #endif
119 #ifdef OS_IS_WIN32
121 static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval *tv, void *userdata) {
122 MSG msg;
123 struct timeval tvnext;
125 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
126 if (msg.message == WM_QUIT)
127 raise(SIGTERM);
128 else {
129 TranslateMessage(&msg);
130 DispatchMessage(&msg);
134 pa_timeval_add(pa_gettimeofday(&tvnext), 100000);
135 a->rtclock_time_restart(e, &tvnext);
138 #endif
140 static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
141 pa_log_info(_("Got signal %s."), pa_sig2str(sig));
143 switch (sig) {
144 #ifdef SIGUSR1
145 case SIGUSR1:
146 pa_module_load(userdata, "module-cli", NULL);
147 break;
148 #endif
150 #ifdef SIGUSR2
151 case SIGUSR2:
152 pa_module_load(userdata, "module-cli-protocol-unix", NULL);
153 break;
154 #endif
156 #ifdef SIGHUP
157 case SIGHUP: {
158 char *c = pa_full_status_string(userdata);
159 pa_log_notice("%s", c);
160 pa_xfree(c);
161 return;
163 #endif
165 case SIGINT:
166 case SIGTERM:
167 default:
168 pa_log_info(_("Exiting."));
169 m->quit(m, 1);
170 break;
174 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
176 static int change_user(void) {
177 struct passwd *pw;
178 struct group * gr;
179 int r;
181 /* This function is called only in system-wide mode. It creates a
182 * runtime dir in /var/run/ with proper UID/GID and drops privs
183 * afterwards. */
185 if (!(pw = getpwnam(PA_SYSTEM_USER))) {
186 pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER);
187 return -1;
190 if (!(gr = getgrnam(PA_SYSTEM_GROUP))) {
191 pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP);
192 return -1;
195 pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."),
196 PA_SYSTEM_USER, (unsigned long) pw->pw_uid,
197 PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid);
199 if (pw->pw_gid != gr->gr_gid) {
200 pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP);
201 return -1;
204 if (strcmp(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH) != 0)
205 pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
207 if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) {
208 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
209 return -1;
212 if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) {
213 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
214 return -1;
217 /* We don't create the config dir here, because we don't need to write to it */
219 if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) {
220 pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno));
221 return -1;
224 #if defined(HAVE_SETRESGID)
225 r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid);
226 #elif defined(HAVE_SETEGID)
227 if ((r = setgid(gr->gr_gid)) >= 0)
228 r = setegid(gr->gr_gid);
229 #elif defined(HAVE_SETREGID)
230 r = setregid(gr->gr_gid, gr->gr_gid);
231 #else
232 #error "No API to drop privileges"
233 #endif
235 if (r < 0) {
236 pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno));
237 return -1;
240 #if defined(HAVE_SETRESUID)
241 r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
242 #elif defined(HAVE_SETEUID)
243 if ((r = setuid(pw->pw_uid)) >= 0)
244 r = seteuid(pw->pw_uid);
245 #elif defined(HAVE_SETREUID)
246 r = setreuid(pw->pw_uid, pw->pw_uid);
247 #else
248 #error "No API to drop privileges"
249 #endif
251 if (r < 0) {
252 pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno));
253 return -1;
256 pa_set_env("USER", PA_SYSTEM_USER);
257 pa_set_env("USERNAME", PA_SYSTEM_USER);
258 pa_set_env("LOGNAME", PA_SYSTEM_USER);
259 pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH);
261 /* Relevant for pa_runtime_path() */
262 if (!getenv("PULSE_RUNTIME_PATH"))
263 pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH);
265 if (!getenv("PULSE_CONFIG_PATH"))
266 pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH);
268 if (!getenv("PULSE_STATE_PATH"))
269 pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
271 pa_log_info(_("Successfully dropped root privileges."));
273 return 0;
276 #else /* HAVE_PWD_H && HAVE_GRP_H */
278 static int change_user(void) {
279 pa_log(_("System wide mode unsupported on this platform."));
280 return -1;
283 #endif /* HAVE_PWD_H && HAVE_GRP_H */
285 #ifdef HAVE_SYS_RESOURCE_H
287 static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
288 struct rlimit rl;
289 pa_assert(r);
291 if (!r->is_set)
292 return 0;
294 rl.rlim_cur = rl.rlim_max = r->value;
296 if (setrlimit(resource, &rl) < 0) {
297 pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
298 return -1;
301 return 0;
304 static void set_all_rlimits(const pa_daemon_conf *conf) {
305 set_one_rlimit(&conf->rlimit_fsize, RLIMIT_FSIZE, "RLIMIT_FSIZE");
306 set_one_rlimit(&conf->rlimit_data, RLIMIT_DATA, "RLIMIT_DATA");
307 set_one_rlimit(&conf->rlimit_stack, RLIMIT_STACK, "RLIMIT_STACK");
308 set_one_rlimit(&conf->rlimit_core, RLIMIT_CORE, "RLIMIT_CORE");
309 #ifdef RLIMIT_RSS
310 set_one_rlimit(&conf->rlimit_rss, RLIMIT_RSS, "RLIMIT_RSS");
311 #endif
312 #ifdef RLIMIT_NPROC
313 set_one_rlimit(&conf->rlimit_nproc, RLIMIT_NPROC, "RLIMIT_NPROC");
314 #endif
315 #ifdef RLIMIT_NOFILE
316 set_one_rlimit(&conf->rlimit_nofile, RLIMIT_NOFILE, "RLIMIT_NOFILE");
317 #endif
318 #ifdef RLIMIT_MEMLOCK
319 set_one_rlimit(&conf->rlimit_memlock, RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK");
320 #endif
321 #ifdef RLIMIT_AS
322 set_one_rlimit(&conf->rlimit_as, RLIMIT_AS, "RLIMIT_AS");
323 #endif
324 #ifdef RLIMIT_LOCKS
325 set_one_rlimit(&conf->rlimit_locks, RLIMIT_LOCKS, "RLIMIT_LOCKS");
326 #endif
327 #ifdef RLIMIT_SIGPENDING
328 set_one_rlimit(&conf->rlimit_sigpending, RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING");
329 #endif
330 #ifdef RLIMIT_MSGQUEUE
331 set_one_rlimit(&conf->rlimit_msgqueue, RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE");
332 #endif
333 #ifdef RLIMIT_NICE
334 set_one_rlimit(&conf->rlimit_nice, RLIMIT_NICE, "RLIMIT_NICE");
335 #endif
336 #ifdef RLIMIT_RTPRIO
337 set_one_rlimit(&conf->rlimit_rtprio, RLIMIT_RTPRIO, "RLIMIT_RTPRIO");
338 #endif
339 #ifdef RLIMIT_RTTIME
340 set_one_rlimit(&conf->rlimit_rttime, RLIMIT_RTTIME, "RLIMIT_RTTIME");
341 #endif
343 #endif
345 #ifdef HAVE_DBUS
346 static pa_dbus_connection *register_dbus(pa_core *c) {
347 DBusError error;
348 pa_dbus_connection *conn;
350 dbus_error_init(&error);
352 if (!(conn = pa_dbus_bus_get(c, pa_in_system_mode() ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) {
353 pa_log_warn("Unable to contact D-Bus: %s: %s", error.name, error.message);
354 goto fail;
357 if (dbus_bus_request_name(pa_dbus_connection_get(conn), "org.pulseaudio.Server", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
358 pa_log_debug("Got org.pulseaudio.Server!");
359 return conn;
362 if (dbus_error_is_set(&error))
363 pa_log_warn("Failed to acquire org.pulseaudio.Server: %s: %s", error.name, error.message);
364 else
365 pa_log_warn("D-Bus name org.pulseaudio.Server already taken. Weird shit!");
367 /* PA cannot be started twice by the same user and hence we can
368 * ignore mostly the case that org.pulseaudio.Server is already
369 * taken. */
371 fail:
373 if (conn)
374 pa_dbus_connection_unref(conn);
376 dbus_error_free(&error);
377 return NULL;
379 #endif
381 int main(int argc, char *argv[]) {
382 pa_core *c = NULL;
383 pa_strbuf *buf = NULL;
384 pa_daemon_conf *conf = NULL;
385 pa_mainloop *mainloop = NULL;
386 char *s;
387 int r = 0, retval = 1, d = 0;
388 pa_bool_t valid_pid_file = FALSE;
389 pa_bool_t ltdl_init = FALSE;
390 int passed_fd = -1;
391 const char *e;
392 #ifdef HAVE_FORK
393 int daemon_pipe[2] = { -1, -1 };
394 #endif
395 #ifdef OS_IS_WIN32
396 pa_time_event *win32_timer;
397 struct timeval win32_tv;
398 #endif
399 int autospawn_fd = -1;
400 pa_bool_t autospawn_locked = FALSE;
401 #ifdef HAVE_DBUS
402 pa_dbus_connection *dbus = NULL;
403 #endif
405 pa_log_set_ident("pulseaudio");
406 pa_log_set_level(PA_LOG_NOTICE);
407 pa_log_set_flags(PA_LOG_COLORS|PA_LOG_PRINT_FILE|PA_LOG_PRINT_LEVEL, PA_LOG_RESET);
409 #if defined(__linux__) && defined(__OPTIMIZE__)
411 Disable lazy relocations to make usage of external libraries
412 more deterministic for our RT threads. We abuse __OPTIMIZE__ as
413 a check whether we are a debug build or not. This all is
414 admittedly a bit snake-oilish.
417 if (!getenv("LD_BIND_NOW")) {
418 char *rp;
419 char *canonical_rp;
421 /* We have to execute ourselves, because the libc caches the
422 * value of $LD_BIND_NOW on initialization. */
424 pa_set_env("LD_BIND_NOW", "1");
426 if ((canonical_rp = pa_realpath(PA_BINARY))) {
428 if ((rp = pa_readlink("/proc/self/exe"))) {
430 if (pa_streq(rp, canonical_rp))
431 pa_assert_se(execv(rp, argv) == 0);
432 else
433 pa_log_warn("/proc/self/exe does not point to %s, cannot self execute. Are you playing games?", canonical_rp);
435 pa_xfree(rp);
437 } else
438 pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
440 pa_xfree(canonical_rp);
442 } else
443 pa_log_warn("Couldn't canonicalize binary path, cannot self execute.");
445 #endif
447 if ((e = getenv("PULSE_PASSED_FD"))) {
448 passed_fd = atoi(e);
450 if (passed_fd <= 2)
451 passed_fd = -1;
454 /* We might be autospawned, in which case have no idea in which
455 * context we have been started. Let's cleanup our execution
456 * context as good as possible */
458 pa_reset_personality();
459 pa_drop_root();
460 pa_close_all(passed_fd, -1);
461 pa_reset_sigs(-1);
462 pa_unblock_sigs(-1);
463 pa_reset_priority();
465 setlocale(LC_ALL, "");
466 pa_init_i18n();
468 conf = pa_daemon_conf_new();
470 if (pa_daemon_conf_load(conf, NULL) < 0)
471 goto finish;
473 if (pa_daemon_conf_env(conf) < 0)
474 goto finish;
476 if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
477 pa_log(_("Failed to parse command line."));
478 goto finish;
481 pa_log_set_level(conf->log_level);
482 pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target);
483 if (conf->log_meta)
484 pa_log_set_flags(PA_LOG_PRINT_META, PA_LOG_SET);
485 if (conf->log_time)
486 pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
487 pa_log_set_show_backtrace(conf->log_backtrace);
489 LTDL_SET_PRELOADED_SYMBOLS();
490 pa_ltdl_init();
491 ltdl_init = TRUE;
493 if (conf->dl_search_path)
494 lt_dlsetsearchpath(conf->dl_search_path);
496 #ifdef OS_IS_WIN32
498 WSADATA data;
499 WSAStartup(MAKEWORD(2, 0), &data);
501 #endif
503 pa_random_seed();
505 switch (conf->cmd) {
506 case PA_CMD_DUMP_MODULES:
507 pa_dump_modules(conf, argc-d, argv+d);
508 retval = 0;
509 goto finish;
511 case PA_CMD_DUMP_CONF: {
512 s = pa_daemon_conf_dump(conf);
513 fputs(s, stdout);
514 pa_xfree(s);
515 retval = 0;
516 goto finish;
519 case PA_CMD_DUMP_RESAMPLE_METHODS: {
520 int i;
522 for (i = 0; i < PA_RESAMPLER_MAX; i++)
523 if (pa_resample_method_supported(i))
524 printf("%s\n", pa_resample_method_to_string(i));
526 retval = 0;
527 goto finish;
530 case PA_CMD_HELP :
531 pa_cmdline_help(argv[0]);
532 retval = 0;
533 goto finish;
535 case PA_CMD_VERSION :
536 printf(PACKAGE_NAME" "PACKAGE_VERSION"\n");
537 retval = 0;
538 goto finish;
540 case PA_CMD_CHECK: {
541 pid_t pid;
543 if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
544 pa_log_info(_("Daemon not running"));
545 else {
546 pa_log_info(_("Daemon running as PID %u"), pid);
547 retval = 0;
550 goto finish;
553 case PA_CMD_KILL:
555 if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
556 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
557 else
558 retval = 0;
560 goto finish;
562 case PA_CMD_CLEANUP_SHM:
564 if (pa_shm_cleanup() >= 0)
565 retval = 0;
567 goto finish;
569 default:
570 pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
573 if (getuid() == 0 && !conf->system_instance)
574 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
575 else if (getuid() != 0 && conf->system_instance) {
576 pa_log(_("Root privileges required."));
577 goto finish;
580 if (conf->cmd == PA_CMD_START && conf->system_instance) {
581 pa_log(_("--start not supported for system instances."));
582 goto finish;
585 if (conf->system_instance && !conf->disallow_exit)
586 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
588 if (conf->system_instance && !conf->disallow_module_loading)
589 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
591 if (conf->system_instance && !conf->disable_shm) {
592 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
593 conf->disable_shm = TRUE;
596 if (conf->system_instance && conf->exit_idle_time >= 0) {
597 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
598 conf->exit_idle_time = -1;
601 if (conf->cmd == PA_CMD_START) {
602 /* If we shall start PA only when it is not running yet, we
603 * first take the autospawn lock to make things
604 * synchronous. */
606 if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
607 pa_log("Failed to initialize autospawn lock");
608 goto finish;
611 if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
612 pa_log("Failed to acquire autospawn lock");
613 goto finish;
616 autospawn_locked = TRUE;
619 if (conf->daemonize) {
620 pid_t child;
622 if (pa_stdio_acquire() < 0) {
623 pa_log(_("Failed to acquire stdio."));
624 goto finish;
627 #ifdef HAVE_FORK
628 if (pipe(daemon_pipe) < 0) {
629 pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
630 goto finish;
633 if ((child = fork()) < 0) {
634 pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
635 goto finish;
638 if (child != 0) {
639 ssize_t n;
640 /* Father */
642 pa_assert_se(pa_close(daemon_pipe[1]) == 0);
643 daemon_pipe[1] = -1;
645 if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
647 if (n < 0)
648 pa_log(_("read() failed: %s"), pa_cstrerror(errno));
650 retval = 1;
653 if (retval)
654 pa_log(_("Daemon startup failed."));
655 else
656 pa_log_info(_("Daemon startup successful."));
658 goto finish;
661 if (autospawn_fd >= 0) {
662 /* The lock file is unlocked from the parent, so we need
663 * to close it in the child */
665 pa_autospawn_lock_release();
666 pa_autospawn_lock_done(TRUE);
668 autospawn_locked = FALSE;
669 autospawn_fd = -1;
672 pa_assert_se(pa_close(daemon_pipe[0]) == 0);
673 daemon_pipe[0] = -1;
674 #endif
676 if (conf->auto_log_target)
677 pa_log_set_target(PA_LOG_SYSLOG);
679 #ifdef HAVE_SETSID
680 setsid();
681 #endif
682 #ifdef HAVE_SETPGID
683 setpgid(0,0);
684 #endif
686 #ifndef OS_IS_WIN32
687 pa_close(0);
688 pa_close(1);
689 pa_close(2);
691 pa_assert_se(open("/dev/null", O_RDONLY) == 0);
692 pa_assert_se(open("/dev/null", O_WRONLY) == 1);
693 pa_assert_se(open("/dev/null", O_WRONLY) == 2);
694 #else
695 FreeConsole();
696 #endif
698 #ifdef SIGTTOU
699 signal(SIGTTOU, SIG_IGN);
700 #endif
701 #ifdef SIGTTIN
702 signal(SIGTTIN, SIG_IGN);
703 #endif
704 #ifdef SIGTSTP
705 signal(SIGTSTP, SIG_IGN);
706 #endif
708 #ifdef TIOCNOTTY
709 if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
710 ioctl(tty_fd, TIOCNOTTY, (char*) 0);
711 pa_assert_se(pa_close(tty_fd) == 0);
713 #endif
716 pa_set_env_and_record("PULSE_INTERNAL", "1");
717 pa_assert_se(chdir("/") == 0);
718 umask(0022);
720 #ifdef HAVE_SYS_RESOURCE_H
721 set_all_rlimits(conf);
722 #endif
723 pa_rtclock_hrtimer_enable();
725 pa_raise_priority(conf->nice_level);
727 if (conf->system_instance)
728 if (change_user() < 0)
729 goto finish;
731 pa_set_env_and_record("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
733 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
734 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
735 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
737 s = pa_uname_string();
738 pa_log_debug(_("Running on host: %s"), s);
739 pa_xfree(s);
741 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
743 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
745 #ifdef HAVE_VALGRIND_MEMCHECK_H
746 pa_log_debug(_("Compiled with Valgrind support: yes"));
747 #else
748 pa_log_debug(_("Compiled with Valgrind support: no"));
749 #endif
751 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
753 pa_log_debug(_("Running in VM: %s"), pa_yes_no(pa_running_in_vm()));
755 #ifdef __OPTIMIZE__
756 pa_log_debug(_("Optimized build: yes"));
757 #else
758 pa_log_debug(_("Optimized build: no"));
759 #endif
761 #ifdef NDEBUG
762 pa_log_debug(_("NDEBUG defined, all asserts disabled."));
763 #elif defined(FASTPATH)
764 pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
765 #else
766 pa_log_debug(_("All asserts enabled."));
767 #endif
769 if (!(s = pa_machine_id())) {
770 pa_log(_("Failed to get machine ID"));
771 goto finish;
773 pa_log_info(_("Machine ID is %s."), s);
774 pa_xfree(s);
776 if ((s = pa_session_id())) {
777 pa_log_info(_("Session ID is %s."), s);
778 pa_xfree(s);
781 if (!(s = pa_get_runtime_dir()))
782 goto finish;
783 pa_log_info(_("Using runtime directory %s."), s);
784 pa_xfree(s);
786 if (!(s = pa_get_state_dir()))
787 goto finish;
788 pa_log_info(_("Using state directory %s."), s);
789 pa_xfree(s);
791 pa_log_info(_("Using modules directory %s."), conf->dl_search_path);
793 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
795 if (pa_in_system_mode())
796 pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
797 "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
798 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
800 if (conf->use_pid_file) {
801 int z;
803 if ((z = pa_pid_file_create("pulseaudio")) != 0) {
805 if (conf->cmd == PA_CMD_START && z > 0) {
806 /* If we are already running and with are run in
807 * --start mode, then let's return this as success. */
809 retval = 0;
810 goto finish;
813 pa_log(_("pa_pid_file_create() failed."));
814 goto finish;
817 valid_pid_file = TRUE;
820 pa_disable_sigpipe();
822 if (pa_rtclock_hrtimer())
823 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
824 else
825 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
827 if (conf->lock_memory) {
828 #ifdef HAVE_SYS_MMAN_H
829 if (mlockall(MCL_FUTURE) < 0)
830 pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
831 else
832 pa_log_info("Sucessfully locked process into memory.");
833 #else
834 pa_log_warn("Memory locking requested but not supported on platform.");
835 #endif
838 pa_memtrap_install();
840 if (!getenv("PULSE_NO_SIMD")) {
841 pa_cpu_init_x86();
842 pa_cpu_init_arm();
845 pa_assert_se(mainloop = pa_mainloop_new());
847 if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
848 pa_log(_("pa_core_new() failed."));
849 goto finish;
852 c->default_sample_spec = conf->default_sample_spec;
853 c->default_channel_map = conf->default_channel_map;
854 c->default_n_fragments = conf->default_n_fragments;
855 c->default_fragment_size_msec = conf->default_fragment_size_msec;
856 c->exit_idle_time = conf->exit_idle_time;
857 c->scache_idle_time = conf->scache_idle_time;
858 c->resample_method = conf->resample_method;
859 c->realtime_priority = conf->realtime_priority;
860 c->realtime_scheduling = !!conf->realtime_scheduling;
861 c->disable_remixing = !!conf->disable_remixing;
862 c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
863 c->running_as_daemon = !!conf->daemonize;
864 c->disallow_exit = conf->disallow_exit;
865 c->flat_volumes = conf->flat_volumes;
867 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
868 pa_signal_new(SIGINT, signal_callback, c);
869 pa_signal_new(SIGTERM, signal_callback, c);
870 #ifdef SIGUSR1
871 pa_signal_new(SIGUSR1, signal_callback, c);
872 #endif
873 #ifdef SIGUSR2
874 pa_signal_new(SIGUSR2, signal_callback, c);
875 #endif
876 #ifdef SIGHUP
877 pa_signal_new(SIGHUP, signal_callback, c);
878 #endif
880 #ifdef OS_IS_WIN32
881 win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
882 #endif
884 if (!conf->no_cpu_limit)
885 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
887 buf = pa_strbuf_new();
888 if (conf->load_default_script_file) {
889 FILE *f;
891 if ((f = pa_daemon_conf_open_default_script_file(conf))) {
892 r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
893 fclose(f);
897 if (r >= 0)
898 r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
900 pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
901 pa_xfree(s);
903 /* We completed the initial module loading, so let's disable it
904 * from now on, if requested */
905 c->disallow_module_loading = !!conf->disallow_module_loading;
907 if (r < 0 && conf->fail) {
908 pa_log(_("Failed to initialize daemon."));
909 goto finish;
912 if (!c->modules || pa_idxset_size(c->modules) == 0) {
913 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
914 goto finish;
917 #ifdef HAVE_FORK
918 if (daemon_pipe[1] >= 0) {
919 int ok = 0;
920 pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
921 pa_close(daemon_pipe[1]);
922 daemon_pipe[1] = -1;
924 #endif
926 #ifdef HAVE_DBUS
927 dbus = register_dbus(c);
928 #endif
930 pa_log_info(_("Daemon startup complete."));
932 retval = 0;
933 if (pa_mainloop_run(mainloop, &retval) < 0)
934 goto finish;
936 pa_log_info(_("Daemon shutdown initiated."));
938 finish:
939 #ifdef HAVE_DBUS
940 if (dbus)
941 pa_dbus_connection_unref(dbus);
942 #endif
944 if (autospawn_fd >= 0) {
945 if (autospawn_locked)
946 pa_autospawn_lock_release();
948 pa_autospawn_lock_done(FALSE);
951 #ifdef OS_IS_WIN32
952 if (win32_timer)
953 pa_mainloop_get_api(mainloop)->time_free(win32_timer);
954 #endif
956 if (c) {
957 pa_core_unref(c);
958 pa_log_info(_("Daemon terminated."));
961 if (!conf->no_cpu_limit)
962 pa_cpu_limit_done();
964 pa_signal_done();
966 #ifdef HAVE_FORK
967 if (daemon_pipe[1] >= 0)
968 pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
970 pa_close_pipe(daemon_pipe);
971 #endif
973 if (mainloop)
974 pa_mainloop_free(mainloop);
976 if (conf)
977 pa_daemon_conf_free(conf);
979 if (valid_pid_file)
980 pa_pid_file_remove();
982 /* This has no real purpose except making things valgrind-clean */
983 pa_unset_env_recorded();
985 #ifdef OS_IS_WIN32
986 WSACleanup();
987 #endif
989 if (ltdl_init)
990 pa_ltdl_done();
992 #ifdef HAVE_DBUS
993 dbus_shutdown();
994 #endif
996 return retval;