diff options
Diffstat (limited to 'src/daemon')
-rw-r--r-- | src/daemon/caps.c | 35 | ||||
-rw-r--r-- | src/daemon/caps.h | 5 | ||||
-rw-r--r-- | src/daemon/cmdline.c | 12 | ||||
-rw-r--r-- | src/daemon/cmdline.h | 2 | ||||
-rw-r--r-- | src/daemon/cpulimit.c | 2 | ||||
-rw-r--r-- | src/daemon/cpulimit.h | 2 | ||||
-rw-r--r-- | src/daemon/daemon-conf.c | 6 | ||||
-rw-r--r-- | src/daemon/daemon-conf.h | 3 | ||||
-rw-r--r-- | src/daemon/daemon.conf.in | 2 | ||||
-rwxr-xr-x | src/daemon/default.pa.in | 14 | ||||
-rw-r--r-- | src/daemon/dumpmodules.c | 2 | ||||
-rw-r--r-- | src/daemon/dumpmodules.h | 2 | ||||
-rwxr-xr-x | src/daemon/esdcompat.in | 2 | ||||
-rw-r--r-- | src/daemon/ltdl-bind-now.c | 2 | ||||
-rw-r--r-- | src/daemon/ltdl-bind-now.h | 2 | ||||
-rw-r--r-- | src/daemon/main.c | 111 | ||||
-rw-r--r-- | src/daemon/org.pulseaudio.policy | 2 | ||||
-rw-r--r-- | src/daemon/polkit.c | 2 | ||||
-rw-r--r-- | src/daemon/polkit.h | 2 |
19 files changed, 142 insertions, 68 deletions
diff --git a/src/daemon/caps.c b/src/daemon/caps.c index e936d6bb..ae07119c 100644 --- a/src/daemon/caps.c +++ b/src/daemon/caps.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -93,13 +91,18 @@ void pa_limit_caps(void) { pa_assert_se(cap_clear(caps) == 0); pa_assert_se(cap_set_flag(caps, CAP_EFFECTIVE, 1, &nice_cap, CAP_SET) == 0); pa_assert_se(cap_set_flag(caps, CAP_PERMITTED, 1, &nice_cap, CAP_SET) == 0); - pa_assert_se(cap_set_proc(caps) == 0); - - pa_assert_se(prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == 0); - pa_log_info("Dropped capabilities successfully."); + if (cap_set_proc(caps) < 0) + /* Hmm, so we couldn't limit our caps, which probably means we + * hadn't any in the first place, so let's just make sure of + * that */ + pa_drop_caps(); + else + pa_log_info("Limited capabilities successfully to CAP_SYS_NICE."); pa_assert_se(cap_free(caps) == 0); + + pa_assert_se(prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == 0); } /* Drop all capabilities, effectively becoming a normal user */ @@ -112,17 +115,33 @@ void pa_drop_caps(void) { pa_assert_se(cap_clear(caps) == 0); pa_assert_se(cap_set_proc(caps) == 0); pa_assert_se(cap_free(caps) == 0); + + pa_assert_se(!pa_have_caps()); +} + +pa_bool_t pa_have_caps(void) { + cap_t caps; + cap_flag_value_t flag = CAP_CLEAR; + + pa_assert_se(caps = cap_get_proc()); + pa_assert_se(cap_get_flag(caps, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0); + pa_assert_se(cap_free(caps) == 0); + + return flag == CAP_SET; } #else /* NOOPs in case capabilities are not available. */ -int pa_limit_caps(void) { - return 0; +void pa_limit_caps(void) { } void pa_drop_caps(void) { pa_drop_root(); } +pa_bool_t pa_have_caps(void) { + return FALSE; +} + #endif diff --git a/src/daemon/caps.h b/src/daemon/caps.h index 5b21f12e..176aa90e 100644 --- a/src/daemon/caps.h +++ b/src/daemon/caps.h @@ -1,8 +1,6 @@ #ifndef foocapshfoo #define foocapshfoo -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -24,8 +22,11 @@ USA. ***/ +#include <pulsecore/macro.h> + void pa_drop_root(void); void pa_drop_caps(void); void pa_limit_caps(void); +pa_bool_t pa_have_caps(void); #endif diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index 97c75f37..4b2466ce 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -66,7 +64,8 @@ enum { ARG_DISABLE_SHM, ARG_DUMP_RESAMPLE_METHODS, ARG_SYSTEM, - ARG_CLEANUP_SHM + ARG_CLEANUP_SHM, + ARG_START }; /* Tabel for getopt_long() */ @@ -91,6 +90,7 @@ static const struct option long_options[] = { {"dl-search-path", 1, 0, ARG_DL_SEARCH_PATH}, {"resample-method", 1, 0, ARG_RESAMPLE_METHOD}, {"kill", 0, 0, ARG_KILL}, + {"start", 0, 0, ARG_START}, {"use-pid-file", 2, 0, ARG_USE_PID_FILE}, {"check", 0, 0, ARG_CHECK}, {"system", 2, 0, ARG_SYSTEM}, @@ -119,6 +119,7 @@ void pa_cmdline_help(const char *argv0) { " --dump-modules Dump list of available modules\n" " --dump-resample-methods Dump available resample methods\n" " --cleanup-shm Cleanup stale shared memory segments\n" + " --start Start the daemon if it is not running\n" " -k --kill Kill a running daemon\n" " --check Check for a running daemon\n\n" @@ -207,6 +208,11 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d conf->cmd = PA_CMD_KILL; break; + case ARG_START: + conf->cmd = PA_CMD_START; + conf->daemonize = TRUE; + break; + case ARG_CHECK: conf->cmd = PA_CMD_CHECK; break; diff --git a/src/daemon/cmdline.h b/src/daemon/cmdline.h index 18418894..fd72a6d3 100644 --- a/src/daemon/cmdline.h +++ b/src/daemon/cmdline.h @@ -1,8 +1,6 @@ #ifndef foocmdlinehfoo #define foocmdlinehfoo -/* $Id$ */ - /*** This file is part of PulseAudio. diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index 579b91e3..42a71f7e 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. diff --git a/src/daemon/cpulimit.h b/src/daemon/cpulimit.h index 271109b4..cb9a123d 100644 --- a/src/daemon/cpulimit.h +++ b/src/daemon/cpulimit.h @@ -1,8 +1,6 @@ #ifndef foocpulimithfoo #define foocpulimithfoo -/* $Id$ */ - /*** This file is part of PulseAudio. diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index f9ad7ec0..9ac40901 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -295,7 +293,7 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *lv pa_assert(rvalue); pa_assert(data); - if (pa_atoi(rvalue, &r) < 0 || r > PA_RATE_MAX || r <= 0) { + if (pa_atoi(rvalue, &r) < 0 || r > (int32_t) PA_RATE_MAX || r <= 0) { pa_log("[%s:%u] Invalid sample rate '%s'.", filename, line, rvalue); return -1; } @@ -313,7 +311,7 @@ static int parse_sample_channels(const char *filename, unsigned line, const char pa_assert(rvalue); pa_assert(data); - if (pa_atoi(rvalue, &n) < 0 || n > PA_CHANNELS_MAX || n <= 0) { + if (pa_atoi(rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) { pa_log("[%s:%u] Invalid sample channels '%s'.", filename, line, rvalue); return -1; } diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index 03a75661..be2fe1ab 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -1,8 +1,6 @@ #ifndef foodaemonconfhfoo #define foodaemonconfhfoo -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -37,6 +35,7 @@ /* The actual command to execute */ typedef enum pa_daemon_conf_cmd { PA_CMD_DAEMON, /* the default */ + PA_CMD_START, PA_CMD_HELP, PA_CMD_VERSION, PA_CMD_DUMP_CONF, diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in index fd35c0f6..dfabcfb2 100644 --- a/src/daemon/daemon.conf.in +++ b/src/daemon/daemon.conf.in @@ -1,5 +1,3 @@ -# $Id$ -# # This file is part of PulseAudio. # # PulseAudio is free software; you can redistribute it and/or modify diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index 064a6cc9..aad9f5d6 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -74,16 +74,26 @@ load-module module-default-device-restore ### connected to dies, similar for sources load-module module-rescue-streams +### Make sure we always have a sink around, even if it is a null sink. +load-module module-always-sink + ### Automatically suspend sinks/sources that become idle for too long load-module module-suspend-on-idle ### Load X11 bell module -#load-module module-x11-bell sample=x11-bell +#load-module module-x11-bell sample=bell-windowing-system ### Register ourselves in the X11 session manager # Deactivated by default, to avoid deadlock when PA is started as esd from gnome-session # Instead we load this via /etc/xdg/autostart/ and "pactl load-module" now -# load-module module-x11-xsmp +#load-module module-x11-xsmp + +### If autoexit on idle is enabled we want to make sure we only quit +### when no local session needs us anymore. +load-module module-console-kit + +### Enable positioned event sounds +load-module module-position-event-sounds ### Load additional modules from GConf settings. This can be configured with the paprefs tool. ### Please keep in mind that the modules configured by paprefs might conflict with manually diff --git a/src/daemon/dumpmodules.c b/src/daemon/dumpmodules.c index 68236c70..cd6866aa 100644 --- a/src/daemon/dumpmodules.c +++ b/src/daemon/dumpmodules.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. diff --git a/src/daemon/dumpmodules.h b/src/daemon/dumpmodules.h index ab2ddb64..c49a5eda 100644 --- a/src/daemon/dumpmodules.h +++ b/src/daemon/dumpmodules.h @@ -1,8 +1,6 @@ #ifndef foodumpmoduleshfoo #define foodumpmoduleshfoo -/* $Id*/ - /*** This file is part of PulseAudio. diff --git a/src/daemon/esdcompat.in b/src/daemon/esdcompat.in index 942389d2..66501803 100755 --- a/src/daemon/esdcompat.in +++ b/src/daemon/esdcompat.in @@ -1,7 +1,5 @@ #!/bin/sh -# $Id$ -# # This file is part of PulseAudio. # # PulseAudio is free software; you can redistribute it and/or modify diff --git a/src/daemon/ltdl-bind-now.c b/src/daemon/ltdl-bind-now.c index 6915fe0c..b1770674 100644 --- a/src/daemon/ltdl-bind-now.c +++ b/src/daemon/ltdl-bind-now.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. diff --git a/src/daemon/ltdl-bind-now.h b/src/daemon/ltdl-bind-now.h index e19c7bc1..f95d13b4 100644 --- a/src/daemon/ltdl-bind-now.h +++ b/src/daemon/ltdl-bind-now.h @@ -1,8 +1,6 @@ #ifndef foopulsecoreltdlbindnowhfoo #define foopulsecoreltdlbindnowhfoo -/* $Id$ */ - /*** This file is part of PulseAudio. diff --git a/src/daemon/main.c b/src/daemon/main.c index 789d104b..14594416 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -96,6 +94,8 @@ #include "ltdl-bind-now.h" #include "polkit.h" +#define AUTOSPAWN_LOCK "autospawn.lock" + #ifdef HAVE_LIBWRAP /* Only one instance of these variables */ int allow_severity = LOG_INFO; @@ -202,6 +202,13 @@ static int change_user(void) { return -1; } + if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) { + pa_log("Failed to create '%s': %s", PA_SYSTEM_STATE_PATH, pa_cstrerror(errno)); + return -1; + } + + /* We don't create the config dir here, because we don't need to write to it */ + if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) { pa_log("Failed to change group list: %s", pa_cstrerror(errno)); return -1; @@ -246,7 +253,8 @@ static int change_user(void) { /* Relevant for pa_runtime_path() */ pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH); - pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_RUNTIME_PATH); + pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH); + pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH); pa_log_info("Successfully dropped root privileges."); @@ -336,6 +344,8 @@ int main(int argc, char *argv[]) { pa_time_event *win32_timer; struct timeval win32_tv; #endif + char *lf = NULL; + int autospawn_lock_fd = -1; #if defined(__linux__) && defined(__OPTIMIZE__) /* @@ -364,7 +374,7 @@ int main(int argc, char *argv[]) { suid_root = FALSE; #endif - if (suid_root) { + if (!real_root) { /* Drop all capabilities except CAP_SYS_NICE */ pa_limit_caps(); @@ -416,20 +426,26 @@ int main(int argc, char *argv[]) { pa_log_set_maximal_level(conf->log_level); pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target, NULL); - if (suid_root) { - pa_bool_t allow_realtime, allow_high_priority; + pa_log_debug("Started as real root: %s, suid root: %s", pa_yes_no(real_root), pa_yes_no(suid_root)); + + if (!real_root && pa_have_caps()) { + pa_bool_t allow_high_priority = FALSE, allow_realtime = FALSE; - /* Ok, we're suid root, so let's better not enable high prio - * or RT by default */ + /* Let's better not enable high prio or RT by default */ - allow_high_priority = allow_realtime = FALSE; + if (conf->high_priority && !allow_high_priority) { + if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) { + pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing high-priority scheduling."); + allow_high_priority = TRUE; + } + } - if (conf->high_priority || conf->realtime_scheduling) + if (conf->realtime_scheduling && !allow_realtime) { if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) { - pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing real-time and high-priority scheduling."); - allow_realtime = conf->realtime_scheduling; - allow_high_priority = conf->high_priority; + pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing real-time scheduling."); + allow_realtime = TRUE; } + } #ifdef HAVE_POLKIT if (conf->high_priority && !allow_high_priority) { @@ -455,7 +471,6 @@ int main(int argc, char *argv[]) { * let's give it up early */ pa_drop_caps(); - suid_root = FALSE; if (conf->high_priority || conf->realtime_scheduling) pa_log_notice("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n" @@ -478,13 +493,13 @@ int main(int argc, char *argv[]) { if (conf->high_priority && !pa_can_high_priority()) pa_log_warn("High-priority scheduling enabled in configuration but not allowed by policy."); - if (conf->high_priority && conf->cmd == PA_CMD_DAEMON) + if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START)) pa_raise_priority(conf->nice_level); - if (suid_root) { + if (pa_have_caps()) { pa_bool_t drop; - drop = conf->cmd != PA_CMD_DAEMON || !conf->realtime_scheduling; + drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling; #ifdef RLIMIT_RTPRIO if (!drop) { @@ -520,6 +535,8 @@ int main(int argc, char *argv[]) { if (conf->realtime_scheduling && !pa_can_realtime()) pa_log_warn("Real-time scheduling enabled in configuration but not allowed by policy."); + pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority())); + LTDL_SET_PRELOADED_SYMBOLS(); pa_ltdl_init(); ltdl_init = TRUE; @@ -600,7 +617,7 @@ int main(int argc, char *argv[]) { goto finish; default: - pa_assert(conf->cmd == PA_CMD_DAEMON); + pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START); } if (real_root && !conf->system_instance) @@ -610,6 +627,15 @@ int main(int argc, char *argv[]) { goto finish; } + if (conf->cmd == PA_CMD_START) { + /* If we shall start PA only when it is not running yet, we + * first take the autospawn lock to make things + * synchronous. */ + + lf = pa_runtime_path(AUTOSPAWN_LOCK); + autospawn_lock_fd = pa_lock_lockfile(lf); + } + if (conf->daemonize) { pid_t child; int tty_fd; @@ -653,6 +679,14 @@ int main(int argc, char *argv[]) { goto finish; } + if (autospawn_lock_fd >= 0) { + /* The lock file is unlocked from the parent, so we need + * to close it in the child */ + + pa_close(autospawn_lock_fd); + autospawn_lock_fd = -1; + } + pa_assert_se(pa_close(daemon_pipe[0]) == 0); daemon_pipe[0] = -1; #endif @@ -705,13 +739,35 @@ int main(int argc, char *argv[]) { if (change_user() < 0) goto finish; + pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0"); + pa_log_info("This is PulseAudio " PACKAGE_VERSION); pa_log_info("Page size is %lu bytes", (unsigned long) PA_PAGE_SIZE); - pa_log_info("Using runtime directory %s.", s = pa_get_runtime_dir()); + if (!(s = pa_get_runtime_dir())) + goto finish; + pa_log_info("Using runtime directory %s.", s); pa_xfree(s); + if (!(s = pa_get_state_dir())) + pa_log_info("Using state directory %s.", s); + pa_xfree(s); + + pa_log_info("Running in system mode: %s", pa_yes_no(pa_in_system_mode())); if (conf->use_pid_file) { - if (pa_pid_file_create() < 0) { + int z; + + if ((z = pa_pid_file_create("pulseaudio")) != 0) { + + if (conf->cmd == PA_CMD_START && z > 0) { + /* If we are already running and with are run in + * --start mode, then let's return this as success. */ + + pa_log_info("z=%i rock!", z); + + retval = 0; + goto finish; + } + pa_log("pa_pid_file_create() failed."); goto finish; } @@ -740,7 +796,6 @@ int main(int argc, char *argv[]) { goto finish; } - c->is_system_instance = !!conf->system_instance; c->default_sample_spec = conf->default_sample_spec; c->default_n_fragments = conf->default_n_fragments; c->default_fragment_size_msec = conf->default_fragment_size_msec; @@ -810,11 +865,12 @@ int main(int argc, char *argv[]) { goto finish; } - #ifdef HAVE_FORK - if (conf->daemonize) { + if (daemon_pipe[1] >= 0) { int ok = 0; pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL); + pa_close(daemon_pipe[1]); + daemon_pipe[1] = -1; } #endif @@ -828,6 +884,12 @@ int main(int argc, char *argv[]) { finish: + if (autospawn_lock_fd >= 0) + pa_unlock_lockfile(lf, autospawn_lock_fd); + + if (lf) + pa_xfree(lf); + #ifdef OS_IS_WIN32 if (win32_timer) pa_mainloop_get_api(mainloop)->time_free(win32_timer); @@ -844,6 +906,9 @@ finish: pa_signal_done(); #ifdef HAVE_FORK + if (daemon_pipe[1] >= 0) + pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL); + pa_close_pipe(daemon_pipe); #endif diff --git a/src/daemon/org.pulseaudio.policy b/src/daemon/org.pulseaudio.policy index 507a2cb1..6cdeec68 100644 --- a/src/daemon/org.pulseaudio.policy +++ b/src/daemon/org.pulseaudio.policy @@ -3,8 +3,6 @@ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> -<!-- $Id$ --> - <!-- This file is part of PulseAudio. diff --git a/src/daemon/polkit.c b/src/daemon/polkit.c index ce7c83e0..256e3199 100644 --- a/src/daemon/polkit.c +++ b/src/daemon/polkit.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. diff --git a/src/daemon/polkit.h b/src/daemon/polkit.h index cbcf6a6a..0d65ec52 100644 --- a/src/daemon/polkit.h +++ b/src/daemon/polkit.h @@ -1,8 +1,6 @@ #ifndef foopolkithfoo #define foopolkithfoo -/* $Id$ */ - /*** This file is part of PulseAudio. |