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 #include <liboil/liboil.h>
44 #ifdef HAVE_SYS_MMAN_H
48 #ifdef HAVE_SYS_IOCTL_H
49 #include <sys/ioctl.h>
65 #include <dbus/dbus.h>
69 #include <sys/personality.h>
72 #include <pulse/mainloop.h>
73 #include <pulse/mainloop-signal.h>
74 #include <pulse/timeval.h>
75 #include <pulse/xmalloc.h>
76 #include <pulse/i18n.h>
78 #include <pulsecore/lock-autospawn.h>
79 #include <pulsecore/winsock.h>
80 #include <pulsecore/core-error.h>
81 #include <pulsecore/core-rtclock.h>
82 #include <pulsecore/core.h>
83 #include <pulsecore/memblock.h>
84 #include <pulsecore/module.h>
85 #include <pulsecore/cli-command.h>
86 #include <pulsecore/log.h>
87 #include <pulsecore/core-util.h>
88 #include <pulsecore/sioman.h>
89 #include <pulsecore/cli-text.h>
90 #include <pulsecore/pid.h>
91 #include <pulsecore/namereg.h>
92 #include <pulsecore/random.h>
93 #include <pulsecore/macro.h>
94 #include <pulsecore/mutex.h>
95 #include <pulsecore/thread.h>
96 #include <pulsecore/once.h>
97 #include <pulsecore/shm.h>
98 #include <pulsecore/memtrap.h>
100 #include <pulsecore/dbus-shared.h>
104 #include "cpulimit.h"
105 #include "daemon-conf.h"
106 #include "dumpmodules.h"
108 #include "ltdl-bind-now.h"
111 /* Only one instance of these variables */
112 int allow_severity
= LOG_INFO
;
113 int deny_severity
= LOG_WARNING
;
117 /* padsp looks for this symbol in the running process and disables
118 * itself if it finds it and it is set to 7 (which is actually a bit
119 * mask). For details see padsp. */
120 int __padsp_disabled__
= 7;
125 static void message_cb(pa_mainloop_api
*a
, pa_time_event
*e
, const struct timeval
*tv
, void *userdata
) {
127 struct timeval tvnext
;
129 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
130 if (msg
.message
== WM_QUIT
)
133 TranslateMessage(&msg
);
134 DispatchMessage(&msg
);
138 pa_timeval_add(pa_gettimeofday(&tvnext
), 100000);
139 a
->rtclock_time_restart(e
, &tvnext
);
144 static void signal_callback(pa_mainloop_api
*m
, pa_signal_event
*e
, int sig
, void *userdata
) {
145 pa_log_info(_("Got signal %s."), pa_sig2str(sig
));
150 pa_module_load(userdata
, "module-cli", NULL
);
156 pa_module_load(userdata
, "module-cli-protocol-unix", NULL
);
162 char *c
= pa_full_status_string(userdata
);
163 pa_log_notice("%s", c
);
172 pa_log_info(_("Exiting."));
178 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
180 static int change_user(void) {
185 /* This function is called only in system-wide mode. It creates a
186 * runtime dir in /var/run/ with proper UID/GID and drops privs
189 if (!(pw
= getpwnam(PA_SYSTEM_USER
))) {
190 pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER
);
194 if (!(gr
= getgrnam(PA_SYSTEM_GROUP
))) {
195 pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP
);
199 pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."),
200 PA_SYSTEM_USER
, (unsigned long) pw
->pw_uid
,
201 PA_SYSTEM_GROUP
, (unsigned long) gr
->gr_gid
);
203 if (pw
->pw_gid
!= gr
->gr_gid
) {
204 pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER
, PA_SYSTEM_GROUP
);
208 if (strcmp(pw
->pw_dir
, PA_SYSTEM_RUNTIME_PATH
) != 0)
209 pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER
, PA_SYSTEM_RUNTIME_PATH
);
211 if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH
, 0755, pw
->pw_uid
, gr
->gr_gid
) < 0) {
212 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH
, pa_cstrerror(errno
));
216 if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH
, 0700, pw
->pw_uid
, gr
->gr_gid
) < 0) {
217 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH
, pa_cstrerror(errno
));
221 /* We don't create the config dir here, because we don't need to write to it */
223 if (initgroups(PA_SYSTEM_USER
, gr
->gr_gid
) != 0) {
224 pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno
));
228 #if defined(HAVE_SETRESGID)
229 r
= setresgid(gr
->gr_gid
, gr
->gr_gid
, gr
->gr_gid
);
230 #elif defined(HAVE_SETEGID)
231 if ((r
= setgid(gr
->gr_gid
)) >= 0)
232 r
= setegid(gr
->gr_gid
);
233 #elif defined(HAVE_SETREGID)
234 r
= setregid(gr
->gr_gid
, gr
->gr_gid
);
236 #error "No API to drop privileges"
240 pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno
));
244 #if defined(HAVE_SETRESUID)
245 r
= setresuid(pw
->pw_uid
, pw
->pw_uid
, pw
->pw_uid
);
246 #elif defined(HAVE_SETEUID)
247 if ((r
= setuid(pw
->pw_uid
)) >= 0)
248 r
= seteuid(pw
->pw_uid
);
249 #elif defined(HAVE_SETREUID)
250 r
= setreuid(pw
->pw_uid
, pw
->pw_uid
);
252 #error "No API to drop privileges"
256 pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno
));
260 pa_set_env("USER", PA_SYSTEM_USER
);
261 pa_set_env("USERNAME", PA_SYSTEM_USER
);
262 pa_set_env("LOGNAME", PA_SYSTEM_USER
);
263 pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH
);
265 /* Relevant for pa_runtime_path() */
266 pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH
);
267 pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH
);
268 pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH
);
270 pa_log_info(_("Successfully dropped root privileges."));
275 #else /* HAVE_PWD_H && HAVE_GRP_H */
277 static int change_user(void) {
278 pa_log(_("System wide mode unsupported on this platform."));
282 #endif /* HAVE_PWD_H && HAVE_GRP_H */
284 #ifdef HAVE_SYS_RESOURCE_H
286 static int set_one_rlimit(const pa_rlimit
*r
, int resource
, const char *name
) {
293 rl
.rlim_cur
= rl
.rlim_max
= r
->value
;
295 if (setrlimit(resource
, &rl
) < 0) {
296 pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name
, (unsigned) r
->value
, (unsigned) r
->value
, pa_cstrerror(errno
));
303 static void set_all_rlimits(const pa_daemon_conf
*conf
) {
304 set_one_rlimit(&conf
->rlimit_fsize
, RLIMIT_FSIZE
, "RLIMIT_FSIZE");
305 set_one_rlimit(&conf
->rlimit_data
, RLIMIT_DATA
, "RLIMIT_DATA");
306 set_one_rlimit(&conf
->rlimit_stack
, RLIMIT_STACK
, "RLIMIT_STACK");
307 set_one_rlimit(&conf
->rlimit_core
, RLIMIT_CORE
, "RLIMIT_CORE");
309 set_one_rlimit(&conf
->rlimit_rss
, RLIMIT_RSS
, "RLIMIT_RSS");
312 set_one_rlimit(&conf
->rlimit_nproc
, RLIMIT_NPROC
, "RLIMIT_NPROC");
315 set_one_rlimit(&conf
->rlimit_nofile
, RLIMIT_NOFILE
, "RLIMIT_NOFILE");
317 #ifdef RLIMIT_MEMLOCK
318 set_one_rlimit(&conf
->rlimit_memlock
, RLIMIT_MEMLOCK
, "RLIMIT_MEMLOCK");
321 set_one_rlimit(&conf
->rlimit_as
, RLIMIT_AS
, "RLIMIT_AS");
324 set_one_rlimit(&conf
->rlimit_locks
, RLIMIT_LOCKS
, "RLIMIT_LOCKS");
326 #ifdef RLIMIT_SIGPENDING
327 set_one_rlimit(&conf
->rlimit_sigpending
, RLIMIT_SIGPENDING
, "RLIMIT_SIGPENDING");
329 #ifdef RLIMIT_MSGQUEUE
330 set_one_rlimit(&conf
->rlimit_msgqueue
, RLIMIT_MSGQUEUE
, "RLIMIT_MSGQUEUE");
333 set_one_rlimit(&conf
->rlimit_nice
, RLIMIT_NICE
, "RLIMIT_NICE");
336 set_one_rlimit(&conf
->rlimit_rtprio
, RLIMIT_RTPRIO
, "RLIMIT_RTPRIO");
339 set_one_rlimit(&conf
->rlimit_rttime
, RLIMIT_RTTIME
, "RLIMIT_RTTIME");
345 static pa_dbus_connection
*register_dbus(pa_core
*c
) {
347 pa_dbus_connection
*conn
;
349 dbus_error_init(&error
);
351 if (!(conn
= pa_dbus_bus_get(c
, pa_in_system_mode() ? DBUS_BUS_SYSTEM
: DBUS_BUS_SESSION
, &error
)) || dbus_error_is_set(&error
)) {
352 pa_log_warn("Unable to contact D-Bus: %s: %s", error
.name
, error
.message
);
356 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
) {
357 pa_log_debug("Got org.pulseaudio.Server!");
361 if (dbus_error_is_set(&error
))
362 pa_log_warn("Failed to acquire org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
364 pa_log_warn("D-Bus name org.pulseaudio.Server already taken. Weird shit!");
366 /* PA cannot be started twice by the same user and hence we can
367 * ignore mostly the case that org.pulseaudio.Server is already
373 pa_dbus_connection_unref(conn
);
375 dbus_error_free(&error
);
380 int main(int argc
, char *argv
[]) {
382 pa_strbuf
*buf
= NULL
;
383 pa_daemon_conf
*conf
= NULL
;
384 pa_mainloop
*mainloop
= NULL
;
386 int r
= 0, retval
= 1, d
= 0;
387 pa_bool_t valid_pid_file
= FALSE
;
388 pa_bool_t ltdl_init
= FALSE
;
392 int daemon_pipe
[2] = { -1, -1 };
395 pa_time_event
*win32_timer
;
396 struct timeval win32_tv
;
398 int autospawn_fd
= -1;
399 pa_bool_t autospawn_locked
= FALSE
;
401 pa_dbus_connection
*dbus
= NULL
;
404 pa_log_set_ident("pulseaudio");
405 pa_log_set_level(PA_LOG_NOTICE
);
406 pa_log_set_flags(PA_LOG_COLORS
|PA_LOG_PRINT_FILE
|PA_LOG_PRINT_LEVEL
, PA_LOG_RESET
);
408 if ((e
= getenv("PULSE_PASSED_FD"))) {
415 /* We might be autospawned, in which case have no idea in which
416 * context we have been started. Let's cleanup our execution
417 * context as good as possible */
420 if (personality(PER_LINUX
) < 0)
421 pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno
));
425 pa_close_all(passed_fd
, -1);
429 setlocale(LC_ALL
, "");
432 conf
= pa_daemon_conf_new();
434 if (pa_daemon_conf_load(conf
, NULL
) < 0)
437 if (pa_daemon_conf_env(conf
) < 0)
440 if (pa_cmdline_parse(conf
, argc
, argv
, &d
) < 0) {
441 pa_log(_("Failed to parse command line."));
445 pa_log_set_level(conf
->log_level
);
446 pa_log_set_target(conf
->auto_log_target
? PA_LOG_STDERR
: conf
->log_target
);
448 pa_log_set_flags(PA_LOG_PRINT_META
, PA_LOG_SET
);
450 pa_log_set_flags(PA_LOG_PRINT_TIME
, PA_LOG_SET
);
451 pa_log_set_show_backtrace(conf
->log_backtrace
);
453 LTDL_SET_PRELOADED_SYMBOLS();
457 if (conf
->dl_search_path
)
458 lt_dlsetsearchpath(conf
->dl_search_path
);
463 WSAStartup(MAKEWORD(2, 0), &data
);
470 case PA_CMD_DUMP_MODULES
:
471 pa_dump_modules(conf
, argc
-d
, argv
+d
);
475 case PA_CMD_DUMP_CONF
: {
476 s
= pa_daemon_conf_dump(conf
);
483 case PA_CMD_DUMP_RESAMPLE_METHODS
: {
486 for (i
= 0; i
< PA_RESAMPLER_MAX
; i
++)
487 if (pa_resample_method_supported(i
))
488 printf("%s\n", pa_resample_method_to_string(i
));
495 pa_cmdline_help(argv
[0]);
499 case PA_CMD_VERSION
:
500 printf(PACKAGE_NAME
" "PACKAGE_VERSION
"\n");
507 if (pa_pid_file_check_running(&pid
, "pulseaudio") < 0)
508 pa_log_info(_("Daemon not running"));
510 pa_log_info(_("Daemon running as PID %u"), pid
);
519 if (pa_pid_file_kill(SIGINT
, NULL
, "pulseaudio") < 0)
520 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno
));
526 case PA_CMD_CLEANUP_SHM
:
528 if (pa_shm_cleanup() >= 0)
534 pa_assert(conf
->cmd
== PA_CMD_DAEMON
|| conf
->cmd
== PA_CMD_START
);
537 if (getuid() == 0 && !conf
->system_instance
)
538 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
539 else if (getuid() != 0 && conf
->system_instance
) {
540 pa_log(_("Root privileges required."));
544 if (conf
->cmd
== PA_CMD_START
&& conf
->system_instance
) {
545 pa_log(_("--start not supported for system instances."));
549 if (conf
->system_instance
&& !conf
->disallow_exit
)
550 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
552 if (conf
->system_instance
&& !conf
->disallow_module_loading
)
553 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
555 if (conf
->system_instance
&& !conf
->disable_shm
) {
556 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
557 conf
->disable_shm
= TRUE
;
560 if (conf
->system_instance
&& conf
->exit_idle_time
>= 0) {
561 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
562 conf
->exit_idle_time
= -1;
565 if (conf
->cmd
== PA_CMD_START
) {
566 /* If we shall start PA only when it is not running yet, we
567 * first take the autospawn lock to make things
570 if ((autospawn_fd
= pa_autospawn_lock_init()) < 0) {
571 pa_log("Failed to initialize autospawn lock");
575 if ((pa_autospawn_lock_acquire(TRUE
) < 0)) {
576 pa_log("Failed to acquire autospawn lock");
580 autospawn_locked
= TRUE
;
583 if (conf
->daemonize
) {
587 if (pa_stdio_acquire() < 0) {
588 pa_log(_("Failed to acquire stdio."));
593 if (pipe(daemon_pipe
) < 0) {
594 pa_log(_("pipe failed: %s"), pa_cstrerror(errno
));
598 if ((child
= fork()) < 0) {
599 pa_log(_("fork() failed: %s"), pa_cstrerror(errno
));
607 pa_assert_se(pa_close(daemon_pipe
[1]) == 0);
610 if ((n
= pa_loop_read(daemon_pipe
[0], &retval
, sizeof(retval
), NULL
)) != sizeof(retval
)) {
613 pa_log(_("read() failed: %s"), pa_cstrerror(errno
));
619 pa_log(_("Daemon startup failed."));
621 pa_log_info(_("Daemon startup successful."));
626 if (autospawn_fd
>= 0) {
627 /* The lock file is unlocked from the parent, so we need
628 * to close it in the child */
630 pa_autospawn_lock_release();
631 pa_autospawn_lock_done(TRUE
);
633 autospawn_locked
= FALSE
;
637 pa_assert_se(pa_close(daemon_pipe
[0]) == 0);
641 if (conf
->auto_log_target
)
642 pa_log_set_target(PA_LOG_SYSLOG
);
656 pa_assert_se(open("/dev/null", O_RDONLY
) == 0);
657 pa_assert_se(open("/dev/null", O_WRONLY
) == 1);
658 pa_assert_se(open("/dev/null", O_WRONLY
) == 2);
664 signal(SIGTTOU
, SIG_IGN
);
667 signal(SIGTTIN
, SIG_IGN
);
670 signal(SIGTSTP
, SIG_IGN
);
674 if ((tty_fd
= open("/dev/tty", O_RDWR
)) >= 0) {
675 ioctl(tty_fd
, TIOCNOTTY
, (char*) 0);
676 pa_assert_se(pa_close(tty_fd
) == 0);
681 pa_set_env("PULSE_INTERNAL", "1");
682 pa_assert_se(chdir("/") == 0);
685 #ifdef HAVE_SYS_RESOURCE_H
686 set_all_rlimits(conf
);
688 pa_rtclock_hrtimer_enable();
690 pa_raise_priority(conf
->nice_level
);
692 if (conf
->system_instance
)
693 if (change_user() < 0)
696 pa_set_env("PULSE_SYSTEM", conf
->system_instance
? "1" : "0");
698 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION
);
699 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST
);
700 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS
);
702 s
= pa_uname_string();
703 pa_log_debug(_("Running on host: %s"), s
);
706 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
708 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE
);
710 #ifdef HAVE_VALGRIND_MEMCHECK_H
711 pa_log_debug(_("Compiled with Valgrind support: yes"));
713 pa_log_debug(_("Compiled with Valgrind support: no"));
716 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
719 pa_log_debug(_("Optimized build: yes"));
721 pa_log_debug(_("Optimized build: no"));
725 pa_log_debug(_("NDEBUG defined, all asserts disabled."));
726 #elif defined(FASTPATH)
727 pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
729 pa_log_debug(_("All asserts enabled."));
732 if (!(s
= pa_machine_id())) {
733 pa_log(_("Failed to get machine ID"));
736 pa_log_info(_("Machine ID is %s."), s
);
739 if ((s
= pa_session_id())) {
740 pa_log_info(_("Session ID is %s."), s
);
744 if (!(s
= pa_get_runtime_dir()))
746 pa_log_info(_("Using runtime directory %s."), s
);
749 if (!(s
= pa_get_state_dir()))
751 pa_log_info(_("Using state directory %s."), s
);
754 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
756 if (pa_in_system_mode())
757 pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
758 "If you do it nonetheless then it's your own fault if things don't work as expected.\n"
759 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."));
761 if (conf
->use_pid_file
) {
764 if ((z
= pa_pid_file_create("pulseaudio")) != 0) {
766 if (conf
->cmd
== PA_CMD_START
&& z
> 0) {
767 /* If we are already running and with are run in
768 * --start mode, then let's return this as success. */
774 pa_log(_("pa_pid_file_create() failed."));
778 valid_pid_file
= TRUE
;
781 pa_disable_sigpipe();
783 if (pa_rtclock_hrtimer())
784 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
786 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
788 if (conf
->lock_memory
) {
789 #ifdef HAVE_SYS_MMAN_H
790 if (mlockall(MCL_FUTURE
) < 0)
791 pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno
));
793 pa_log_info("Sucessfully locked process into memory.");
795 pa_log_warn("Memory locking requested but not supported on platform.");
799 pa_memtrap_install();
801 pa_assert_se(mainloop
= pa_mainloop_new());
803 if (!(c
= pa_core_new(pa_mainloop_get_api(mainloop
), !conf
->disable_shm
, conf
->shm_size
))) {
804 pa_log(_("pa_core_new() failed."));
808 c
->default_sample_spec
= conf
->default_sample_spec
;
809 c
->default_channel_map
= conf
->default_channel_map
;
810 c
->default_n_fragments
= conf
->default_n_fragments
;
811 c
->default_fragment_size_msec
= conf
->default_fragment_size_msec
;
812 c
->exit_idle_time
= conf
->exit_idle_time
;
813 c
->scache_idle_time
= conf
->scache_idle_time
;
814 c
->resample_method
= conf
->resample_method
;
815 c
->realtime_priority
= conf
->realtime_priority
;
816 c
->realtime_scheduling
= !!conf
->realtime_scheduling
;
817 c
->disable_remixing
= !!conf
->disable_remixing
;
818 c
->disable_lfe_remixing
= !!conf
->disable_lfe_remixing
;
819 c
->running_as_daemon
= !!conf
->daemonize
;
820 c
->disallow_exit
= conf
->disallow_exit
;
821 c
->flat_volumes
= conf
->flat_volumes
;
823 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop
)) == 0);
824 pa_signal_new(SIGINT
, signal_callback
, c
);
825 pa_signal_new(SIGTERM
, signal_callback
, c
);
827 pa_signal_new(SIGUSR1
, signal_callback
, c
);
830 pa_signal_new(SIGUSR2
, signal_callback
, c
);
833 pa_signal_new(SIGHUP
, signal_callback
, c
);
837 win32_timer
= pa_mainloop_get_api(mainloop
)->rtclock_time_new(pa_mainloop_get_api(mainloop
), pa_gettimeofday(&win32_tv
), message_cb
, NULL
);
842 if (!conf
->no_cpu_limit
)
843 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop
)) == 0);
845 buf
= pa_strbuf_new();
846 if (conf
->load_default_script_file
) {
849 if ((f
= pa_daemon_conf_open_default_script_file(conf
))) {
850 r
= pa_cli_command_execute_file_stream(c
, f
, buf
, &conf
->fail
);
856 r
= pa_cli_command_execute(c
, conf
->script_commands
, buf
, &conf
->fail
);
858 pa_log_error("%s", s
= pa_strbuf_tostring_free(buf
));
861 /* We completed the initial module loading, so let's disable it
862 * from now on, if requested */
863 c
->disallow_module_loading
= !!conf
->disallow_module_loading
;
865 if (r
< 0 && conf
->fail
) {
866 pa_log(_("Failed to initialize daemon."));
870 if (!c
->modules
|| pa_idxset_size(c
->modules
) == 0) {
871 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
876 if (daemon_pipe
[1] >= 0) {
878 pa_loop_write(daemon_pipe
[1], &ok
, sizeof(ok
), NULL
);
879 pa_close(daemon_pipe
[1]);
885 dbus
= register_dbus(c
);
888 pa_log_info(_("Daemon startup complete."));
891 if (pa_mainloop_run(mainloop
, &retval
) < 0)
894 pa_log_info(_("Daemon shutdown initiated."));
899 pa_dbus_connection_unref(dbus
);
902 if (autospawn_fd
>= 0) {
903 if (autospawn_locked
)
904 pa_autospawn_lock_release();
906 pa_autospawn_lock_done(FALSE
);
911 pa_mainloop_get_api(mainloop
)->time_free(win32_timer
);
916 pa_log_info(_("Daemon terminated."));
919 if (!conf
->no_cpu_limit
)
925 if (daemon_pipe
[1] >= 0)
926 pa_loop_write(daemon_pipe
[1], &retval
, sizeof(retval
), NULL
);
928 pa_close_pipe(daemon_pipe
);
932 pa_mainloop_free(mainloop
);
935 pa_daemon_conf_free(conf
);
938 pa_pid_file_remove();