summaryrefslogtreecommitdiffstats
path: root/src/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon')
-rw-r--r--src/daemon/caps.c35
-rw-r--r--src/daemon/caps.h5
-rw-r--r--src/daemon/cmdline.c12
-rw-r--r--src/daemon/cmdline.h2
-rw-r--r--src/daemon/cpulimit.c2
-rw-r--r--src/daemon/cpulimit.h2
-rw-r--r--src/daemon/daemon-conf.c6
-rw-r--r--src/daemon/daemon-conf.h3
-rw-r--r--src/daemon/daemon.conf.in2
-rwxr-xr-xsrc/daemon/default.pa.in14
-rw-r--r--src/daemon/dumpmodules.c2
-rw-r--r--src/daemon/dumpmodules.h2
-rwxr-xr-xsrc/daemon/esdcompat.in2
-rw-r--r--src/daemon/ltdl-bind-now.c2
-rw-r--r--src/daemon/ltdl-bind-now.h2
-rw-r--r--src/daemon/main.c111
-rw-r--r--src/daemon/org.pulseaudio.policy2
-rw-r--r--src/daemon/polkit.c2
-rw-r--r--src/daemon/polkit.h2
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.