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>
41 #include <liboil/liboil.h>
43 #ifdef HAVE_SYS_IOCTL_H
44 #include <sys/ioctl.h>
60 #include <dbus/dbus.h>
63 #include <pulse/mainloop.h>
64 #include <pulse/mainloop-signal.h>
65 #include <pulse/timeval.h>
66 #include <pulse/xmalloc.h>
67 #include <pulse/i18n.h>
69 #include <pulsecore/lock-autospawn.h>
70 #include <pulsecore/winsock.h>
71 #include <pulsecore/core-error.h>
72 #include <pulsecore/core.h>
73 #include <pulsecore/memblock.h>
74 #include <pulsecore/module.h>
75 #include <pulsecore/cli-command.h>
76 #include <pulsecore/log.h>
77 #include <pulsecore/core-util.h>
78 #include <pulsecore/sioman.h>
79 #include <pulsecore/cli-text.h>
80 #include <pulsecore/pid.h>
81 #include <pulsecore/namereg.h>
82 #include <pulsecore/random.h>
83 #include <pulsecore/rtsig.h>
84 #include <pulsecore/rtclock.h>
85 #include <pulsecore/macro.h>
86 #include <pulsecore/mutex.h>
87 #include <pulsecore/thread.h>
88 #include <pulsecore/once.h>
89 #include <pulsecore/shm.h>
91 #include <pulsecore/dbus-shared.h>
96 #include "daemon-conf.h"
97 #include "dumpmodules.h"
99 #include "ltdl-bind-now.h"
103 /* Only one instance of these variables */
104 int allow_severity
= LOG_INFO
;
105 int deny_severity
= LOG_WARNING
;
109 /* padsp looks for this symbol in the running process and disables
110 * itself if it finds it and it is set to 7 (which is actually a bit
111 * mask). For details see padsp. */
112 int __padsp_disabled__
= 7;
117 static void message_cb(pa_mainloop_api
*a
, pa_time_event
*e
, const struct timeval
*tv
, void *userdata
) {
119 struct timeval tvnext
;
121 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
122 if (msg
.message
== WM_QUIT
)
125 TranslateMessage(&msg
);
126 DispatchMessage(&msg
);
130 pa_timeval_add(pa_gettimeofday(&tvnext
), 100000);
131 a
->time_restart(e
, &tvnext
);
136 static void signal_callback(pa_mainloop_api
*m
, pa_signal_event
*e
, int sig
, void *userdata
) {
137 pa_log_info(_("Got signal %s."), pa_sig2str(sig
));
142 pa_module_load(userdata
, "module-cli", NULL
);
148 pa_module_load(userdata
, "module-cli-protocol-unix", NULL
);
154 char *c
= pa_full_status_string(userdata
);
155 pa_log_notice("%s", c
);
164 pa_log_info(_("Exiting."));
170 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
172 static int change_user(void) {
177 /* This function is called only in system-wide mode. It creates a
178 * runtime dir in /var/run/ with proper UID/GID and drops privs
181 if (!(pw
= getpwnam(PA_SYSTEM_USER
))) {
182 pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER
);
186 if (!(gr
= getgrnam(PA_SYSTEM_GROUP
))) {
187 pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP
);
191 pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."),
192 PA_SYSTEM_USER
, (unsigned long) pw
->pw_uid
,
193 PA_SYSTEM_GROUP
, (unsigned long) gr
->gr_gid
);
195 if (pw
->pw_gid
!= gr
->gr_gid
) {
196 pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER
, PA_SYSTEM_GROUP
);
200 if (strcmp(pw
->pw_dir
, PA_SYSTEM_RUNTIME_PATH
) != 0)
201 pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER
, PA_SYSTEM_RUNTIME_PATH
);
203 if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH
, 0755, pw
->pw_uid
, gr
->gr_gid
) < 0) {
204 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH
, pa_cstrerror(errno
));
208 if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH
, 0700, pw
->pw_uid
, gr
->gr_gid
) < 0) {
209 pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH
, pa_cstrerror(errno
));
213 /* We don't create the config dir here, because we don't need to write to it */
215 if (initgroups(PA_SYSTEM_USER
, gr
->gr_gid
) != 0) {
216 pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno
));
220 #if defined(HAVE_SETRESGID)
221 r
= setresgid(gr
->gr_gid
, gr
->gr_gid
, gr
->gr_gid
);
222 #elif defined(HAVE_SETEGID)
223 if ((r
= setgid(gr
->gr_gid
)) >= 0)
224 r
= setegid(gr
->gr_gid
);
225 #elif defined(HAVE_SETREGID)
226 r
= setregid(gr
->gr_gid
, gr
->gr_gid
);
228 #error "No API to drop privileges"
232 pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno
));
236 #if defined(HAVE_SETRESUID)
237 r
= setresuid(pw
->pw_uid
, pw
->pw_uid
, pw
->pw_uid
);
238 #elif defined(HAVE_SETEUID)
239 if ((r
= setuid(pw
->pw_uid
)) >= 0)
240 r
= seteuid(pw
->pw_uid
);
241 #elif defined(HAVE_SETREUID)
242 r
= setreuid(pw
->pw_uid
, pw
->pw_uid
);
244 #error "No API to drop privileges"
248 pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno
));
252 pa_set_env("USER", PA_SYSTEM_USER
);
253 pa_set_env("USERNAME", PA_SYSTEM_USER
);
254 pa_set_env("LOGNAME", PA_SYSTEM_USER
);
255 pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH
);
257 /* Relevant for pa_runtime_path() */
258 pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH
);
259 pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH
);
260 pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH
);
262 pa_log_info(_("Successfully dropped root privileges."));
267 #else /* HAVE_PWD_H && HAVE_GRP_H */
269 static int change_user(void) {
270 pa_log(_("System wide mode unsupported on this platform."));
274 #endif /* HAVE_PWD_H && HAVE_GRP_H */
276 #ifdef HAVE_SYS_RESOURCE_H
278 static int set_one_rlimit(const pa_rlimit
*r
, int resource
, const char *name
) {
285 rl
.rlim_cur
= rl
.rlim_max
= r
->value
;
287 if (setrlimit(resource
, &rl
) < 0) {
288 pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name
, (unsigned) r
->value
, (unsigned) r
->value
, pa_cstrerror(errno
));
295 static void set_all_rlimits(const pa_daemon_conf
*conf
) {
296 set_one_rlimit(&conf
->rlimit_fsize
, RLIMIT_FSIZE
, "RLIMIT_FSIZE");
297 set_one_rlimit(&conf
->rlimit_data
, RLIMIT_DATA
, "RLIMIT_DATA");
298 set_one_rlimit(&conf
->rlimit_stack
, RLIMIT_STACK
, "RLIMIT_STACK");
299 set_one_rlimit(&conf
->rlimit_core
, RLIMIT_CORE
, "RLIMIT_CORE");
301 set_one_rlimit(&conf
->rlimit_rss
, RLIMIT_RSS
, "RLIMIT_RSS");
304 set_one_rlimit(&conf
->rlimit_nproc
, RLIMIT_NPROC
, "RLIMIT_NPROC");
307 set_one_rlimit(&conf
->rlimit_nofile
, RLIMIT_NOFILE
, "RLIMIT_NOFILE");
309 #ifdef RLIMIT_MEMLOCK
310 set_one_rlimit(&conf
->rlimit_memlock
, RLIMIT_MEMLOCK
, "RLIMIT_MEMLOCK");
313 set_one_rlimit(&conf
->rlimit_as
, RLIMIT_AS
, "RLIMIT_AS");
316 set_one_rlimit(&conf
->rlimit_locks
, RLIMIT_LOCKS
, "RLIMIT_LOCKS");
318 #ifdef RLIMIT_SIGPENDING
319 set_one_rlimit(&conf
->rlimit_sigpending
, RLIMIT_SIGPENDING
, "RLIMIT_SIGPENDING");
321 #ifdef RLIMIT_MSGQUEUE
322 set_one_rlimit(&conf
->rlimit_msgqueue
, RLIMIT_MSGQUEUE
, "RLIMIT_MSGQUEUE");
325 set_one_rlimit(&conf
->rlimit_nice
, RLIMIT_NICE
, "RLIMIT_NICE");
328 set_one_rlimit(&conf
->rlimit_rtprio
, RLIMIT_RTPRIO
, "RLIMIT_RTPRIO");
331 set_one_rlimit(&conf
->rlimit_rttime
, RLIMIT_RTTIME
, "RLIMIT_RTTIME");
337 static void register_org_pulseaudio(pa_core
*c
)
340 pa_dbus_connection
*conn
;
342 dbus_error_init(&error
);
343 if (!(conn
= pa_dbus_bus_get(c
, pa_in_system_mode() ? DBUS_BUS_SYSTEM
: DBUS_BUS_SESSION
, &error
)) || dbus_error_is_set(&error
)) {
344 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
348 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
)
349 pa_log_debug("Got org.pulseaudio.Server!");
350 else if (dbus_error_is_set(&error
))
351 pa_log_warn("Unable to get org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
355 pa_dbus_connection_unref(conn
);
357 dbus_error_free(&error
);
361 int main(int argc
, char *argv
[]) {
363 pa_strbuf
*buf
= NULL
;
364 pa_daemon_conf
*conf
= NULL
;
365 pa_mainloop
*mainloop
= NULL
;
367 int r
= 0, retval
= 1, d
= 0;
368 pa_bool_t suid_root
, real_root
;
369 pa_bool_t valid_pid_file
= FALSE
;
370 gid_t gid
= (gid_t
) -1;
371 pa_bool_t ltdl_init
= FALSE
;
375 int daemon_pipe
[2] = { -1, -1 };
378 pa_time_event
*win32_timer
;
379 struct timeval win32_tv
;
381 int autospawn_fd
= -1;
382 pa_bool_t autospawn_locked
= FALSE
;
384 pa_log_set_ident("pulseaudio");
385 pa_log_set_level(PA_LOG_INFO
);
386 pa_log_set_flags(PA_LOG_COLORS
|PA_LOG_PRINT_FILE
|PA_LOG_PRINT_LEVEL
, PA_LOG_RESET
);
388 #if defined(__linux__) && defined(__OPTIMIZE__)
390 Disable lazy relocations to make usage of external libraries
391 more deterministic for our RT threads. We abuse __OPTIMIZE__ as
392 a check whether we are a debug build or not.
395 if (!getenv("LD_BIND_NOW")) {
398 /* We have to execute ourselves, because the libc caches the
399 * value of $LD_BIND_NOW on initialization. */
401 pa_set_env("LD_BIND_NOW", "1");
403 if ((rp
= pa_readlink("/proc/self/exe")))
404 pa_assert_se(execv(rp
, argv
) == 0);
406 pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
411 real_root
= getuid() == 0;
412 suid_root
= !real_root
&& geteuid() == 0;
419 /* Drop all capabilities except CAP_SYS_NICE */
422 /* Drop privileges, but keep CAP_SYS_NICE */
425 /* After dropping root, the effective set is reset, hence,
426 * let's raise it again */
429 /* When capabilities are not supported we will not be able to
430 * acquire RT sched anymore. But yes, that's the way it is. It
431 * is just too risky tun let PA run as root all the time. */
434 if ((e
= getenv("PULSE_PASSED_FD"))) {
441 pa_close_all(passed_fd
, -1);
446 /* At this point, we are a normal user, possibly with CAP_NICE if
447 * we were started SUID. If we are started as normal root, than we
448 * still are normal root. */
450 setlocale(LC_ALL
, "");
453 conf
= pa_daemon_conf_new();
455 if (pa_daemon_conf_load(conf
, NULL
) < 0)
458 if (pa_daemon_conf_env(conf
) < 0)
461 if (pa_cmdline_parse(conf
, argc
, argv
, &d
) < 0) {
462 pa_log(_("Failed to parse command line."));
466 pa_log_set_level(conf
->log_level
);
467 pa_log_set_target(conf
->auto_log_target
? PA_LOG_STDERR
: conf
->log_target
);
469 pa_log_set_flags(PA_LOG_PRINT_META
, PA_LOG_SET
);
471 pa_log_set_flags(PA_LOG_PRINT_TIME
, PA_LOG_SET
);
472 pa_log_set_show_backtrace(conf
->log_backtrace
);
474 pa_log_debug("Started as real root: %s, suid root: %s", pa_yes_no(real_root
), pa_yes_no(suid_root
));
476 if (!real_root
&& pa_have_caps()) {
477 #ifdef HAVE_SYS_RESOURCE_H
480 pa_bool_t allow_high_priority
= FALSE
, allow_realtime
= FALSE
;
482 /* Let's better not enable high prio or RT by default */
484 if (conf
->high_priority
&& !allow_high_priority
) {
485 if (pa_own_uid_in_group(PA_REALTIME_GROUP
, &gid
) > 0) {
486 pa_log_info(_("We're in the group '%s', allowing high-priority scheduling."), PA_REALTIME_GROUP
);
487 allow_high_priority
= TRUE
;
491 if (conf
->realtime_scheduling
&& !allow_realtime
) {
492 if (pa_own_uid_in_group(PA_REALTIME_GROUP
, &gid
) > 0) {
493 pa_log_info(_("We're in the group '%s', allowing real-time scheduling."), PA_REALTIME_GROUP
);
494 allow_realtime
= TRUE
;
499 if (conf
->high_priority
&& !allow_high_priority
) {
500 if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) {
501 pa_log_info(_("PolicyKit grants us acquire-high-priority privilege."));
502 allow_high_priority
= TRUE
;
504 pa_log_info(_("PolicyKit refuses acquire-high-priority privilege."));
507 if (conf
->realtime_scheduling
&& !allow_realtime
) {
508 if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) {
509 pa_log_info(_("PolicyKit grants us acquire-real-time privilege."));
510 allow_realtime
= TRUE
;
512 pa_log_info(_("PolicyKit refuses acquire-real-time privilege."));
516 if (!allow_high_priority
&& !allow_realtime
) {
518 /* OK, there's no further need to keep CAP_NICE. Hence
519 * let's give it up early */
525 if (getrlimit(RLIMIT_RTPRIO
, &rl
) >= 0)
526 if (rl
.rlim_cur
> 0) {
527 pa_log_info("RLIMIT_RTPRIO is set to %u, allowing real-time scheduling.", (unsigned) rl
.rlim_cur
);
528 allow_realtime
= TRUE
;
532 if (getrlimit(RLIMIT_NICE
, &rl
) >= 0)
533 if (rl
.rlim_cur
> 20 ) {
534 pa_log_info("RLIMIT_NICE is set to %u, allowing high-priority scheduling.", (unsigned) rl
.rlim_cur
);
535 allow_high_priority
= TRUE
;
539 if ((conf
->high_priority
&& !allow_high_priority
) ||
540 (conf
->realtime_scheduling
&& !allow_realtime
))
541 pa_log_info(_("Called SUID root and real-time and/or high-priority scheduling was requested in the configuration. However, we lack the necessary privileges:\n"
542 "We are not in group '%s', PolicyKit refuse to grant us the requested privileges and we have no increase RLIMIT_NICE/RLIMIT_RTPRIO resource limits.\n"
543 "For enabling real-time/high-priority scheduling please acquire the appropriate PolicyKit privileges, or become a member of '%s', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."),
544 PA_REALTIME_GROUP
, PA_REALTIME_GROUP
);
548 conf
->realtime_scheduling
= FALSE
;
550 if (!allow_high_priority
)
551 conf
->high_priority
= FALSE
;
554 #ifdef HAVE_SYS_RESOURCE_H
555 /* Reset resource limits. If we are run as root (for system mode)
556 * this might end up increasing the limits, which is intended
557 * behaviour. For all other cases, i.e. started as normal user, or
558 * SUID root at this point we should have no CAP_SYS_RESOURCE and
559 * increasing the limits thus should fail. Which is, too, intended
562 set_all_rlimits(conf
);
565 if (conf
->high_priority
&& !pa_can_high_priority()) {
566 pa_log_info(_("High-priority scheduling enabled in configuration but not allowed by policy."));
567 conf
->high_priority
= FALSE
;
570 if (conf
->high_priority
&& (conf
->cmd
== PA_CMD_DAEMON
|| conf
->cmd
== PA_CMD_START
))
571 pa_raise_priority(conf
->nice_level
);
573 pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
575 if (!real_root
&& pa_have_caps()) {
578 drop
= (conf
->cmd
!= PA_CMD_DAEMON
&& conf
->cmd
!= PA_CMD_START
) || !conf
->realtime_scheduling
;
583 /* At this point we still have CAP_NICE if we were loaded
584 * SUID root. If possible let's acquire RLIMIT_RTPRIO
585 * instead and give CAP_NICE up. */
587 if (getrlimit(RLIMIT_RTPRIO
, &rl
) >= 0) {
589 if (rl
.rlim_cur
>= 9)
592 rl
.rlim_max
= rl
.rlim_cur
= 9;
594 if (setrlimit(RLIMIT_RTPRIO
, &rl
) >= 0) {
595 pa_log_info(_("Successfully increased RLIMIT_RTPRIO"));
598 pa_log_warn(_("RLIMIT_RTPRIO failed: %s"), pa_cstrerror(errno
));
605 pa_log_info(_("Giving up CAP_NICE"));
611 if (conf
->realtime_scheduling
&& !pa_can_realtime()) {
612 pa_log_info(_("Real-time scheduling enabled in configuration but not allowed by policy."));
613 conf
->realtime_scheduling
= FALSE
;
616 pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
618 LTDL_SET_PRELOADED_SYMBOLS();
622 if (conf
->dl_search_path
)
623 lt_dlsetsearchpath(conf
->dl_search_path
);
628 WSAStartup(MAKEWORD(2, 0), &data
);
635 case PA_CMD_DUMP_MODULES
:
636 pa_dump_modules(conf
, argc
-d
, argv
+d
);
640 case PA_CMD_DUMP_CONF
: {
641 s
= pa_daemon_conf_dump(conf
);
648 case PA_CMD_DUMP_RESAMPLE_METHODS
: {
651 for (i
= 0; i
< PA_RESAMPLER_MAX
; i
++)
652 if (pa_resample_method_supported(i
))
653 printf("%s\n", pa_resample_method_to_string(i
));
660 pa_cmdline_help(argv
[0]);
664 case PA_CMD_VERSION
:
665 printf(PACKAGE_NAME
" "PACKAGE_VERSION
"\n");
672 if (pa_pid_file_check_running(&pid
, "pulseaudio") < 0)
673 pa_log_info(_("Daemon not running"));
675 pa_log_info(_("Daemon running as PID %u"), pid
);
684 if (pa_pid_file_kill(SIGINT
, NULL
, "pulseaudio") < 0)
685 pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno
));
691 case PA_CMD_CLEANUP_SHM
:
693 if (pa_shm_cleanup() >= 0)
699 pa_assert(conf
->cmd
== PA_CMD_DAEMON
|| conf
->cmd
== PA_CMD_START
);
702 if (real_root
&& !conf
->system_instance
)
703 pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
704 else if (!real_root
&& conf
->system_instance
) {
705 pa_log(_("Root privileges required."));
709 if (conf
->cmd
== PA_CMD_START
&& conf
->system_instance
) {
710 pa_log(_("--start not supported for system instances."));
714 if (conf
->system_instance
&& !conf
->disallow_exit
)
715 pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
717 if (conf
->system_instance
&& !conf
->disallow_module_loading
)
718 pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
720 if (conf
->system_instance
&& !conf
->disable_shm
) {
721 pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
722 conf
->disable_shm
= TRUE
;
725 if (conf
->system_instance
&& conf
->exit_idle_time
>= 0) {
726 pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
727 conf
->exit_idle_time
= -1;
730 if (conf
->cmd
== PA_CMD_START
) {
731 /* If we shall start PA only when it is not running yet, we
732 * first take the autospawn lock to make things
735 if ((autospawn_fd
= pa_autospawn_lock_init()) < 0) {
736 pa_log("Failed to initialize autospawn lock");
740 if ((pa_autospawn_lock_acquire(TRUE
) < 0)) {
741 pa_log("Failed to acquire autospawn lock");
745 autospawn_locked
= TRUE
;
748 if (conf
->daemonize
) {
752 if (pa_stdio_acquire() < 0) {
753 pa_log(_("Failed to acquire stdio."));
758 if (pipe(daemon_pipe
) < 0) {
759 pa_log(_("pipe failed: %s"), pa_cstrerror(errno
));
763 if ((child
= fork()) < 0) {
764 pa_log(_("fork() failed: %s"), pa_cstrerror(errno
));
772 pa_assert_se(pa_close(daemon_pipe
[1]) == 0);
775 if ((n
= pa_loop_read(daemon_pipe
[0], &retval
, sizeof(retval
), NULL
)) != sizeof(retval
)) {
778 pa_log(_("read() failed: %s"), pa_cstrerror(errno
));
784 pa_log(_("Daemon startup failed."));
786 pa_log_info(_("Daemon startup successful."));
791 if (autospawn_fd
>= 0) {
792 /* The lock file is unlocked from the parent, so we need
793 * to close it in the child */
795 pa_autospawn_lock_release();
796 pa_autospawn_lock_done(TRUE
);
798 autospawn_locked
= FALSE
;
802 pa_assert_se(pa_close(daemon_pipe
[0]) == 0);
806 if (conf
->auto_log_target
)
807 pa_log_set_target(PA_LOG_SYSLOG
);
821 pa_assert_se(open("/dev/null", O_RDONLY
) == 0);
822 pa_assert_se(open("/dev/null", O_WRONLY
) == 1);
823 pa_assert_se(open("/dev/null", O_WRONLY
) == 2);
829 signal(SIGTTOU
, SIG_IGN
);
832 signal(SIGTTIN
, SIG_IGN
);
835 signal(SIGTSTP
, SIG_IGN
);
839 if ((tty_fd
= open("/dev/tty", O_RDWR
)) >= 0) {
840 ioctl(tty_fd
, TIOCNOTTY
, (char*) 0);
841 pa_assert_se(pa_close(tty_fd
) == 0);
846 pa_set_env("PULSE_INTERNAL", "1");
847 pa_assert_se(chdir("/") == 0);
850 if (conf
->system_instance
)
851 if (change_user() < 0)
854 pa_set_env("PULSE_SYSTEM", conf
->system_instance
? "1" : "0");
856 pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION
);
857 pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST
);
858 pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS
);
860 s
= pa_uname_string();
861 pa_log_debug(_("Running on host: %s"), s
);
864 pa_log_debug(_("Found %u CPUs."), pa_ncpus());
866 pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE
);
868 #ifdef HAVE_VALGRIND_MEMCHECK_H
869 pa_log_debug(_("Compiled with Valgrind support: yes"));
871 pa_log_debug(_("Compiled with Valgrind support: no"));
874 pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
877 pa_log_debug(_("Optimized build: yes"));
879 pa_log_debug(_("Optimized build: no"));
883 pa_log_debug(_("NDEBUG defined, all asserts disabled."));
884 #elif defined(FASTPATH)
885 pa_log_debug(_("FASTPATH defined, only fast path asserts disabled."));
887 pa_log_debug(_("All asserts enabled."));
890 if (!(s
= pa_machine_id())) {
891 pa_log(_("Failed to get machine ID"));
894 pa_log_info(_("Machine ID is %s."), s
);
897 if (!(s
= pa_get_runtime_dir()))
899 pa_log_info(_("Using runtime directory %s."), s
);
902 if (!(s
= pa_get_state_dir()))
904 pa_log_info(_("Using state directory %s."), s
);
907 pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
909 if (conf
->use_pid_file
) {
912 if ((z
= pa_pid_file_create("pulseaudio")) != 0) {
914 if (conf
->cmd
== PA_CMD_START
&& z
> 0) {
915 /* If we are already running and with are run in
916 * --start mode, then let's return this as success. */
922 pa_log(_("pa_pid_file_create() failed."));
926 valid_pid_file
= TRUE
;
930 signal(SIGPIPE
, SIG_IGN
);
933 if (pa_rtclock_hrtimer())
934 pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
936 pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
938 pa_rtclock_hrtimer_enable();
941 /* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */
942 pa_rtsig_configure(SIGRTMIN
, SIGRTMAX
-1);
945 pa_assert_se(mainloop
= pa_mainloop_new());
947 if (!(c
= pa_core_new(pa_mainloop_get_api(mainloop
), !conf
->disable_shm
, conf
->shm_size
))) {
948 pa_log(_("pa_core_new() failed."));
952 c
->default_sample_spec
= conf
->default_sample_spec
;
953 c
->default_channel_map
= conf
->default_channel_map
;
954 c
->default_n_fragments
= conf
->default_n_fragments
;
955 c
->default_fragment_size_msec
= conf
->default_fragment_size_msec
;
956 c
->exit_idle_time
= conf
->exit_idle_time
;
957 c
->scache_idle_time
= conf
->scache_idle_time
;
958 c
->resample_method
= conf
->resample_method
;
959 c
->realtime_priority
= conf
->realtime_priority
;
960 c
->realtime_scheduling
= !!conf
->realtime_scheduling
;
961 c
->disable_remixing
= !!conf
->disable_remixing
;
962 c
->disable_lfe_remixing
= !!conf
->disable_lfe_remixing
;
963 c
->running_as_daemon
= !!conf
->daemonize
;
964 c
->disallow_exit
= conf
->disallow_exit
;
965 c
->flat_volumes
= conf
->flat_volumes
;
967 pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop
)) == 0);
968 pa_signal_new(SIGINT
, signal_callback
, c
);
969 pa_signal_new(SIGTERM
, signal_callback
, c
);
971 pa_signal_new(SIGUSR1
, signal_callback
, c
);
974 pa_signal_new(SIGUSR2
, signal_callback
, c
);
977 pa_signal_new(SIGHUP
, signal_callback
, c
);
981 win32_timer
= pa_mainloop_get_api(mainloop
)->time_new(pa_mainloop_get_api(mainloop
), pa_gettimeofday(&win32_tv
), message_cb
, NULL
);
986 if (!conf
->no_cpu_limit
)
987 pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop
)) == 0);
989 buf
= pa_strbuf_new();
990 if (conf
->load_default_script_file
) {
993 if ((f
= pa_daemon_conf_open_default_script_file(conf
))) {
994 r
= pa_cli_command_execute_file_stream(c
, f
, buf
, &conf
->fail
);
1000 r
= pa_cli_command_execute(c
, conf
->script_commands
, buf
, &conf
->fail
);
1002 pa_log_error("%s", s
= pa_strbuf_tostring_free(buf
));
1005 /* We completed the initial module loading, so let's disable it
1006 * from now on, if requested */
1007 c
->disallow_module_loading
= !!conf
->disallow_module_loading
;
1009 if (r
< 0 && conf
->fail
) {
1010 pa_log(_("Failed to initialize daemon."));
1014 if (!c
->modules
|| pa_idxset_size(c
->modules
) == 0) {
1015 pa_log(_("Daemon startup without any loaded modules, refusing to work."));
1020 if (daemon_pipe
[1] >= 0) {
1022 pa_loop_write(daemon_pipe
[1], &ok
, sizeof(ok
), NULL
);
1023 pa_close(daemon_pipe
[1]);
1024 daemon_pipe
[1] = -1;
1029 register_org_pulseaudio(c
);
1032 pa_log_info(_("Daemon startup complete."));
1035 if (pa_mainloop_run(mainloop
, &retval
) < 0)
1038 pa_log_info(_("Daemon shutdown initiated."));
1042 if (autospawn_fd
>= 0) {
1043 if (autospawn_locked
)
1044 pa_autospawn_lock_release();
1046 pa_autospawn_lock_done(FALSE
);
1051 pa_mainloop_get_api(mainloop
)->time_free(win32_timer
);
1056 pa_log_info(_("Daemon terminated."));
1059 if (!conf
->no_cpu_limit
)
1060 pa_cpu_limit_done();
1065 if (daemon_pipe
[1] >= 0)
1066 pa_loop_write(daemon_pipe
[1], &retval
, sizeof(retval
), NULL
);
1068 pa_close_pipe(daemon_pipe
);
1072 pa_mainloop_free(mainloop
);
1075 pa_daemon_conf_free(conf
);
1078 pa_pid_file_remove();