merge 'lennart' branch back into trunk.

git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1971 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
Lennart Poettering 2007-10-28 19:13:50 +00:00
parent 6687dd0131
commit a67c21f093
294 changed files with 79057 additions and 11614 deletions

View file

@ -26,11 +26,11 @@
#include <config.h>
#endif
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <pulsecore/macro.h>
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
@ -60,7 +60,7 @@ void pa_drop_root(void) {
if (uid == 0 || geteuid() != 0)
return;
pa_log_info("dropping root rights.");
pa_log_info("Dropping root priviliges.");
#if defined(HAVE_SETRESUID)
setresuid(uid, uid, uid);
@ -88,8 +88,9 @@ int pa_limit_caps(void) {
cap_value_t nice_cap = CAP_SYS_NICE;
caps = cap_init();
assert(caps);
pa_assert(caps);
cap_clear(caps);
cap_set_flag(caps, CAP_EFFECTIVE, 1, &nice_cap, CAP_SET);
cap_set_flag(caps, CAP_PERMITTED, 1, &nice_cap, CAP_SET);
if (cap_set_proc(caps) < 0)
@ -98,7 +99,7 @@ int pa_limit_caps(void) {
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0)
goto fail;
pa_log_info("dropped capabilities successfully.");
pa_log_info("Dropped capabilities successfully.");
r = 1;
@ -114,14 +115,14 @@ int pa_drop_caps(void) {
int r = -1;
caps = cap_init();
assert(caps);
pa_assert(caps);
cap_clear(caps);
prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
if (cap_set_proc(caps) < 0) {
pa_log("failed to drop capabilities: %s", pa_cstrerror(errno));
pa_log("Failed to drop capabilities: %s", pa_cstrerror(errno));
goto fail;
}

View file

@ -26,7 +26,6 @@
#endif
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
@ -36,6 +35,7 @@
#include <pulsecore/core-util.h>
#include <pulsecore/strbuf.h>
#include <pulsecore/macro.h>
#include "cmdline.h"
@ -63,7 +63,9 @@ enum {
ARG_CHECK,
ARG_NO_CPU_LIMIT,
ARG_DISABLE_SHM,
ARG_SYSTEM
ARG_DUMP_RESAMPLE_METHODS,
ARG_SYSTEM,
ARG_CLEANUP_SHM
};
/* Tabel for getopt_long() */
@ -92,12 +94,16 @@ static struct option long_options[] = {
{"system", 2, 0, ARG_SYSTEM},
{"no-cpu-limit", 2, 0, ARG_NO_CPU_LIMIT},
{"disable-shm", 2, 0, ARG_DISABLE_SHM},
{"dump-resample-methods", 2, 0, ARG_DUMP_RESAMPLE_METHODS},
{"cleanup-shm", 2, 0, ARG_CLEANUP_SHM},
{NULL, 0, 0, 0}
};
void pa_cmdline_help(const char *argv0) {
const char *e;
pa_assert(argv0);
if ((e = strrchr(argv0, '/')))
e++;
else
@ -109,6 +115,8 @@ void pa_cmdline_help(const char *argv0) {
" --version Show version\n"
" --dump-conf Dump default configuration\n"
" --dump-modules Dump list of available modules\n"
" --dump-resample-methods Dump available resample methods\n"
" --cleanup-shm Cleanup stale shared memory segments\n"
" -k --kill Kill a running daemon\n"
" --check Check for a running daemon\n\n"
@ -131,9 +139,8 @@ void pa_cmdline_help(const char *argv0) {
" -p, --dl-search-path=PATH Set the search path for dynamic shared\n"
" objects (plugins)\n"
" --resample-method=[METHOD] Use the specified resampling method\n"
" (one of src-sinc-medium-quality,\n"
" src-sinc-best-quality,src-sinc-fastest\n"
" src-zero-order-hold,src-linear,trivial)\n"
" (See --dump-resample-methods for\n"
" possible values)\n"
" --use-pid-file[=BOOL] Create a PID file\n"
" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n"
" platforms that support it.\n"
@ -152,7 +159,10 @@ void pa_cmdline_help(const char *argv0) {
int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d) {
pa_strbuf *buf = NULL;
int c;
assert(conf && argc && argv);
pa_assert(conf);
pa_assert(argc > 0);
pa_assert(argv);
buf = pa_strbuf_new();
@ -178,6 +188,14 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
conf->cmd = PA_CMD_DUMP_MODULES;
break;
case ARG_DUMP_RESAMPLE_METHODS:
conf->cmd = PA_CMD_DUMP_RESAMPLE_METHODS;
break;
case ARG_CLEANUP_SHM:
conf->cmd = PA_CMD_CLEANUP_SHM;
break;
case 'k':
case ARG_KILL:
conf->cmd = PA_CMD_KILL;
@ -193,9 +211,12 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
break;
case ARG_FILE:
case 'F':
pa_strbuf_printf(buf, ".include %s\n", optarg);
case 'F': {
char *p;
pa_strbuf_printf(buf, ".include %s\n", p = pa_make_path_absolute(optarg));
pa_xfree(p);
break;
}
case 'C':
pa_strbuf_puts(buf, "load-module module-cli exit_on_eof=1\n");

View file

@ -30,6 +30,7 @@
#include <pulsecore/core-util.h>
#include <pulsecore/core-error.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include "cpulimit.h"
@ -38,7 +39,6 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
@ -92,23 +92,18 @@ static enum {
/* Reset the SIGXCPU timer to the next t seconds */
static void reset_cpu_time(int t) {
int r;
long n;
struct rlimit rl;
struct rusage ru;
/* Get the current CPU time of the current process */
r = getrusage(RUSAGE_SELF, &ru);
assert(r >= 0);
pa_assert_se(getrusage(RUSAGE_SELF, &ru) >= 0);
n = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec + t;
r = getrlimit(RLIMIT_CPU, &rl);
assert(r >= 0);
pa_assert_se(getrlimit(RLIMIT_CPU, &rl) >= 0);
rl.rlim_cur = n;
r = setrlimit(RLIMIT_CPU, &rl);
assert(r >= 0);
pa_assert_se(setrlimit(RLIMIT_CPU, &rl) >= 0);
}
/* A simple, thread-safe puts() work-alike */
@ -118,7 +113,7 @@ static void write_err(const char *p) {
/* The signal handler, called on every SIGXCPU */
static void signal_handler(int sig) {
assert(sig == SIGXCPU);
pa_assert(sig == SIGXCPU);
if (phase == PHASE_IDLE) {
time_t now;
@ -130,7 +125,7 @@ static void signal_handler(int sig) {
time(&now);
#ifdef PRINT_CPU_LOAD
snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", (double)CPUTIME_INTERVAL_SOFT/(now-last_time)*100);
pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", (double)CPUTIME_INTERVAL_SOFT/(now-last_time)*100);
write_err(t);
#endif
@ -160,7 +155,12 @@ static void signal_handler(int sig) {
/* Callback for IO events on the FIFO */
static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags_t f, void *userdata) {
char c;
assert(m && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == the_pipe[0]);
pa_assert(m);
pa_assert(e);
pa_assert(f == PA_IO_EVENT_INPUT);
pa_assert(e == io_event);
pa_assert(fd == the_pipe[0]);
pa_read(the_pipe[0], &c, sizeof(c), NULL);
m->quit(m, 1); /* Quit the main loop */
}
@ -168,7 +168,13 @@ static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags
/* Initializes CPU load limiter */
int pa_cpu_limit_init(pa_mainloop_api *m) {
struct sigaction sa;
assert(m && !api && !io_event && the_pipe[0] == -1 && the_pipe[1] == -1 && !installed);
pa_assert(m);
pa_assert(!api);
pa_assert(!io_event);
pa_assert(the_pipe[0] == -1);
pa_assert(the_pipe[1] == -1);
pa_assert(!installed);
time(&last_time);
@ -178,10 +184,10 @@ int pa_cpu_limit_init(pa_mainloop_api *m) {
return -1;
}
pa_make_nonblock_fd(the_pipe[0]);
pa_make_nonblock_fd(the_pipe[1]);
pa_fd_set_cloexec(the_pipe[0], 1);
pa_fd_set_cloexec(the_pipe[1], 1);
pa_make_fd_nonblock(the_pipe[0]);
pa_make_fd_nonblock(the_pipe[1]);
pa_make_fd_cloexec(the_pipe[0]);
pa_make_fd_cloexec(the_pipe[1]);
api = m;
io_event = api->io_new(m, the_pipe[0], PA_IO_EVENT_INPUT, callback, NULL);
@ -208,24 +214,18 @@ int pa_cpu_limit_init(pa_mainloop_api *m) {
/* Shutdown CPU load limiter */
void pa_cpu_limit_done(void) {
int r;
if (io_event) {
assert(api);
pa_assert(api);
api->io_free(io_event);
io_event = NULL;
api = NULL;
}
if (the_pipe[0] >= 0)
close(the_pipe[0]);
if (the_pipe[1] >= 0)
close(the_pipe[1]);
the_pipe[0] = the_pipe[1] = -1;
pa_close_pipe(the_pipe);
if (installed) {
r = sigaction(SIGXCPU, &sigaction_prev, NULL);
assert(r >= 0);
pa_assert_se(sigaction(SIGXCPU, &sigaction_prev, NULL) >= 0);
installed = 0;
}
}

View file

@ -29,7 +29,6 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <pulse/xmalloc.h>
@ -39,19 +38,14 @@
#include <pulsecore/strbuf.h>
#include <pulsecore/conf-parser.h>
#include <pulsecore/resampler.h>
#include <pulsecore/macro.h>
#include "daemon-conf.h"
#ifndef OS_IS_WIN32
# define PATH_SEP "/"
#else
# define PATH_SEP "\\"
#endif
#define DEFAULT_SCRIPT_FILE PA_DEFAULT_CONFIG_DIR PATH_SEP "default.pa"
#define DEFAULT_SCRIPT_FILE_USER PATH_SEP "default.pa"
#define DEFAULT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PATH_SEP "daemon.conf"
#define DEFAULT_CONFIG_FILE_USER PATH_SEP "daemon.conf"
#define DEFAULT_SCRIPT_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "default.pa"
#define DEFAULT_SCRIPT_FILE_USER PA_PATH_SEP "default.pa"
#define DEFAULT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "daemon.conf"
#define DEFAULT_CONFIG_FILE_USER PA_PATH_SEP "daemon.conf"
#define ENV_SCRIPT_FILE "PULSE_SCRIPT"
#define ENV_CONFIG_FILE "PULSE_CONFIG"
@ -72,31 +66,34 @@ static const pa_daemon_conf default_conf = {
.default_script_file = NULL,
.log_target = PA_LOG_SYSLOG,
.log_level = PA_LOG_NOTICE,
.resample_method = PA_RESAMPLER_SRC_SINC_FASTEST,
.resample_method = PA_RESAMPLER_AUTO,
.config_file = NULL,
.use_pid_file = 1,
.system_instance = 0,
.no_cpu_limit = 0,
.disable_shm = 0
.disable_shm = 0,
.default_n_fragments = 4,
.default_fragment_size_msec = 25,
.default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 }
#ifdef HAVE_SYS_RESOURCE_H
, .rlimit_as = { .value = 0, .is_set = 0 },
.rlimit_core = { .value = 0, .is_set = 0 },
.rlimit_data = { .value = 0, .is_set = 0 },
.rlimit_fsize = { .value = 0, .is_set = 0 },
.rlimit_nofile = { .value = 200, .is_set = 1 },
.rlimit_nofile = { .value = 256, .is_set = 1 },
.rlimit_stack = { .value = 0, .is_set = 0 }
#ifdef RLIMIT_NPROC
, .rlimit_nproc = { .value = 0, .is_set = 0 }
#endif
#ifdef RLIMIT_MEMLOCK
, .rlimit_memlock = { .value = 0, .is_set = 1 }
, .rlimit_memlock = { .value = 16384, .is_set = 1 }
#endif
#endif
};
pa_daemon_conf* pa_daemon_conf_new(void) {
FILE *f;
pa_daemon_conf *c = pa_xmemdup(&default_conf, sizeof(default_conf));
pa_daemon_conf *c = pa_xnewdup(pa_daemon_conf, &default_conf, 1);
if ((f = pa_open_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE, &c->default_script_file, "r")))
fclose(f);
@ -106,7 +103,7 @@ pa_daemon_conf* pa_daemon_conf_new(void) {
}
void pa_daemon_conf_free(pa_daemon_conf *c) {
assert(c);
pa_assert(c);
pa_xfree(c->script_commands);
pa_xfree(c->dl_search_path);
pa_xfree(c->default_script_file);
@ -115,7 +112,8 @@ void pa_daemon_conf_free(pa_daemon_conf *c) {
}
int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) {
assert(c && string);
pa_assert(c);
pa_assert(string);
if (!strcmp(string, "auto"))
c->auto_log_target = 1;
@ -133,7 +131,8 @@ int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) {
int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) {
uint32_t u;
assert(c && string);
pa_assert(c);
pa_assert(string);
if (pa_atou(string, &u) >= 0) {
if (u >= PA_LOG_LEVEL_MAX)
@ -158,7 +157,8 @@ int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) {
int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
int m;
assert(c && string);
pa_assert(c);
pa_assert(string);
if ((m = pa_parse_resample_method(string)) < 0)
return -1;
@ -169,7 +169,11 @@ int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
pa_daemon_conf *c = data;
assert(filename && lvalue && rvalue && data);
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if (pa_daemon_conf_set_log_target(c, rvalue) < 0) {
pa_log("[%s:%u] Invalid log target '%s'.", filename, line, rvalue);
@ -181,7 +185,11 @@ static int parse_log_target(const char *filename, unsigned line, const char *lva
static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
pa_daemon_conf *c = data;
assert(filename && lvalue && rvalue && data);
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if (pa_daemon_conf_set_log_level(c, rvalue) < 0) {
pa_log("[%s:%u] Invalid log level '%s'.", filename, line, rvalue);
@ -193,10 +201,14 @@ static int parse_log_level(const char *filename, unsigned line, const char *lval
static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
pa_daemon_conf *c = data;
assert(filename && lvalue && rvalue && data);
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if (pa_daemon_conf_set_resample_method(c, rvalue) < 0) {
pa_log("[%s:%u] Inavalid resample method '%s'.", filename, line, rvalue);
pa_log("[%s:%u] Invalid resample method '%s'.", filename, line, rvalue);
return -1;
}
@ -206,10 +218,11 @@ static int parse_resample_method(const char *filename, unsigned line, const char
static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
#ifdef HAVE_SYS_RESOURCE_H
struct pa_rlimit *r = data;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(r);
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(r);
if (rvalue[strspn(rvalue, "\t ")] == 0) {
/* Empty string */
@ -218,7 +231,7 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue,
} else {
int32_t k;
if (pa_atoi(rvalue, &k) < 0) {
pa_log("[%s:%u] Inavalid rlimit '%s'.", filename, line, rvalue);
pa_log("[%s:%u] Invalid rlimit '%s'.", filename, line, rvalue);
return -1;
}
r->is_set = k >= 0;
@ -231,43 +244,138 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue,
return 0;
}
static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
pa_daemon_conf *c = data;
pa_sample_format_t f;
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if ((f = pa_parse_sample_format(rvalue)) < 0) {
pa_log("[%s:%u] Invalid sample format '%s'.", filename, line, rvalue);
return -1;
}
c->default_sample_spec.format = f;
return 0;
}
static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
pa_daemon_conf *c = data;
int32_t r;
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if (pa_atoi(rvalue, &r) < 0 || r > PA_RATE_MAX || r <= 0) {
pa_log("[%s:%u] Invalid sample rate '%s'.", filename, line, rvalue);
return -1;
}
c->default_sample_spec.rate = r;
return 0;
}
static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if (pa_atoi(rvalue, &n) < 0 || n > PA_CHANNELS_MAX || n <= 0) {
pa_log("[%s:%u] Invalid sample channels '%s'.", filename, line, rvalue);
return -1;
}
c->default_sample_spec.channels = (uint8_t) n;
return 0;
}
static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if (pa_atoi(rvalue, &n) < 0 || n < 2) {
pa_log("[%s:%u] Invalid number of fragments '%s'.", filename, line, rvalue);
return -1;
}
c->default_n_fragments = (unsigned) n;
return 0;
}
static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if (pa_atoi(rvalue, &n) < 0 || n < 1) {
pa_log("[%s:%u] Invalid fragment size '%s'.", filename, line, rvalue);
return -1;
}
c->default_fragment_size_msec = (unsigned) n;
return 0;
}
int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
int r = -1;
FILE *f = NULL;
pa_config_item table[] = {
{ "daemonize", pa_config_parse_bool, NULL },
{ "fail", pa_config_parse_bool, NULL },
{ "high-priority", pa_config_parse_bool, NULL },
{ "disallow-module-loading", pa_config_parse_bool, NULL },
{ "exit-idle-time", pa_config_parse_int, NULL },
{ "module-idle-time", pa_config_parse_int, NULL },
{ "scache-idle-time", pa_config_parse_int, NULL },
{ "dl-search-path", pa_config_parse_string, NULL },
{ "default-script-file", pa_config_parse_string, NULL },
{ "log-target", parse_log_target, NULL },
{ "log-level", parse_log_level, NULL },
{ "verbose", parse_log_level, NULL },
{ "resample-method", parse_resample_method, NULL },
{ "use-pid-file", pa_config_parse_bool, NULL },
{ "system-instance", pa_config_parse_bool, NULL },
{ "no-cpu-limit", pa_config_parse_bool, NULL },
{ "disable-shm", pa_config_parse_bool, NULL },
{ "daemonize", pa_config_parse_bool, NULL },
{ "fail", pa_config_parse_bool, NULL },
{ "high-priority", pa_config_parse_bool, NULL },
{ "disallow-module-loading", pa_config_parse_bool, NULL },
{ "exit-idle-time", pa_config_parse_int, NULL },
{ "module-idle-time", pa_config_parse_int, NULL },
{ "scache-idle-time", pa_config_parse_int, NULL },
{ "dl-search-path", pa_config_parse_string, NULL },
{ "default-script-file", pa_config_parse_string, NULL },
{ "log-target", parse_log_target, NULL },
{ "log-level", parse_log_level, NULL },
{ "verbose", parse_log_level, NULL },
{ "resample-method", parse_resample_method, NULL },
{ "use-pid-file", pa_config_parse_bool, NULL },
{ "system-instance", pa_config_parse_bool, NULL },
{ "no-cpu-limit", pa_config_parse_bool, NULL },
{ "disable-shm", pa_config_parse_bool, NULL },
{ "default-sample-format", parse_sample_format, NULL },
{ "default-sample-rate", parse_sample_rate, NULL },
{ "default-sample-channels", parse_sample_channels, NULL },
{ "default-fragments", parse_fragments, NULL },
{ "default-fragment-size-msec", parse_fragment_size_msec, NULL },
#ifdef HAVE_SYS_RESOURCE_H
{ "rlimit-as", parse_rlimit, NULL },
{ "rlimit-core", parse_rlimit, NULL },
{ "rlimit-data", parse_rlimit, NULL },
{ "rlimit-fsize", parse_rlimit, NULL },
{ "rlimit-nofile", parse_rlimit, NULL },
{ "rlimit-stack", parse_rlimit, NULL },
{ "rlimit-as", parse_rlimit, NULL },
{ "rlimit-core", parse_rlimit, NULL },
{ "rlimit-data", parse_rlimit, NULL },
{ "rlimit-fsize", parse_rlimit, NULL },
{ "rlimit-nofile", parse_rlimit, NULL },
{ "rlimit-stack", parse_rlimit, NULL },
#ifdef RLIMIT_NPROC
{ "rlimit-nproc", parse_rlimit, NULL },
{ "rlimit-nproc", parse_rlimit, NULL },
#endif
#ifdef RLIMIT_MEMLOCK
{ "rlimit-memlock", parse_rlimit, NULL },
{ "rlimit-memlock", parse_rlimit, NULL },
#endif
#endif
{ NULL, NULL, NULL },
{ NULL, NULL, NULL },
};
table[0].data = &c->daemonize;
@ -287,25 +395,29 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
table[14].data = &c->system_instance;
table[15].data = &c->no_cpu_limit;
table[16].data = &c->disable_shm;
table[17].data = c;
table[18].data = c;
table[19].data = c;
table[20].data = c;
table[21].data = c;
#ifdef HAVE_SYS_RESOURCE_H
table[17].data = &c->rlimit_as;
table[18].data = &c->rlimit_core;
table[19].data = &c->rlimit_data;
table[20].data = &c->rlimit_fsize;
table[21].data = &c->rlimit_nofile;
table[22].data = &c->rlimit_stack;
table[22].data = &c->rlimit_as;
table[23].data = &c->rlimit_core;
table[24].data = &c->rlimit_data;
table[25].data = &c->rlimit_fsize;
table[26].data = &c->rlimit_nofile;
table[27].data = &c->rlimit_stack;
#ifdef RLIMIT_NPROC
table[23].data = &c->rlimit_nproc;
table[28].data = &c->rlimit_nproc;
#endif
#ifdef RLIMIT_MEMLOCK
#ifndef RLIMIT_NPROC
#error "Houston, we have a numbering problem!"
#endif
table[24].data = &c->rlimit_memlock;
table[29].data = &c->rlimit_memlock;
#endif
#endif
pa_xfree(c->config_file);
c->config_file = NULL;
@ -314,7 +426,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file, "r");
if (!f && errno != ENOENT) {
pa_log("WARNING: failed to open configuration file '%s': %s", c->config_file, pa_cstrerror(errno));
pa_log_warn("Failed to open configuration file '%s': %s", c->config_file, pa_cstrerror(errno));
goto finish;
}
@ -351,12 +463,16 @@ static const char* const log_level_to_string[] = {
};
char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf *s = pa_strbuf_new();
pa_strbuf *s;
pa_assert(c);
s = pa_strbuf_new();
if (c->config_file)
pa_strbuf_printf(s, "### Read from configuration file: %s ###\n", c->config_file);
assert(c->log_level <= PA_LOG_LEVEL_MAX);
pa_assert(c->log_level <= PA_LOG_LEVEL_MAX);
pa_strbuf_printf(s, "daemonize = %i\n", !!c->daemonize);
pa_strbuf_printf(s, "fail = %i\n", !!c->fail);
@ -373,7 +489,12 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf_printf(s, "use-pid-file = %i\n", c->use_pid_file);
pa_strbuf_printf(s, "system-instance = %i\n", !!c->system_instance);
pa_strbuf_printf(s, "no-cpu-limit = %i\n", !!c->no_cpu_limit);
pa_strbuf_printf(s, "disable_shm = %i\n", !!c->disable_shm);
pa_strbuf_printf(s, "disable-shm = %i\n", !!c->disable_shm);
pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments);
pa_strbuf_printf(s, "default-fragment-size-msec = %u\n", c->default_fragment_size_msec);
#ifdef HAVE_SYS_RESOURCE_H
pa_strbuf_printf(s, "rlimit-as = %li\n", c->rlimit_as.is_set ? (long int) c->rlimit_as.value : -1);
pa_strbuf_printf(s, "rlimit-core = %li\n", c->rlimit_core.is_set ? (long int) c->rlimit_core.value : -1);

View file

@ -26,6 +26,7 @@
***/
#include <pulsecore/log.h>
#include <pulse/sample.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
@ -39,7 +40,9 @@ typedef enum pa_daemon_conf_cmd {
PA_CMD_DUMP_CONF,
PA_CMD_DUMP_MODULES,
PA_CMD_KILL,
PA_CMD_CHECK
PA_CMD_CHECK,
PA_CMD_DUMP_RESAMPLE_METHODS,
PA_CMD_CLEANUP_SHM
} pa_daemon_conf_cmd_t;
#ifdef HAVE_SYS_RESOURCE_H
@ -80,6 +83,8 @@ typedef struct pa_daemon_conf {
#endif
#endif
unsigned default_n_fragments, default_fragment_size_msec;
pa_sample_spec default_sample_spec;
} pa_daemon_conf;
/* Allocate a new structure and fill it with sane defaults */

View file

@ -92,10 +92,19 @@
; rlimit-core = -1
; rlimit-data = -1
; rlimit-fsize = -1
; rlimit-nofile = 200
; rlimit-nofile = 256
; rlimit-stack = -1
; rlimit-nproc = -1
; rlimit-memlock = 25
; rlimit-memlock = 16384
## Disable shared memory data transfer
; disable-shm = 0
## Default sample format
; default-sample-format = s16le
; default-sample-rate = 44100
; default-sample-channels = 2
## Default fragment settings, for device drivers that need this
; default-fragments = 4
; default-fragment-size-msec = 25

View file

@ -1,5 +1,4 @@
#!@PA_BINARY@ -nF
#!@PA_BINARY@ -nF
#
# This file is part of PulseAudio.
#
@ -17,8 +16,19 @@
# along with PulseAudio; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
.nofail
### Load audio drivers statically
### Load something into the sample cache
#load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav
load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
#load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav
#load-sample-lazy pulse-access /usr/share/sounds/generic.wav
.fail
### Load audio drivers statically (it's probably better to not load
### these drivers manually, but instead use module-hal-detect --
### see below -- for doing this automatically)
#load-module module-alsa-sink
#load-module module-alsa-source device=hw:1,0
#load-module module-oss device="/dev/dsp" sink_name=output source_name=input
@ -27,19 +37,13 @@
#load-module module-pipe-sink
### Automatically load driver modules depending on the hardware available
@HAVE_HAL_TRUE@load-module module-hal-detect
.ifexists @PA_DLSEARCHPATH@/module-hal-detect@PA_SOEXT@
load-module module-hal-detect
.else
### Alternatively use the static hardware detection module (for systems that
### lack HAL support
@HAVE_HAL_FALSE@load-module module-detect
### Load audio drivers automatically on access
#add-autoload-sink output module-oss device="/dev/dsp" sink_name=output source_name=input
#add-autoload-source input module-oss device="/dev/dsp" sink_name=output source_name=input
#add-autoload-sink output module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
#add-autoload-source input module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
#add-autoload-sink output module-alsa-sink sink_name=output
#add-autoload-source input module-alsa-source source_name=input
### lack HAL support)
load-module module-detect
.endif
### Load several protocols
load-module module-esound-protocol-unix
@ -61,27 +65,36 @@ load-module module-native-protocol-unix
### Automatically restore the volume of playback streams
load-module module-volume-restore
### Automatically restore the default sink/source when changed by the user during runtime
load-module module-default-device-restore
### Automatically move streams to the default sink if the sink they are
### connected to dies, similar for sources
load-module module-rescue-streams
### Make some devices default
#set-default-sink output
#set-default-source input
.nofail
### Load something to the sample cache
load-sample x11-bell /usr/share/sounds/gtk-events/activate.wav
#load-sample-dir-lazy /usr/share/sounds/*.wav
### 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=x11-bell
### Publish connection data in the X11 root window
.ifexists @PA_DLSEARCHPATH@/module-x11-publish@PA_SOEXT@
load-module module-x11-publish
.endif
### 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 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
### loaded modules.
.ifexists @PA_DLSEARCHPATH@/module-gconf@PA_SOEXT@
load-module module-gconf
.endif
### Make some devices default
#set-default-sink output
#set-default-source input

View file

@ -28,26 +28,30 @@
#include <string.h>
#include <getopt.h>
#include <assert.h>
#include <stdio.h>
#include <ltdl.h>
#include <pulse/util.h>
#include <pulsecore/modinfo.h>
#include <pulsecore/core-util.h>
#include <pulsecore/macro.h>
#include "dumpmodules.h"
#define PREFIX "module-"
static void short_info(const char *name, PA_GCC_UNUSED const char *path, pa_modinfo *i) {
assert(name && i);
pa_assert(name);
pa_assert(i);
printf("%-40s%s\n", name, i->description ? i->description : "n/a");
}
static void long_info(const char *name, const char *path, pa_modinfo *i) {
static int nl = 0;
assert(name && i);
pa_assert(name);
pa_assert(i);
if (nl)
printf("\n");
@ -76,6 +80,8 @@ static void long_info(const char *name, const char *path, pa_modinfo *i) {
static void show_info(const char *name, const char *path, void (*info)(const char *name, const char *path, pa_modinfo*i)) {
pa_modinfo *i;
pa_assert(name);
if ((i = pa_modinfo_get_by_name(path ? path : name))) {
info(name, path, i);
pa_modinfo_free(i);
@ -93,7 +99,7 @@ static int is_preloaded(const char *name) {
if (l->address)
continue;
snprintf(buf, sizeof(buf), "%s", l->name);
pa_snprintf(buf, sizeof(buf), "%s", l->name);
if ((e = strrchr(buf, '.')))
*e = 0;
@ -121,6 +127,8 @@ static int callback(const char *path, lt_ptr data) {
}
void pa_dump_modules(pa_daemon_conf *c, int argc, char * const argv[]) {
pa_assert(c);
if (argc > 0) {
int i;
for (i = 0; i < argc; i++)
@ -137,7 +145,7 @@ void pa_dump_modules(pa_daemon_conf *c, int argc, char * const argv[]) {
if (strlen(l->name) <= sizeof(PREFIX)-1 || strncmp(l->name, PREFIX, sizeof(PREFIX)-1))
continue;
snprintf(buf, sizeof(buf), "%s", l->name);
pa_snprintf(buf, sizeof(buf), "%s", l->name);
if ((e = strrchr(buf, '.')))
*e = 0;

160
src/daemon/ltdl-bind-now.c Normal file
View file

@ -0,0 +1,160 @@
/* $Id$ */
/***
This file is part of PulseAudio.
Copyright 2004-2006 Lennart Poettering
Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#if HAVE_SYS_DL_H
#include <sys/dl.h>
#endif
#include <ltdl.h>
#include <pulsecore/macro.h>
#include <pulsecore/mutex.h>
#include <pulsecore/thread.h>
#include <pulsecore/log.h>
#include "ltdl-bind-now.h"
#ifdef RTLD_NOW
#define PA_BIND_NOW RTLD_NOW
#elif defined(DL_NOW)
#define PA_BIND_NOW DL_NOW
#else
#undef PA_BIND_NOW
#endif
static pa_mutex *libtool_mutex = NULL;
PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls);
static void libtool_lock(void) {
pa_mutex_lock(libtool_mutex);
}
static void libtool_unlock(void) {
pa_mutex_unlock(libtool_mutex);
}
static void libtool_set_error(const char *error) {
PA_STATIC_TLS_SET(libtool_tls, (char*) error);
}
static const char *libtool_get_error(void) {
return PA_STATIC_TLS_GET(libtool_tls);
}
#ifdef PA_BIND_NOW
/*
To avoid lazy relocations during runtime in our RT threads we add
our own shared object loader with uses RTLD_NOW if it is
available. The standard ltdl loader prefers RTLD_LAZY.
Please note that this loader doesn't have any influence on
relocations on any libraries that are already loaded into our
process, i.e. because the pulseaudio binary links directly to
them. To disable lazy relocations for those libraries it is possible
to set $LT_BIND_NOW before starting the pulsaudio binary.
*/
static lt_module bind_now_open(lt_user_data d, const char *fname) {
lt_module m;
pa_assert(fname);
if (!(m = dlopen(fname, PA_BIND_NOW))) {
libtool_set_error(dlerror());
return NULL;
}
return m;
}
static int bind_now_close(lt_user_data d, lt_module m) {
pa_assert(m);
if (dlclose(m) != 0){
libtool_set_error(dlerror());
return 1;
}
return 0;
}
static lt_ptr bind_now_find_sym(lt_user_data d, lt_module m, const char *symbol) {
lt_ptr ptr;
pa_assert(m);
pa_assert(symbol);
if (!(ptr = dlsym(m, symbol))) {
libtool_set_error(dlerror());
return NULL;
}
return ptr;
}
#endif
void pa_ltdl_init(void) {
#ifdef PA_BIND_NOW
lt_dlloader *place;
static const struct lt_user_dlloader loader = {
.module_open = bind_now_open,
.module_close = bind_now_close,
.find_sym = bind_now_find_sym
};
#endif
pa_assert_se(lt_dlinit() == 0);
pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE));
pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0);
#ifdef PA_BIND_NOW
if (!(place = lt_dlloader_find("dlopen")))
place = lt_dlloader_next(NULL);
/* Add our BIND_NOW loader as the default module loader. */
if (lt_dlloader_add(place, &loader, "bind-now-loader") != 0)
pa_log_warn("Failed to add bind-now-loader.");
#endif
}
void pa_ltdl_done(void) {
pa_assert_se(lt_dlexit() == 0);
pa_mutex_free(libtool_mutex);
libtool_mutex = NULL;
}

View file

@ -0,0 +1,32 @@
#ifndef foopulsecoreltdlbindnowhfoo
#define foopulsecoreltdlbindnowhfoo
/* $Id$ */
/***
This file is part of PulseAudio.
Copyright 2004-2006 Lennart Poettering
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
void pa_ltdl_init(void);
void pa_ltdl_done(void);
#endif

View file

@ -33,7 +33,6 @@
#include <stdio.h>
#include <signal.h>
#include <stddef.h>
#include <assert.h>
#include <ltdl.h>
#include <limits.h>
#include <fcntl.h>
@ -59,13 +58,16 @@
#include <tcpd.h>
#endif
#include "../pulsecore/winsock.h"
#ifdef HAVE_DBUS
#include <dbus/dbus.h>
#endif
#include <pulse/mainloop.h>
#include <pulse/mainloop-signal.h>
#include <pulse/timeval.h>
#include <pulse/xmalloc.h>
#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
#include <pulsecore/core.h>
#include <pulsecore/memblock.h>
@ -78,12 +80,20 @@
#include <pulsecore/pid.h>
#include <pulsecore/namereg.h>
#include <pulsecore/random.h>
#include <pulsecore/rtsig.h>
#include <pulsecore/rtclock.h>
#include <pulsecore/macro.h>
#include <pulsecore/mutex.h>
#include <pulsecore/thread.h>
#include <pulsecore/once.h>
#include <pulsecore/shm.h>
#include "cmdline.h"
#include "cpulimit.h"
#include "daemon-conf.h"
#include "dumpmodules.h"
#include "caps.h"
#include "ltdl-bind-now.h"
#ifdef HAVE_LIBWRAP
/* Only one instance of these variables */
@ -120,7 +130,7 @@ static void message_cb(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const s
#endif
static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e, int sig, void *userdata) {
pa_log_info("Got signal %s.", pa_strsignal(sig));
pa_log_info("Got signal %s.", pa_sig2str(sig));
switch (sig) {
#ifdef SIGUSR1
@ -153,14 +163,6 @@ static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e,
}
}
static void close_pipe(int p[2]) {
if (p[0] != -1)
close(p[0]);
if (p[1] != -1)
close(p[1]);
p[0] = p[1] = -1;
}
#define set_env(key, value) putenv(pa_sprintf_malloc("%s=%s", (key), (value)))
#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
@ -281,7 +283,7 @@ static int create_runtime_dir(void) {
static void set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
struct rlimit rl;
assert(r);
pa_assert(r);
if (!r->is_set)
return;
@ -313,13 +315,11 @@ int main(int argc, char *argv[]) {
pa_strbuf *buf = NULL;
pa_daemon_conf *conf = NULL;
pa_mainloop *mainloop = NULL;
char *s;
int r, retval = 1, d = 0;
int r = 0, retval = 1, d = 0;
int daemon_pipe[2] = { -1, -1 };
int suid_root, real_root;
int valid_pid_file = 0;
gid_t gid = (gid_t) -1;
#ifdef OS_IS_WIN32
@ -327,6 +327,23 @@ int main(int argc, char *argv[]) {
struct timeval tv;
#endif
#if defined(__linux__) && defined(__OPTIMIZE__)
/*
Disable lazy relocations to make usage of external libraries
more deterministic for our RT threads. We abuse __OPTIMIZE__ as
a check whether we are a debug build or not.
*/
if (!getenv("LD_BIND_NOW")) {
putenv(pa_xstrdup("LD_BIND_NOW=1"));
/* We have to execute ourselves, because the libc caches the
* value of $LD_BIND_NOW on initialization. */
pa_assert_se(execv("/proc/self/exe", argv) == 0);
}
#endif
#ifdef HAVE_GETUID
real_root = getuid() == 0;
suid_root = !real_root && geteuid() == 0;
@ -336,16 +353,26 @@ int main(int argc, char *argv[]) {
#endif
if (suid_root) {
if (pa_limit_caps() > 0)
/* We managed to drop capabilities except the needed
* ones. Hence we can drop the uid. */
pa_drop_root();
/* Drop all capabilities except CAP_SYS_NICE */
pa_limit_caps();
/* Drop priviliges, but keep CAP_SYS_NICE */
pa_drop_root();
/* After dropping root, the effective set is reset, hence,
* let's raise it again */
pa_limit_caps();
/* When capabilities are not supported we will not be able to
* aquire RT sched anymore. But yes, that's the way it is. It
* is just too risky tun let PA run as root all the time. */
}
setlocale(LC_ALL, "");
if (suid_root && (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) <= 0 || gid >= 1000)) {
pa_log_warn("WARNING: called SUID root, but not in group '"PA_REALTIME_GROUP"'.");
if (suid_root && (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) <= 0)) {
pa_log_info("Warning: Called SUID root, but not in group '"PA_REALTIME_GROUP"'. "
"For enabling real-time scheduling please become a member of '"PA_REALTIME_GROUP"' , or increase the RLIMIT_RTPRIO user limit.");
pa_drop_caps();
pa_drop_root();
suid_root = real_root = 0;
@ -353,8 +380,7 @@ int main(int argc, char *argv[]) {
LTDL_SET_PRELOADED_SYMBOLS();
r = lt_dlinit();
assert(r == 0);
pa_ltdl_init();
#ifdef OS_IS_WIN32
{
@ -386,7 +412,7 @@ int main(int argc, char *argv[]) {
if (conf->high_priority && conf->cmd == PA_CMD_DAEMON)
pa_raise_priority();
if (suid_root) {
if (suid_root && (conf->cmd != PA_CMD_DAEMON || !conf->high_priority)) {
pa_drop_caps();
pa_drop_root();
}
@ -408,6 +434,16 @@ int main(int argc, char *argv[]) {
goto finish;
}
case PA_CMD_DUMP_RESAMPLE_METHODS: {
int i;
for (i = 0; i < PA_RESAMPLER_MAX; i++)
if (pa_resample_method_supported(i))
printf("%s\n", pa_resample_method_to_string(i));
goto finish;
}
case PA_CMD_HELP :
pa_cmdline_help(argv[0]);
retval = 0;
@ -440,8 +476,15 @@ int main(int argc, char *argv[]) {
goto finish;
case PA_CMD_CLEANUP_SHM:
if (pa_shm_cleanup() >= 0)
retval = 0;
goto finish;
default:
assert(conf->cmd == PA_CMD_DAEMON);
pa_assert(conf->cmd == PA_CMD_DAEMON);
}
if (real_root && !conf->system_instance) {
@ -474,7 +517,7 @@ int main(int argc, char *argv[]) {
if (child != 0) {
/* Father */
close(daemon_pipe[1]);
pa_assert_se(pa_close(daemon_pipe[1]) == 0);
daemon_pipe[1] = -1;
if (pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL) != sizeof(retval)) {
@ -490,7 +533,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
close(daemon_pipe[0]);
pa_assert_se(pa_close(daemon_pipe[0]) == 0);
daemon_pipe[0] = -1;
#endif
@ -505,9 +548,9 @@ int main(int argc, char *argv[]) {
#endif
#ifndef OS_IS_WIN32
close(0);
close(1);
close(2);
pa_close(0);
pa_close(1);
pa_close(2);
open("/dev/null", O_RDONLY);
open("/dev/null", O_WRONLY);
@ -529,12 +572,12 @@ int main(int argc, char *argv[]) {
#ifdef TIOCNOTTY
if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
ioctl(tty_fd, TIOCNOTTY, (char*) 0);
close(tty_fd);
pa_assert_se(pa_close(tty_fd) == 0);
}
#endif
}
chdir("/");
pa_assert_se(chdir("/") == 0);
umask(0022);
if (conf->system_instance) {
@ -564,18 +607,37 @@ int main(int argc, char *argv[]) {
signal(SIGPIPE, SIG_IGN);
#endif
mainloop = pa_mainloop_new();
assert(mainloop);
pa_log_info("Page size is %lu bytes", (unsigned long) PA_PAGE_SIZE);
if (pa_rtclock_hrtimer())
pa_log_info("Fresh high-resolution timers available! Bon appetit!");
else
pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!");
#ifdef SIGRTMIN
/* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */
pa_rtsig_configure(SIGRTMIN, SIGRTMAX-1);
#endif
pa_assert_se(mainloop = pa_mainloop_new());
if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm))) {
pa_log("pa_core_new() failed.");
pa_log("pa_core_new() failed.");
goto finish;
}
c->is_system_instance = !!conf->system_instance;
c->high_priority = !!conf->high_priority;
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;
c->disallow_module_loading = conf->disallow_module_loading;
c->exit_idle_time = conf->exit_idle_time;
c->module_idle_time = conf->module_idle_time;
c->scache_idle_time = conf->scache_idle_time;
c->resample_method = conf->resample_method;
r = pa_signal_init(pa_mainloop_get_api(mainloop));
assert(r == 0);
pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
pa_signal_new(SIGINT, signal_callback, c);
pa_signal_new(SIGTERM, signal_callback, c);
@ -590,9 +652,7 @@ int main(int argc, char *argv[]) {
#endif
#ifdef OS_IS_WIN32
timer = pa_mainloop_get_api(mainloop)->time_new(
pa_mainloop_get_api(mainloop), pa_gettimeofday(&tv), message_cb, NULL);
assert(timer);
pa_assert_se(timer = pa_mainloop_get_api(mainloop)->time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&tv), message_cb, NULL));
#endif
if (conf->daemonize)
@ -600,10 +660,8 @@ int main(int argc, char *argv[]) {
oil_init();
if (!conf->no_cpu_limit) {
r = pa_cpu_limit_init(pa_mainloop_get_api(mainloop));
assert(r == 0);
}
if (!conf->no_cpu_limit)
pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
buf = pa_strbuf_new();
if (conf->default_script_file)
@ -634,12 +692,6 @@ int main(int argc, char *argv[]) {
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
#endif
c->disallow_module_loading = conf->disallow_module_loading;
c->exit_idle_time = conf->exit_idle_time;
c->module_idle_time = conf->module_idle_time;
c->scache_idle_time = conf->scache_idle_time;
c->resample_method = conf->resample_method;
if (c->default_sink_name &&
pa_namereg_get(c, c->default_sink_name, PA_NAMEREG_SINK, 1) == NULL) {
pa_log_error("%s : Fatal error. Default sink name (%s) does not exist in name register.", __FILE__, c->default_sink_name);
@ -656,7 +708,7 @@ int main(int argc, char *argv[]) {
pa_mainloop_get_api(mainloop)->time_free(timer);
#endif
pa_core_free(c);
pa_core_unref(c);
if (!conf->no_cpu_limit)
pa_cpu_limit_done();
@ -676,13 +728,17 @@ finish:
if (valid_pid_file)
pa_pid_file_remove();
close_pipe(daemon_pipe);
pa_close_pipe(daemon_pipe);
#ifdef OS_IS_WIN32
WSACleanup();
#endif
lt_dlexit();
pa_ltdl_done();
#ifdef HAVE_DBUS
dbus_shutdown();
#endif
return retval;
}

View file

@ -0,0 +1,10 @@
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Name=PulseAudio Session Management
Comment=Load module-x11-xsmp into PulseAudio
Exec=pactl load-module module-x11-xsmp
Terminal=false
Type=Application
Categories=
GenericName=