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
39 #include <sys/types.h>
42 #ifdef HAVE_SYS_MMAN_H
46 #ifdef HAVE_SYS_IOCTL_H
47 #include <sys/ioctl.h>
63 #include <dbus/dbus.h>
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>
94 #include <pulsecore/dbus-shared.h>
96 #include <pulsecore/cpu-arm.h>
97 #include <pulsecore/cpu-x86.h>
100 #include "cpulimit.h"
101 #include "daemon-conf.h"
102 #include "dumpmodules.h"
104 #include "ltdl-bind-now.h"
107 /* Only one instance of these variables */
108 int allow_severity
= LOG_INFO
;
109 int deny_severity
= LOG_WARNING
;
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;
121 static void message_cb(pa_mainloop_api
*a
, pa_time_event
*e
, const struct timeval
*tv
, void *userdata
) {
123 struct timeval tvnext
;
125 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
126 if (msg
.message
== WM_QUIT
)
129 TranslateMessage(&msg
);
130 DispatchMessage(&msg
);
134 pa_timeval_add(pa_gettimeofday(&tvnext
), 100000);
135 a
->rtclock_time_restart(e
, &tvnext
);
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
));
146 pa_module_load(userdata
, "module-cli", NULL
);
152 pa_module_load(userdata
, "module-cli-protocol-unix", NULL
);
158 char *c
= pa_full_status_string(userdata
);
159 pa_log_notice("%s", c
);
168 pa_log_info(_("Exiting."));
174 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
176 static int change_user(void) {
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
185 if (!(pw
= getpwnam(PA_SYSTEM_USER
))) {
186 pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER
);
190 if (!(gr
= getgrnam(PA_SYSTEM_GROUP
))) {
191 pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP
);
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
);
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
));
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
));
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
));
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
);
232 #error "No API to drop privileges"
236 pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno
));
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
);
248 #error "No API to drop privileges"
252 pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno
));
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."));
276 #else /* HAVE_PWD_H && HAVE_GRP_H */
278 static int change_user(void) {
279 pa_log(_("System wide mode unsupported on this platform."));
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
) {
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
));
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");
310 set_one_rlimit(&conf
->rlimit_rss
, RLIMIT_RSS
, "RLIMIT_RSS");
313 set_one_rlimit(&conf
->rlimit_nproc
, RLIMIT_NPROC
, "RLIMIT_NPROC");
316 set_one_rlimit(&conf
->rlimit_nofile
, RLIMIT_NOFILE
, "RLIMIT_NOFILE");
318 #ifdef RLIMIT_MEMLOCK
319 set_one_rlimit(&conf
->rlimit_memlock
, RLIMIT_MEMLOCK
, "RLIMIT_MEMLOCK");
322 set_one_rlimit(&conf
->rlimit_as
, RLIMIT_AS
, "RLIMIT_AS");
325 set_one_rlimit(&conf
->rlimit_locks
, RLIMIT_LOCKS
, "RLIMIT_LOCKS");
327 #ifdef RLIMIT_SIGPENDING
328 set_one_rlimit(&conf
->rlimit_sigpending
, RLIMIT_SIGPENDING
, "RLIMIT_SIGPENDING");
330 #ifdef RLIMIT_MSGQUEUE
331 set_one_rlimit(&conf
->rlimit_msgqueue
, RLIMIT_MSGQUEUE
, "RLIMIT_MSGQUEUE");
334 set_one_rlimit(&conf
->rlimit_nice
, RLIMIT_NICE
, "RLIMIT_NICE");
337 set_one_rlimit(&conf
->rlimit_rtprio
, RLIMIT_RTPRIO
, "RLIMIT_RTPRIO");
340 set_one_rlimit(&conf
->rlimit_rttime
, RLIMIT_RTTIME
, "RLIMIT_RTTIME");
346 static pa_dbus_connection
*register_dbus(pa_core
*c
) {
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
);
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!");
362 if (dbus_error_is_set(&error
))
363 pa_log_warn("Failed to acquire org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
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
374 pa_dbus_connection_unref(conn
);
376 dbus_error_free(&error
);
381 int main(int argc
, char *argv
[]) {
383 pa_strbuf
*buf
= NULL
;
384 pa_daemon_conf
*conf
= NULL
;
385 pa_mainloop
*mainloop
= NULL
;
387 int r
= 0, retval
= 1, d
= 0;
388 pa_bool_t valid_pid_file
= FALSE
;
389 pa_bool_t ltdl_init
= FALSE
;
393 int daemon_pipe
[2] = { -1, -1 };
396 pa_time_event
*win32_timer
;
397 struct timeval win32_tv
;
399 int autospawn_fd
= -1;
400 pa_bool_t autospawn_locked
= FALSE
;
402 pa_dbus_connection
*dbus
= NULL
;
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")) {
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 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);
433 pa_log_warn("/proc/self/exe does not point to %s, cannot self execute. Are you playing games?", canonical_rp
);
438 pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
440 pa_xfree(canonical_rp
);
444 if ((e
= getenv("PULSE_PASSED_FD"))) {
451 /* We might be autospawned, in which case have no idea in which
452 * context we have been started. Let's cleanup our execution
453 * context as good as possible */
455 pa_reset_personality();
457 pa_close_all(passed_fd
, -1);
462 setlocale(LC_ALL
, "");
465 conf
= pa_daemon_conf_new();
467 if (pa_daemon_conf_load(conf
, NULL
) < 0)
470 if (pa_daemon_conf_env(conf
) < 0)
473 if (pa_cmdline_parse(conf
, argc
, argv
, &d
) < 0) {
474 pa_log(_("Failed to parse command line."));
478 pa_log_set_level(conf
->log_level
);
479 pa_log_set_target(conf
->auto_log_target
? PA_LOG_STDERR
: conf
->log_target
);
481 pa_log_set_flags(PA_LOG_PRINT_META
, PA_LOG_SET
);
483 pa_log_set_flags(PA_LOG_PRINT_TIME
, PA_LOG_SET
);
484 pa_log_set_show_backtrace(conf
->log_backtrace
);
486 LTDL_SET_PRELOADED_SYMBOLS();
490 if (conf
->dl_search_path
)
491 lt_dlsetsearchpath(conf
->dl_search_path
);
496 WSAStartup(MAKEWORD(2, 0), &data
);
503 case PA_CMD_DUMP_MODULES
:
504 pa_dump_modules(conf
, argc
-d
, argv
+d
);
508 case PA_CMD_DUMP_CONF
: {
509 s
= pa_daemon_conf_dump(conf
);
516 case PA_CMD_DUMP_RESAMPLE_METHODS
: {
519 for (i
= 0; i
< PA_RESAMPLER_MAX
; i
++)
520 if (pa_resample_method_supported(i
))
521 printf("%s\n", pa_resample_method_to_string(i
));
528 pa_cmdline_help(argv
[0]);
532 case PA_CMD_VERSION
:
533 printf(PACKAGE_NAME
" "PACKAGE_VERSION
"\n");
540 if (pa_pid_file_check_running(&pid
, "pulseaudio") < 0)
541 pa_log_info(_("Daemon not running"));
543 pa_log_info(_("Daemon running as PID %u"), pid
);
552 if (pa_pid_file_kill(SIGINT
, NULL
, "pulseaudio") < 0)
553 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno
));
559 case PA_CMD_CLEANUP_SHM
:
561 if (pa_shm_cleanup() >= 0)
567 pa_assert(conf
->cmd
== PA_CMD_DAEMON
|| conf
->cmd
== PA_CMD_START
);
570 if (getuid() == 0 && !conf
->system_instance
)
571 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
572 else if (getuid() != 0 && conf
->system_instance
) {
573 pa_log(_("Root privileges required."));
577 if (conf
->cmd
== PA_CMD_START
&& conf
->system_instance
) {
578 pa_log(_("--start not supported for system instances."));
582 if (conf
->system_instance
&& !conf
->disallow_exit
)
583 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
585 if (conf
->system_instance
&& !conf
->disallow_module_loading
)
586 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
588 if (conf
->system_instance
&& !conf
->disable_shm
) {
589 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
590 conf
->disable_shm
= TRUE
;
593 if (conf
->system_instance
&& conf
->exit_idle_time
>= 0) {
594 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
595 conf
->exit_idle_time
= -1;
598 if (conf
->cmd
== PA_CMD_START
) {
599 /* If we shall start PA only when it is not running yet, we
600 * first take the autospawn lock to make things
603 if ((autospawn_fd
= pa_autospawn_lock_init()) < 0) {
604 pa_log("Failed to initialize autospawn lock");
608 if ((pa_autospawn_lock_acquire(TRUE
) < 0)) {
609 pa_log("Failed to acquire autospawn lock");
613 autospawn_locked
= TRUE
;
616 if (conf
->daemonize
) {
620 if (pa_stdio_acquire() < 0) {
621 pa_log(_("Failed to acquire stdio."));
626 if (pipe(daemon_pipe
) < 0) {
627 pa_log(_("pipe failed: %s"), pa_cstrerror(errno
));
631 if ((child
= fork()) < 0) {
632 pa_log(_("fork() failed: %s"), pa_cstrerror(errno
));
640 pa_assert_se(pa_close(daemon_pipe
[1]) == 0);
643 if ((n
= pa_loop_read(daemon_pipe
[0], &retval
, sizeof(retval
), NULL
)) != sizeof(retval
)) {
646 pa_log(_("read() failed: %s"), pa_cstrerror(errno
));
652 pa_log(_("Daemon startup failed."));
654 pa_log_info(_("Daemon startup successful."));
659 if (autospawn_fd
>= 0) {
660 /* The lock file is unlocked from the parent, so we need
661 * to close it in the child */
663 pa_autospawn_lock_release();
664 pa_autospawn_lock_done(TRUE
);
666 autospawn_locked
= FALSE
;
670 pa_assert_se(pa_close(daemon_pipe
[0]) == 0);
674 if (conf
->auto_log_target
)
675 pa_log_set_target(PA_LOG_SYSLOG
);
689 pa_assert_se(open("/dev/null", O_RDONLY
) == 0);
690 pa_assert_se(open("/dev/null", O_WRONLY
) == 1);
691 pa_assert_se(open("/dev/null", O_WRONLY
) == 2);
697 signal(SIGTTOU
, SIG_IGN
);
700 signal(SIGTTIN
, SIG_IGN
);
703 signal(SIGTSTP
, SIG_IGN
);
707 if ((tty_fd
= open("/dev/tty", O_RDWR
)) >= 0) {
708 ioctl(tty_fd
, TIOCNOTTY
, (char*) 0);
709 pa_assert_se(pa_close(tty_fd
) == 0);
714 pa_set_env_and_record("PULSE_INTERNAL", "1");
715 pa_assert_se(chdir("/") == 0);
718 #ifdef HAVE_SYS_RESOURCE_H
719 set_all_rlimits(conf
);
721 pa_rtclock_hrtimer_enable();
723 pa_raise_priority(conf
->nice_level
);
725 if (conf
->system_instance
)
726 if (change_user() < 0)
729 pa_set_env_and_record("PULSE_SYSTEM", conf
->system_instance
? "1" : "0");
731 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION
);
732 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST
);
733 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS
);
735 s
= pa_uname_string();
736 pa_log_debug(_("Running on host: %s"), s
);
739 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
741 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE
);
743 #ifdef HAVE_VALGRIND_MEMCHECK_H
744 pa_log_debug(_("Compiled with Valgrind support: yes"));
746 pa_log_debug(_("Compiled with Valgrind support: no"));
749 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
752 pa_log_debug(_("Optimized build: yes"));
754 pa_log_debug(_("Optimized build: no"));
758 pa_log_debug(_("NDEBUG defined, all asserts disabled."));
759 #elif defined(FASTPATH)
760 pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
762 pa_log_debug(_("All asserts enabled."));
765 if (!(s
= pa_machine_id())) {
766 pa_log(_("Failed to get machine ID"));
769 pa_log_info(_("Machine ID is %s."), s
);
772 if ((s
= pa_session_id())) {
773 pa_log_info(_("Session ID is %s."), s
);
777 if (!(s
= pa_get_runtime_dir()))
779 pa_log_info(_("Using runtime directory %s."), s
);
782 if (!(s
= pa_get_state_dir()))
784 pa_log_info(_("Using state directory %s."), s
);
787 pa_log_info(_("Using modules directory %s."), conf
->dl_search_path
);
789 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
791 if (pa_in_system_mode())
792 pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
793 "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
794 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
796 if (conf
->use_pid_file
) {
799 if ((z
= pa_pid_file_create("pulseaudio")) != 0) {
801 if (conf
->cmd
== PA_CMD_START
&& z
> 0) {
802 /* If we are already running and with are run in
803 * --start mode, then let's return this as success. */
809 pa_log(_("pa_pid_file_create() failed."));
813 valid_pid_file
= TRUE
;
816 pa_disable_sigpipe();
818 if (pa_rtclock_hrtimer())
819 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
821 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
823 if (conf
->lock_memory
) {
824 #ifdef HAVE_SYS_MMAN_H
825 if (mlockall(MCL_FUTURE
) < 0)
826 pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno
));
828 pa_log_info("Sucessfully locked process into memory.");
830 pa_log_warn("Memory locking requested but not supported on platform.");
834 pa_memtrap_install();
836 if (!getenv("PULSE_NO_SIMD")) {
841 pa_assert_se(mainloop
= pa_mainloop_new());
843 if (!(c
= pa_core_new(pa_mainloop_get_api(mainloop
), !conf
->disable_shm
, conf
->shm_size
))) {
844 pa_log(_("pa_core_new() failed."));
848 c
->default_sample_spec
= conf
->default_sample_spec
;
849 c
->default_channel_map
= conf
->default_channel_map
;
850 c
->default_n_fragments
= conf
->default_n_fragments
;
851 c
->default_fragment_size_msec
= conf
->default_fragment_size_msec
;
852 c
->exit_idle_time
= conf
->exit_idle_time
;
853 c
->scache_idle_time
= conf
->scache_idle_time
;
854 c
->resample_method
= conf
->resample_method
;
855 c
->realtime_priority
= conf
->realtime_priority
;
856 c
->realtime_scheduling
= !!conf
->realtime_scheduling
;
857 c
->disable_remixing
= !!conf
->disable_remixing
;
858 c
->disable_lfe_remixing
= !!conf
->disable_lfe_remixing
;
859 c
->running_as_daemon
= !!conf
->daemonize
;
860 c
->disallow_exit
= conf
->disallow_exit
;
861 c
->flat_volumes
= conf
->flat_volumes
;
863 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop
)) == 0);
864 pa_signal_new(SIGINT
, signal_callback
, c
);
865 pa_signal_new(SIGTERM
, signal_callback
, c
);
867 pa_signal_new(SIGUSR1
, signal_callback
, c
);
870 pa_signal_new(SIGUSR2
, signal_callback
, c
);
873 pa_signal_new(SIGHUP
, signal_callback
, c
);
877 win32_timer
= pa_mainloop_get_api(mainloop
)->rtclock_time_new(pa_mainloop_get_api(mainloop
), pa_gettimeofday(&win32_tv
), message_cb
, NULL
);
880 if (!conf
->no_cpu_limit
)
881 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop
)) == 0);
883 buf
= pa_strbuf_new();
884 if (conf
->load_default_script_file
) {
887 if ((f
= pa_daemon_conf_open_default_script_file(conf
))) {
888 r
= pa_cli_command_execute_file_stream(c
, f
, buf
, &conf
->fail
);
894 r
= pa_cli_command_execute(c
, conf
->script_commands
, buf
, &conf
->fail
);
896 pa_log_error("%s", s
= pa_strbuf_tostring_free(buf
));
899 /* We completed the initial module loading, so let's disable it
900 * from now on, if requested */
901 c
->disallow_module_loading
= !!conf
->disallow_module_loading
;
903 if (r
< 0 && conf
->fail
) {
904 pa_log(_("Failed to initialize daemon."));
908 if (!c
->modules
|| pa_idxset_size(c
->modules
) == 0) {
909 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
914 if (daemon_pipe
[1] >= 0) {
916 pa_loop_write(daemon_pipe
[1], &ok
, sizeof(ok
), NULL
);
917 pa_close(daemon_pipe
[1]);
923 dbus
= register_dbus(c
);
926 pa_log_info(_("Daemon startup complete."));
929 if (pa_mainloop_run(mainloop
, &retval
) < 0)
932 pa_log_info(_("Daemon shutdown initiated."));
937 pa_dbus_connection_unref(dbus
);
940 if (autospawn_fd
>= 0) {
941 if (autospawn_locked
)
942 pa_autospawn_lock_release();
944 pa_autospawn_lock_done(FALSE
);
949 pa_mainloop_get_api(mainloop
)->time_free(win32_timer
);
954 pa_log_info(_("Daemon terminated."));
957 if (!conf
->no_cpu_limit
)
963 if (daemon_pipe
[1] >= 0)
964 pa_loop_write(daemon_pipe
[1], &retval
, sizeof(retval
), NULL
);
966 pa_close_pipe(daemon_pipe
);
970 pa_mainloop_free(mainloop
);
973 pa_daemon_conf_free(conf
);
976 pa_pid_file_remove();
978 /* This has no real purpose except making things valgrind-clean */
979 pa_unset_env_recorded();