diff options
Diffstat (limited to 'src')
55 files changed, 675 insertions, 212 deletions
diff --git a/src/.gitignore b/src/.gitignore index 6cd173c0..64ab2973 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -63,4 +63,5 @@ thread-test utf8-test voltest start-pulseaudio-x11 +start-pulseaudio-kde vector-test diff --git a/src/Makefile.am b/src/Makefile.am index 98c04683..f0d5a5e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -141,8 +141,10 @@ EXTRA_DIST = \ modules/alsa/mixer/paths/analog-input-tvtuner.conf \ modules/alsa/mixer/paths/analog-input-video.conf \ modules/alsa/mixer/paths/analog-output.conf \ + modules/alsa/mixer/paths/analog-output-speaker.conf \ modules/alsa/mixer/paths/analog-output.conf.common \ modules/alsa/mixer/paths/analog-output-headphones.conf \ + modules/alsa/mixer/paths/analog-output-headphones-2.conf \ modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf \ modules/alsa/mixer/paths/analog-output-mono.conf diff --git a/src/daemon/.gitignore b/src/daemon/.gitignore index 0efa55ba..54e4299b 100644 --- a/src/daemon/.gitignore +++ b/src/daemon/.gitignore @@ -1,2 +1,3 @@ org.pulseaudio.policy pulseaudio.desktop +pulseaudio-kde.desktop diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index c2877ecf..f5042a75 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -188,15 +188,13 @@ int pa_cpu_limit_init(pa_mainloop_api *m) { last_time = pa_rtclock_now(); /* Prepare the main loop pipe */ - if (pipe(the_pipe) < 0) { + if (pa_pipe_cloexec(the_pipe) < 0) { pa_log("pipe() failed: %s", pa_cstrerror(errno)); return -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); diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 571faae4..bfd5c118 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -577,7 +577,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { c->config_file = NULL; f = filename ? - fopen(c->config_file = pa_xstrdup(filename), "r") : + pa_fopen_cloexec(c->config_file = pa_xstrdup(filename), "r") : pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file); if (!f && errno != ENOENT) { @@ -652,7 +652,7 @@ FILE *pa_daemon_conf_open_default_script_file(pa_daemon_conf *c) { else f = pa_open_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE, &c->default_script_file); } else - f = fopen(c->default_script_file, "r"); + f = pa_fopen_cloexec(c->default_script_file, "r"); return f; } diff --git a/src/daemon/main.c b/src/daemon/main.c index 9e5647a8..cc6f24bd 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -425,21 +425,24 @@ int main(int argc, char *argv[]) { pa_set_env("LD_BIND_NOW", "1"); - canonical_rp = pa_realpath(PA_BINARY); + if ((canonical_rp = pa_realpath(PA_BINARY))) { - if ((rp = pa_readlink("/proc/self/exe"))) { + if ((rp = pa_readlink("/proc/self/exe"))) { - if (pa_streq(rp, canonical_rp)) - pa_assert_se(execv(rp, argv) == 0); - else - pa_log_warn("/proc/self/exe does not point to %s, cannot self execute. Are you playing games?", canonical_rp); + if (pa_streq(rp, canonical_rp)) + pa_assert_se(execv(rp, argv) == 0); + else + pa_log_warn("/proc/self/exe does not point to %s, cannot self execute. Are you playing games?", canonical_rp); - pa_xfree(rp); + pa_xfree(rp); - } else - pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?"); + } else + pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?"); + + pa_xfree(canonical_rp); - pa_xfree(canonical_rp); + } else + pa_log_warn("Couldn't canonicalize binary path, cannot self execute."); } #endif @@ -654,7 +657,7 @@ int main(int argc, char *argv[]) { #ifdef HAVE_FORK if (pipe(daemon_pipe) < 0) { - pa_log(_("pipe failed: %s"), pa_cstrerror(errno)); + pa_log(_("pipe() failed: %s"), pa_cstrerror(errno)); goto finish; } @@ -705,22 +708,27 @@ int main(int argc, char *argv[]) { pa_log_set_target(PA_LOG_SYSLOG); #ifdef HAVE_SETSID - setsid(); -#endif -#ifdef HAVE_SETPGID - setpgid(0,0); + if (setsid() < 0) { + pa_log(_("setsid() failed: %s"), pa_cstrerror(errno)); + goto finish; + } #endif -#ifndef OS_IS_WIN32 - pa_close(0); - pa_close(1); - pa_close(2); + /* We now are a session and process group leader. Let's fork + * again and let the father die, so that we'll become a + * process that can never acquire a TTY again, in a session and + * process group without leader */ - pa_assert_se(open("/dev/null", O_RDONLY) == 0); - pa_assert_se(open("/dev/null", O_WRONLY) == 1); - pa_assert_se(open("/dev/null", O_WRONLY) == 2); -#else - FreeConsole(); +#ifdef HAVE_FORK + if ((child = fork()) < 0) { + pa_log(_("fork() failed: %s"), pa_cstrerror(errno)); + goto finish; + } + + if (child != 0) { + retval = 0; + goto finish; + } #endif #ifdef SIGTTOU @@ -733,12 +741,7 @@ int main(int argc, char *argv[]) { signal(SIGTSTP, SIG_IGN); #endif -#ifdef TIOCNOTTY - if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) { - ioctl(tty_fd, TIOCNOTTY, (char*) 0); - pa_assert_se(pa_close(tty_fd) == 0); - } -#endif + pa_nullify_stdfds(); } pa_set_env_and_record("PULSE_INTERNAL", "1"); diff --git a/src/modules/alsa/mixer/paths/analog-input.conf.common b/src/modules/alsa/mixer/paths/analog-input.conf.common index 87af38b3..951e11fa 100644 --- a/src/modules/alsa/mixer/paths/analog-input.conf.common +++ b/src/modules/alsa/mixer/paths/analog-input.conf.common @@ -98,7 +98,11 @@ priority = 18 name = input-docking priority = 17 -;;; ' Capture Source' +[Option Input Source:AUX IN] +name = input +priority = 10 + +;;; 'Capture Source' [Element Capture Source] enumeration = select @@ -244,6 +248,31 @@ name = input-docking [Option Capture Source:Dock Mic] name = input-docking-microphone +;;; 'Mic Jack Mode' + +[Element Mic Jack Mode] +enumeration = select + +[Option Mic Jack Mode:Mic In] +name = input-microphone + +[Option Mic Jack Mode:Line In] +name = input-linein + +;;; 'Digital Input Source' + +[Element Digital Input Source] +enumeration = select + +[Option Digital Input Source:Analog Inputs] +name = input + +[Option Digital Input Source:Digital Mic 1] +name = input-microphone + +[Option Digital Input Source:Digital Mic 2] +name = input-microphone + ;;; Various Boosts [Element Capture Boost] diff --git a/src/modules/alsa/mixer/paths/analog-output-headphones-2.conf b/src/modules/alsa/mixer/paths/analog-output-headphones-2.conf new file mode 100644 index 00000000..f2fd31c7 --- /dev/null +++ b/src/modules/alsa/mixer/paths/analog-output-headphones-2.conf @@ -0,0 +1,82 @@ +# This file is part of PulseAudio. +# +# 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.1 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. + +; Path for mixers that have a 'Headphone2' control +; +; See analog-output.conf.common for an explanation on the directives + +[General] +priority = 89 + +[Element Hardware Master] +switch = mute +volume = merge +override-map.1 = all +override-map.2 = all-left,all-right + +[Element Master] +switch = mute +volume = merge +override-map.1 = all +override-map.2 = all-left,all-right + +[Element Master Mono] +switch = off +volume = off + +; This profile path is intended to control the second headphones, not +; the first headphones. But it should not hurt if we leave the +; headphone jack enabled nonetheless. +[Element Headphone] +switch = mute +volume = zero + +[Element Headphone2] +required = any +switch = mute +volume = merge +override-map.1 = all +override-map.2 = all-left,all-right + +[Element Speaker] +switch = off +volume = off + +[Element Front] +switch = off +volume = off + +[Element Rear] +switch = off +volume = off + +[Element Surround] +switch = off +volume = off + +[Element Side] +switch = off +volume = off + +[Element Center] +switch = off +volume = off + +[Element LFE] +switch = off +volume = off + +.include analog-output.conf.common diff --git a/src/modules/alsa/mixer/paths/analog-output-headphones.conf b/src/modules/alsa/mixer/paths/analog-output-headphones.conf index 61d2e297..2131cfe8 100644 --- a/src/modules/alsa/mixer/paths/analog-output-headphones.conf +++ b/src/modules/alsa/mixer/paths/analog-output-headphones.conf @@ -44,6 +44,13 @@ volume = merge override-map.1 = all override-map.2 = all-left,all-right +; This profile path is intended to control the first headphones, not +; the second headphones. But it should not hurt if we leave the second +; headphone jack enabled nonetheless. +[Element Headphone2] +switch = mute +volume = zero + [Element Speaker] switch = off volume = off diff --git a/src/modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf b/src/modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf index 911361d7..0a43e271 100644 --- a/src/modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf +++ b/src/modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf @@ -48,6 +48,10 @@ override-map.2 = lfe,lfe switch = mute volume = zero +[Element Headphone2] +switch = mute +volume = zero + [Element Speaker] switch = mute volume = merge diff --git a/src/modules/alsa/mixer/paths/analog-output-mono.conf b/src/modules/alsa/mixer/paths/analog-output-mono.conf index 2fbc60b7..542edc40 100644 --- a/src/modules/alsa/mixer/paths/analog-output-mono.conf +++ b/src/modules/alsa/mixer/paths/analog-output-mono.conf @@ -45,6 +45,10 @@ override-map.2 = all-left,all-right switch = mute volume = zero +[Element Headphone2] +switch = mute +volume = zero + [Element Speaker] switch = mute volume = merge diff --git a/src/modules/alsa/mixer/paths/analog-output-speaker.conf b/src/modules/alsa/mixer/paths/analog-output-speaker.conf new file mode 100644 index 00000000..aea78534 --- /dev/null +++ b/src/modules/alsa/mixer/paths/analog-output-speaker.conf @@ -0,0 +1,94 @@ +# This file is part of PulseAudio. +# +# 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.1 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. + +; Path for mixers that have a 'Speaker' control +; +; See analog-output.conf.common for an explanation on the directives + +[General] +priority = 100 + +[Element Hardware Master] +switch = mute +volume = merge +override-map.1 = all +override-map.2 = all-left,all-right + +[Element Master] +switch = mute +volume = merge +override-map.1 = all +override-map.2 = all-left,all-right + +[Element Master Mono] +switch = off +volume = off + +; This profile path is intended to control the speaker, not the +; headphones. But it should not hurt if we leave the headphone jack +; enabled nonetheless. +[Element Headphone] +switch = mute +volume = zero + +[Element Headphone2] +switch = mute +volume = zero + +[Element Speaker] +required = any +switch = mute +volume = merge +override-map.1 = all +override-map.2 = all-left,all-right + +[Element Front] +switch = mute +volume = merge +override-map.1 = all-front +override-map.2 = front-left,front-right + +[Element Rear] +switch = mute +volume = merge +override-map.1 = all-rear +override-map.2 = rear-left,rear-right + +[Element Surround] +switch = mute +volume = merge +override-map.1 = all-rear +override-map.2 = rear-left,rear-right + +[Element Side] +switch = mute +volume = merge +override-map.1 = all-side +override-map.2 = side-left,side-right + +[Element Center] +switch = mute +volume = merge +override-map.1 = all-center +override-map.2 = all-center,all-center + +[Element LFE] +switch = mute +volume = merge +override-map.1 = lfe +override-map.2 = lfe,lfe + +.include analog-output.conf.common diff --git a/src/modules/alsa/mixer/paths/analog-output.conf b/src/modules/alsa/mixer/paths/analog-output.conf index f71a05a1..d7c1223b 100644 --- a/src/modules/alsa/mixer/paths/analog-output.conf +++ b/src/modules/alsa/mixer/paths/analog-output.conf @@ -14,12 +14,13 @@ # along with PulseAudio; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -; Intended for the 'default' output +; Intended for the 'default' output. Note that a-o-speaker.conf has a +; higher priority than this ; ; See analog-output.conf.common for an explanation on the directives [General] -priority = 100 +priority = 99 [Element Hardware Master] switch = mute @@ -37,18 +38,20 @@ override-map.2 = all-left,all-right switch = off volume = off -; This profile path is intended to control the speaker, not the +; This profile path is intended to control the default output, not the ; headphones. But it should not hurt if we leave the headphone jack ; enabled nonetheless. [Element Headphone] switch = mute volume = zero +[Element Headphone2] +switch = mute +volume = zero + [Element Speaker] switch = mute -volume = merge -override-map.1 = all -override-map.2 = all-left,all-right +volume = off [Element Front] switch = mute diff --git a/src/modules/alsa/mixer/profile-sets/default.conf b/src/modules/alsa/mixer/profile-sets/default.conf index ac41a8d3..046938fc 100644 --- a/src/modules/alsa/mixer/profile-sets/default.conf +++ b/src/modules/alsa/mixer/profile-sets/default.conf @@ -62,42 +62,42 @@ auto-profiles = yes [Mapping analog-mono] device-strings = hw:%f channel-map = mono -paths-output = analog-output analog-output-headphones analog-output-mono analog-output-lfe-on-mono +paths-output = analog-output analog-output-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono analog-output-lfe-on-mono paths-input = analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line priority = 1 [Mapping analog-stereo] device-strings = front:%f hw:%f channel-map = left,right -paths-output = analog-output analog-output-headphones analog-output-mono analog-output-lfe-on-mono +paths-output = analog-output analog-output-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono analog-output-lfe-on-mono paths-input = analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line priority = 10 [Mapping analog-surround-40] device-strings = surround40:%f channel-map = front-left,front-right,rear-left,rear-right -paths-output = analog-output analog-output-lfe-on-mono +paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono priority = 7 direction = output [Mapping analog-surround-41] device-strings = surround41:%f channel-map = front-left,front-right,rear-left,rear-right,lfe -paths-output = analog-output analog-output-lfe-on-mono +paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono priority = 8 direction = output [Mapping analog-surround-50] device-strings = surround50:%f channel-map = front-left,front-right,rear-left,rear-right,front-center -paths-output = analog-output analog-output-lfe-on-mono +paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono priority = 7 direction = output [Mapping analog-surround-51] device-strings = surround51:%f channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe -paths-output = analog-output analog-output-lfe-on-mono +paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono priority = 8 direction = output @@ -105,7 +105,7 @@ direction = output device-strings = surround71:%f channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right description = Analog Surround 7.1 -paths-output = analog-output analog-output-lfe-on-mono +paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono priority = 7 direction = output diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index f8c5b778..47d62005 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -723,12 +723,14 @@ const pa_bluetooth_device* pa_bluetooth_discovery_get_by_address(pa_bluetooth_di while ((d = pa_hashmap_iterate(y->devices, &state, NULL))) if (pa_streq(d->address, address)) - return d; + return device_is_audio(d) ? d : NULL; return NULL; } const pa_bluetooth_device* pa_bluetooth_discovery_get_by_path(pa_bluetooth_discovery *y, const char* path) { + pa_bluetooth_device *d; + pa_assert(y); pa_assert(PA_REFCNT_VALUE(y) > 0); pa_assert(path); @@ -736,7 +738,11 @@ const pa_bluetooth_device* pa_bluetooth_discovery_get_by_path(pa_bluetooth_disco if (!pa_hook_is_firing(&y->hook)) pa_bluetooth_discovery_sync(y); - return pa_hashmap_get(y->devices, path); + if ((d = pa_hashmap_get(y->devices, path))) + if (device_is_audio(d)) + return d; + + return NULL; } static int setup_dbus(pa_bluetooth_discovery *y) { diff --git a/src/modules/module-cli.c b/src/modules/module-cli.c index 6bd0f4fc..c5ff4564 100644 --- a/src/modules/module-cli.c +++ b/src/modules/module-cli.c @@ -105,7 +105,7 @@ int pa__init(pa_module*m) { * of log messages, particularly because if stdout and stderr are * dup'ed they share the same O_NDELAY, too. */ - if ((fd = open("/dev/tty", O_RDWR|O_CLOEXEC|O_NONBLOCK)) >= 0) { + if ((fd = pa_open_cloexec("/dev/tty", O_RDWR|O_NONBLOCK, 0)) >= 0) { io = pa_iochannel_new(m->core->mainloop, fd, fd); pa_log_debug("Managed to open /dev/tty."); } else { diff --git a/src/modules/module-default-device-restore.c b/src/modules/module-default-device-restore.c index 27ae60e5..94f589e9 100644 --- a/src/modules/module-default-device-restore.c +++ b/src/modules/module-default-device-restore.c @@ -60,7 +60,7 @@ static void load(struct userdata *u) { if (u->core->default_sink) pa_log_info("Manually configured default sink, not overwriting."); - else if ((f = fopen(u->sink_filename, "r"))) { + else if ((f = pa_fopen_cloexec(u->sink_filename, "r"))) { char ln[256] = ""; pa_sink *s; @@ -81,7 +81,7 @@ static void load(struct userdata *u) { if (u->core->default_source) pa_log_info("Manually configured default source, not overwriting."); - else if ((f = fopen(u->source_filename, "r"))) { + else if ((f = pa_fopen_cloexec(u->source_filename, "r"))) { char ln[256] = ""; pa_source *s; @@ -108,7 +108,7 @@ static void save(struct userdata *u) { return; if (u->sink_filename) { - if ((f = fopen(u->sink_filename, "w"))) { + if ((f = pa_fopen_cloexec(u->sink_filename, "w"))) { pa_sink *s = pa_namereg_get_default_sink(u->core); fprintf(f, "%s\n", s ? s->name : ""); fclose(f); @@ -117,7 +117,7 @@ static void save(struct userdata *u) { } if (u->source_filename) { - if ((f = fopen(u->source_filename, "w"))) { + if ((f = pa_fopen_cloexec(u->source_filename, "w"))) { pa_source *s = pa_namereg_get_default_source(u->core); fprintf(f, "%s\n", s ? s->name : ""); fclose(f); diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index b1f24e15..1fe8eb8b 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -63,7 +63,7 @@ static int detect_alsa(pa_core *c, int just_one) { FILE *f; int n = 0, n_sink = 0, n_source = 0; - if (!(f = fopen("/proc/asound/devices", "r"))) { + if (!(f = pa_fopen_cloexec("/proc/asound/devices", "r"))) { if (errno != ENOENT) pa_log_error("open(\"/proc/asound/devices\") failed: %s", pa_cstrerror(errno)); @@ -124,9 +124,9 @@ static int detect_oss(pa_core *c, int just_one) { FILE *f; int n = 0, b = 0; - if (!(f = fopen("/dev/sndstat", "r")) && - !(f = fopen("/proc/sndstat", "r")) && - !(f = fopen("/proc/asound/oss/sndstat", "r"))) { + if (!(f = pa_fopen_cloexec("/dev/sndstat", "r")) && + !(f = pa_fopen_cloexec("/proc/sndstat", "r")) && + !(f = pa_fopen_cloexec("/proc/asound/oss/sndstat", "r"))) { if (errno != ENOENT) pa_log_error("failed to open OSS sndstat device: %s", pa_cstrerror(errno)); diff --git a/src/modules/module-match.c b/src/modules/module-match.c index 0bd781d2..b1693f18 100644 --- a/src/modules/module-match.c +++ b/src/modules/module-match.c @@ -85,7 +85,7 @@ static int load_rules(struct userdata *u, const char *filename) { pa_assert(u); if (filename) - f = fopen(fn = pa_xstrdup(filename), "r"); + f = pa_fopen_cloexec(fn = pa_xstrdup(filename), "r"); else f = pa_open_config_file(DEFAULT_MATCH_TABLE_FILE, DEFAULT_MATCH_TABLE_FILE_USER, NULL, &fn); diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index 516bf413..14a9dd3d 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -175,7 +175,7 @@ int pa__init(pa_module*m) { u->fd = -1; u->fd_type = 0; - if ((u->fd = open(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY|O_NOCTTY)) < 0) { + if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) { pa_log("Failed to open evdev device: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 9c169327..10cc3415 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -253,12 +253,11 @@ int pa__init(pa_module*m) { u->filename = pa_runtime_path(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); mkfifo(u->filename, 0666); - if ((u->fd = open(u->filename, O_RDWR|O_NOCTTY)) < 0) { + if ((u->fd = pa_open_cloexec(u->filename, O_RDWR, 0)) < 0) { pa_log("open('%s'): %s", u->filename, pa_cstrerror(errno)); goto fail; } - pa_make_fd_cloexec(u->fd); pa_make_fd_nonblock(u->fd); if (fstat(u->fd, &st) < 0) { diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 49104f8d..de680933 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -238,12 +238,11 @@ int pa__init(pa_module*m) { u->filename = pa_runtime_path(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); mkfifo(u->filename, 0666); - if ((u->fd = open(u->filename, O_RDWR|O_NOCTTY)) < 0) { + if ((u->fd = pa_open_cloexec(u->filename, O_RDWR, 0)) < 0) { pa_log("open('%s'): %s", u->filename, pa_cstrerror(errno)); goto fail; } - pa_make_fd_cloexec(u->fd); pa_make_fd_nonblock(u->fd); if (fstat(u->fd, &st) < 0) { diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c index b0d4db43..955997ba 100644 --- a/src/modules/module-solaris.c +++ b/src/modules/module-solaris.c @@ -327,7 +327,7 @@ static int open_audio_device(struct userdata *u, pa_sample_spec *ss) { pa_assert(u); pa_assert(ss); - if ((u->fd = open(u->device_name, u->mode | O_NONBLOCK)) < 0) { + if ((u->fd = pa_open_cloexec(u->device_name, u->mode | O_NONBLOCK)) < 0) { pa_log_warn("open %s failed (%s)", u->device_name, pa_cstrerror(errno)); return -1; } diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c index 1b1e9c1a..a12f7c93 100644 --- a/src/modules/module-udev-detect.c +++ b/src/modules/module-udev-detect.c @@ -172,7 +172,7 @@ static pa_bool_t is_card_busy(const char *id) { if (status_file) fclose(status_file); - if (!(status_file = fopen(sub_status, "r"))) { + if (!(status_file = pa_fopen_cloexec(sub_status, "r"))) { pa_log_warn("Failed to open %s: %s", sub_status, pa_cstrerror(errno)); continue; } diff --git a/src/modules/oss/oss-util.c b/src/modules/oss/oss-util.c index 5a109ae9..b95023c3 100644 --- a/src/modules/oss/oss-util.c +++ b/src/modules/oss/oss-util.c @@ -55,7 +55,7 @@ int pa_oss_open(const char *device, int *mode, int* pcaps) { pcaps = ∩︀ if (*mode == O_RDWR) { - if ((fd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) >= 0) { + if ((fd = pa_open_cloexec(device, O_RDWR|O_NDELAY, 0)) >= 0) { ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0); if (ioctl(fd, SNDCTL_DSP_GETCAPS, pcaps) < 0) { @@ -71,14 +71,14 @@ int pa_oss_open(const char *device, int *mode, int* pcaps) { pa_close(fd); } - if ((fd = open(device, (*mode = O_WRONLY)|O_NDELAY|O_NOCTTY)) < 0) { - if ((fd = open(device, (*mode = O_RDONLY)|O_NDELAY|O_NOCTTY)) < 0) { + if ((fd = pa_open_cloexec(device, (*mode = O_WRONLY)|O_NDELAY, 0)) < 0) { + if ((fd = pa_open_cloexec(device, (*mode = O_RDONLY)|O_NDELAY, 0)) < 0) { pa_log("open('%s'): %s", device, pa_cstrerror(errno)); goto fail; } } } else { - if ((fd = open(device, *mode|O_NDELAY|O_NOCTTY)) < 0) { + if ((fd = pa_open_cloexec(device, *mode|O_NDELAY, 0)) < 0) { pa_log("open('%s'): %s", device, pa_cstrerror(errno)); goto fail; } @@ -145,8 +145,6 @@ success: pa_log_debug("capabilities:%s", t); pa_xfree(t); - pa_make_fd_cloexec(fd); - return fd; fail: @@ -351,9 +349,9 @@ int pa_oss_get_hw_description(const char *dev, char *name, size_t l) { if ((n = get_device_number(dev)) < 0) return -1; - if (!(f = fopen("/dev/sndstat", "r")) && - !(f = fopen("/proc/sndstat", "r")) && - !(f = fopen("/proc/asound/oss/sndstat", "r"))) { + if (!(f = pa_fopen_cloexec("/dev/sndstat", "r")) && + !(f = pa_fopen_cloexec("/proc/sndstat", "r")) && + !(f = pa_fopen_cloexec("/proc/asound/oss/sndstat", "r"))) { if (errno != ENOENT) pa_log_warn("failed to open OSS sndstat device: %s", pa_cstrerror(errno)); @@ -403,7 +401,7 @@ int pa_oss_get_hw_description(const char *dev, char *name, size_t l) { static int open_mixer(const char *mixer) { int fd; - if ((fd = open(mixer, O_RDWR|O_NDELAY|O_NOCTTY)) >= 0) + if ((fd = pa_open_cloexec(mixer, O_RDWR|O_NDELAY, 0)) >= 0) return fd; return -1; diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index 1a05f57d..7dbb1efa 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -390,7 +390,7 @@ static int mcast_socket(const struct sockaddr* sa, socklen_t salen) { pa_assert(salen > 0); af = sa->sa_family; - if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) { + if ((fd = pa_socket_cloexec(af, SOCK_DGRAM, 0)) < 0) { pa_log("Failed to create socket: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c index 8e1cfe36..ab815223 100644 --- a/src/modules/rtp/module-rtp-send.c +++ b/src/modules/rtp/module-rtp-send.c @@ -262,7 +262,7 @@ int pa__init(pa_module*m) { goto fail; } - if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) { + if ((fd = pa_socket_cloexec(af, SOCK_DGRAM, 0)) < 0) { pa_log("socket() failed: %s", pa_cstrerror(errno)); goto fail; } @@ -277,7 +277,7 @@ int pa__init(pa_module*m) { #endif } - if ((sap_fd = socket(af, SOCK_DGRAM, 0)) < 0) { + if ((sap_fd = pa_socket_cloexec(af, SOCK_DGRAM, 0)) < 0) { pa_log("socket() failed: %s", pa_cstrerror(errno)); goto fail; } @@ -316,8 +316,6 @@ int pa__init(pa_module*m) { /* If the socket queue is full, let's drop packets */ pa_make_fd_nonblock(fd); pa_make_udp_socket_low_delay(fd); - pa_make_fd_cloexec(fd); - pa_make_fd_cloexec(sap_fd); pa_source_output_new_data_init(&data); pa_proplist_sets(data.proplist, PA_PROP_MEDIA_NAME, "RTP Monitor Stream"); diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index 62c06f6a..3eaca4d9 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -110,7 +110,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) { if (filename) { - if (!(f = fopen(filename, "r"))) { + if (!(f = pa_fopen_cloexec(filename, "r"))) { pa_log(_("Failed to open configuration file '%s': %s"), fn, pa_cstrerror(errno)); goto finish; } diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c index 3dc74398..70c0122c 100644 --- a/src/pulse/mainloop-signal.c +++ b/src/pulse/mainloop-signal.c @@ -124,15 +124,13 @@ int pa_signal_init(pa_mainloop_api *a) { pa_assert(signal_pipe[1] == -1); pa_assert(!io_event); - if (pipe(signal_pipe) < 0) { + if (pa_pipe_cloexec(signal_pipe) < 0) { pa_log("pipe(): %s", pa_cstrerror(errno)); return -1; } pa_make_fd_nonblock(signal_pipe[0]); pa_make_fd_nonblock(signal_pipe[1]); - pa_make_fd_cloexec(signal_pipe[0]); - pa_make_fd_cloexec(signal_pipe[1]); api = a; diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 090ac8c2..6cd089ef 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -482,7 +482,7 @@ pa_mainloop *pa_mainloop_new(void) { m = pa_xnew0(pa_mainloop, 1); - if (pipe(m->wakeup_pipe) < 0) { + if (pa_pipe_cloexec(m->wakeup_pipe) < 0) { pa_log_error("ERROR: cannot create wakeup pipe"); pa_xfree(m); return NULL; @@ -490,8 +490,6 @@ pa_mainloop *pa_mainloop_new(void) { pa_make_fd_nonblock(m->wakeup_pipe[0]); pa_make_fd_nonblock(m->wakeup_pipe[1]); - pa_make_fd_cloexec(m->wakeup_pipe[0]); - pa_make_fd_cloexec(m->wakeup_pipe[1]); m->rebuild_pollfds = TRUE; diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c index 15613e27..d671e367 100644 --- a/src/pulsecore/authkey.c +++ b/src/pulsecore/authkey.c @@ -70,10 +70,6 @@ static int generate(int fd, void *ret_data, size_t length) { #define O_BINARY 0 #endif -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - /* Load an euthorization cookie from file fn and store it in data. If * the cookie file doesn't exist, create it */ static int load(const char *fn, void *data, size_t length) { @@ -86,9 +82,9 @@ static int load(const char *fn, void *data, size_t length) { pa_assert(data); pa_assert(length > 0); - if ((fd = open(fn, O_RDWR|O_CREAT|O_BINARY|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) { + if ((fd = pa_open_cloexec(fn, O_RDWR|O_CREAT|O_BINARY, S_IRUSR|S_IWUSR)) < 0) { - if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY|O_NOCTTY)) < 0) { + if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY)) < 0) { pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } else @@ -204,7 +200,7 @@ int pa_authkey_save(const char *fn, const void *data, size_t length) { if (!(p = normalize_path(fn))) return -2; - if ((fd = open(p, O_RDWR|O_CREAT|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) { + if ((fd = pa_open_cloexec(p, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) { pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index b57919a4..82a44d84 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -1804,7 +1804,7 @@ int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, pa_b if (!fail) fail = &_fail; - if (!(f = fopen(fn, "r"))) { + if (!(f = pa_fopen_cloexec(fn, "r"))) { pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno)); if (!*fail) ret = 0; diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c index dd4a99ee..34b4d6fe 100644 --- a/src/pulsecore/conf-parser.c +++ b/src/pulsecore/conf-parser.c @@ -168,7 +168,7 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void pa_assert(filename); pa_assert(t); - if (!f && !(f = fopen(filename, "r"))) { + if (!f && !(f = pa_fopen_cloexec(filename, "r"))) { if (errno == ENOENT) { pa_log_debug("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno)); r = 0; diff --git a/src/pulsecore/core-rtclock.c b/src/pulsecore/core-rtclock.c index 1420470a..4fe0a47b 100644 --- a/src/pulsecore/core-rtclock.c +++ b/src/pulsecore/core-rtclock.c @@ -33,6 +33,12 @@ #include <sys/prctl.h> #endif +#ifdef OS_IS_DARWIN +#include <CoreServices/CoreServices.h> +#include <mach/mach.h> +#include <mach/mach_time.h> +#endif + #include <pulse/timeval.h> #include <pulsecore/macro.h> #include <pulsecore/core-error.h> @@ -47,7 +53,8 @@ pa_usec_t pa_rtclock_age(const struct timeval *tv) { } struct timeval *pa_rtclock_get(struct timeval *tv) { -#ifdef HAVE_CLOCK_GETTIME + +#if defined(HAVE_CLOCK_GETTIME) struct timespec ts; #ifdef CLOCK_MONOTONIC @@ -59,7 +66,7 @@ struct timeval *pa_rtclock_get(struct timeval *tv) { no_monotonic = TRUE; if (no_monotonic) -#endif +#endif /* CLOCK_MONOTONIC */ pa_assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); pa_assert(tv); @@ -69,7 +76,30 @@ struct timeval *pa_rtclock_get(struct timeval *tv) { return tv; -#else /* HAVE_CLOCK_GETTIME */ +#elif defined(OS_IS_DARWIN) + static mach_timebase_info_data_t tbi; + uint64_t nticks; + uint64_t time_nsec; + + /* Refer Apple ADC QA1398 + Also: http://devworld.apple.com/documentation/Darwin/Conceptual/KernelProgramming/services/services.html + + Note: argument is timespec NOT timeval (timespec uses nsec, timeval uses usec) + */ + + /* try and be a mite efficient - maybe I should keep the N/D as a float !? */ + if (tbi.denom == 0) + mach_timebase_info(&tbi); + + nticks = mach_absolute_time(); + time_nsec = nticks * tbi.numer / tbi.denom; // see above + + tv->tv_sec = time_nsec / PA_NSEC_PER_SEC; + tv->tv_usec = time_nsec / PA_NSEC_PER_USEC; + + return tv; + +#else /* OS_IS_DARWIN */ return pa_gettimeofday(tv); @@ -77,19 +107,30 @@ struct timeval *pa_rtclock_get(struct timeval *tv) { } pa_bool_t pa_rtclock_hrtimer(void) { -#ifdef HAVE_CLOCK_GETTIME + +#if defined(HAVE_CLOCK_GETTIME) struct timespec ts; #ifdef CLOCK_MONOTONIC + if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0) return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC); -#endif +#endif /* CLOCK_MONOTONIC */ pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0); return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC); -#else /* HAVE_CLOCK_GETTIME */ +#elif defined (OS_IS_DARWIN) + mach_timebase_info_data_t tbi; + uint64_t time_nsec; + + mach_timebase_info(&tbi); + /* nsec = nticks * (N/D) - we want 1 tick == resolution !? */ + time_nsec = tbi.numer / tbi.denom; + return time_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC); + +#else /* OS_IS_DARWIN */ return FALSE; #endif @@ -98,6 +139,7 @@ pa_bool_t pa_rtclock_hrtimer(void) { #define TIMER_SLACK_NS (int) ((500 * PA_NSEC_PER_USEC)) void pa_rtclock_hrtimer_enable(void) { + #ifdef PR_SET_TIMERSLACK int slack_ns; diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 27e09cbc..2b0a60a8 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1200,10 +1200,7 @@ int pa_lock_lockfile(const char *fn) { for (;;) { struct stat st; - if ((fd = open(fn, O_CREAT|O_RDWR -#ifdef O_NOCTTY - |O_NOCTTY -#endif + if ((fd = pa_open_cloexec(fn, O_CREAT|O_RDWR #ifdef O_NOFOLLOW |O_NOFOLLOW #endif @@ -1603,7 +1600,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env fn = buf; #endif - if ((f = fopen(fn, "r"))) { + if ((f = pa_fopen_cloexec(fn, "r"))) { if (result) *result = pa_xstrdup(fn); @@ -1637,7 +1634,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env fn = buf; #endif - if ((f = fopen(fn, "r"))) { + if ((f = pa_fopen_cloexec(fn, "r"))) { if (result) *result = pa_xstrdup(fn); @@ -1664,7 +1661,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env global = buf; #endif - if ((f = fopen(global, "r"))) { + if ((f = pa_fopen_cloexec(global, "r"))) { if (result) *result = pa_xstrdup(global); @@ -2563,7 +2560,7 @@ char *pa_machine_id(void) { * since it fits perfectly our needs and is not as volatile as the * hostname which might be set from dhcp. */ - if ((f = fopen(PA_MACHINE_ID, "r"))) { + if ((f = pa_fopen_cloexec(PA_MACHINE_ID, "r"))) { char ln[34] = "", *r; r = fgets(ln, sizeof(ln)-1, f); @@ -2889,3 +2886,132 @@ const char *pa_get_temp_dir(void) { return "/tmp"; } + +int pa_open_cloexec(const char *fn, int flags, mode_t mode) { + int fd; + +#ifdef O_NOCTTY + flags |= O_NOCTTY; +#endif + +#ifdef O_CLOEXEC + if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0) + goto finish; + + if (errno != EINVAL) + return fd; +#endif + + if ((fd = open(fn, flags, mode)) < 0) + return fd; + +finish: + /* Some implementations might simply ignore O_CLOEXEC if it is not + * understood, make sure FD_CLOEXEC is enabled anyway */ + + pa_make_fd_cloexec(fd); + return fd; +} + +int pa_socket_cloexec(int domain, int type, int protocol) { + int fd; + +#ifdef SOCK_CLOEXEC + if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0) + goto finish; + + if (errno != EINVAL) + return fd; +#endif + + if ((fd = socket(domain, type, protocol)) < 0) + return fd; + +finish: + /* Some implementations might simply ignore SOCK_CLOEXEC if it is + * not understood, make sure FD_CLOEXEC is enabled anyway */ + + pa_make_fd_cloexec(fd); + return fd; +} + +int pa_pipe_cloexec(int pipefd[2]) { + int r; + +#ifdef HAVE_PIPE2 + if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0) + goto finish; + + if (errno != EINVAL && errno != ENOSYS) + return r; +#endif + + if ((r = pipe(pipefd)) < 0) + return r; + +finish: + pa_make_fd_cloexec(pipefd[0]); + pa_make_fd_cloexec(pipefd[1]); + + return 0; +} + +int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + int fd; + +#ifdef HAVE_ACCEPT4 + if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0) + goto finish; + + if (errno != EINVAL && errno != ENOSYS) + return fd; +#endif + + if ((fd = accept(sockfd, addr, addrlen)) < 0) + return fd; + +finish: + pa_make_fd_cloexec(fd); + return fd; +} + +FILE* pa_fopen_cloexec(const char *path, const char *mode) { + FILE *f; + char *m; + + m = pa_sprintf_malloc("%se", mode); + + errno = 0; + if ((f = fopen(path, m))) { + pa_xfree(m); + goto finish; + } + + pa_xfree(m); + + if (errno != EINVAL) + return NULL; + + if (!(f = fopen(path, mode))) + return NULL; + +finish: + pa_make_fd_cloexec(fileno(f)); + return f; +} + +void pa_nullify_stdfds(void) { + +#ifndef OS_IS_WIN32 + pa_close(STDIN_FILENO); + pa_close(STDOUT_FILENO); + pa_close(STDERR_FILENO); + + pa_assert_se(open("/dev/null", O_RDONLY) == STDIN_FILENO); + pa_assert_se(open("/dev/null", O_WRONLY) == STDOUT_FILENO); + pa_assert_se(open("/dev/null", O_WRONLY) == STDERR_FILENO); +#else + FreeConsole(); +#endif + +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 9986b14a..9c9cf78a 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -28,6 +28,7 @@ #include <stdarg.h> #include <stdio.h> #include <string.h> +#include <sys/socket.h> #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> @@ -258,4 +259,12 @@ pa_bool_t pa_run_from_build_tree(void); const char *pa_get_temp_dir(void); +int pa_open_cloexec(const char *fn, int flags, mode_t mode); +int pa_socket_cloexec(int domain, int type, int protocol); +int pa_pipe_cloexec(int pipefd[2]); +int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +FILE* pa_fopen_cloexec(const char *path, const char *mode); + +void pa_nullify_stdfds(void); + #endif diff --git a/src/pulsecore/cpu-arm.c b/src/pulsecore/cpu-arm.c index 453b7848..6bb2eadd 100644 --- a/src/pulsecore/cpu-arm.c +++ b/src/pulsecore/cpu-arm.c @@ -62,7 +62,7 @@ static char *get_cpuinfo(void) { cpuinfo = pa_xmalloc(MAX_BUFFER); - if ((fd = open("/proc/cpuinfo", O_RDONLY)) < 0) { + if ((fd = pa_open_cloexec("/proc/cpuinfo", O_RDONLY, 0)) < 0) { pa_xfree(cpuinfo); return NULL; } diff --git a/src/pulsecore/database-simple.c b/src/pulsecore/database-simple.c index 1f4caf71..754930db 100644 --- a/src/pulsecore/database-simple.c +++ b/src/pulsecore/database-simple.c @@ -237,7 +237,7 @@ pa_database* pa_database_open(const char *fn, pa_bool_t for_write) { path = pa_sprintf_malloc("%s."CANONICAL_HOST".simple", fn); errno = 0; - f = fopen(path, "r"); + f = pa_fopen_cloexec(path, "r"); if (f || errno == ENOENT) { /* file not found is ok */ db = pa_xnew0(simple_data, 1); @@ -480,7 +480,7 @@ int pa_database_sync(pa_database *database) { errno = 0; - f = fopen(db->tmp_filename, "w"); + f = pa_fopen_cloexec(db->tmp_filename, "w"); if (!f) goto fail; diff --git a/src/pulsecore/database-tdb.c b/src/pulsecore/database-tdb.c index b79d2837..4e782d65 100644 --- a/src/pulsecore/database-tdb.c +++ b/src/pulsecore/database-tdb.c @@ -66,6 +66,39 @@ void pa_datum_free(pa_datum *d) { pa_zero(d); } +static struct tdb_context *tdb_open_cloexec( + const char *name, + int hash_size, + int tdb_flags, + int open_flags, + mode_t mode) { + + /* Mimics pa_open_cloexec() */ + + struct tdb_context *c; + +#ifdef O_NOCTTY + open_flags |= O_NOCTTY; +#endif + +#ifdef O_CLOEXEC + errno = 0; + if ((c = tdb_open(name, hash_size, tdb_flags, open_flags | O_CLOEXEC, mode))) + goto finish; + + if (errno != EINVAL) + return NULL; +#endif + + errno = 0; + if (!(c = tdb_open(name, hash_size, tdb_flags, open_flags, mode))) + return NULL; + +finish: + pa_make_fd_cloexec(tdb_fd(c)); + return c; +} + pa_database* pa_database_open(const char *fn, pa_bool_t for_write) { struct tdb_context *c; char *path; @@ -73,15 +106,7 @@ pa_database* pa_database_open(const char *fn, pa_bool_t for_write) { pa_assert(fn); path = pa_sprintf_malloc("%s.tdb", fn); - errno = 0; - c = tdb_open(path, 0, TDB_NOSYNC|TDB_NOLOCK, - (for_write ? O_RDWR|O_CREAT : O_RDONLY)|O_NOCTTY -#ifdef O_CLOEXEC - |O_CLOEXEC -#endif - , 0644); - - if (c) + if ((c = tdb_open_cloexec(path, 0, TDB_NOSYNC|TDB_NOLOCK, (for_write ? O_RDWR|O_CREAT : O_RDONLY), 0644))) pa_log_debug("Opened TDB database '%s'", path); pa_xfree(path); diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index 380f34f5..ea14e8a7 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -62,19 +62,15 @@ pa_fdsem *pa_fdsem_new(void) { f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data))); #ifdef HAVE_SYS_EVENTFD_H - if ((f->efd = eventfd(0, 0)) >= 0) { - pa_make_fd_cloexec(f->efd); + if ((f->efd = eventfd(0, EFD_CLOEXEC)) >= 0) f->fds[0] = f->fds[1] = -1; - } else + else #endif { - if (pipe(f->fds) < 0) { + if (pa_pipe_cloexec(f->fds) < 0) { pa_xfree(f); return NULL; } - - pa_make_fd_cloexec(f->fds[0]); - pa_make_fd_cloexec(f->fds[1]); } f->data = (pa_fdsem_data*) ((uint8_t*) f + PA_ALIGN(sizeof(pa_fdsem))); @@ -114,12 +110,11 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) { f = pa_xnew(pa_fdsem, 1); - if ((f->efd = eventfd(0, 0)) < 0) { + if ((f->efd = eventfd(0, EFD_CLOEXEC)) < 0) { pa_xfree(f); return NULL; } - pa_make_fd_cloexec(f->efd); f->fds[0] = f->fds[1] = -1; f->data = data; diff --git a/src/pulsecore/lock-autospawn.c b/src/pulsecore/lock-autospawn.c index c0df7938..65e35634 100644 --- a/src/pulsecore/lock-autospawn.c +++ b/src/pulsecore/lock-autospawn.c @@ -87,12 +87,9 @@ static int ref(void) { pa_assert(pipe_fd[0] < 0); pa_assert(pipe_fd[1] < 0); - if (pipe(pipe_fd) < 0) + if (pa_pipe_cloexec(pipe_fd) < 0) return -1; - pa_make_fd_cloexec(pipe_fd[0]); - pa_make_fd_cloexec(pipe_fd[1]); - pa_make_fd_nonblock(pipe_fd[1]); pa_make_fd_nonblock(pipe_fd[0]); diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index 996946c2..213e7983 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -88,10 +88,7 @@ static int open_pid_file(const char *fn, int mode) { for (;;) { struct stat st; - if ((fd = open(fn, mode -#ifdef O_NOCTTY - |O_NOCTTY -#endif + if ((fd = pa_open_cloexec(fn, mode #ifdef O_NOFOLLOW |O_NOFOLLOW #endif @@ -146,7 +143,7 @@ static int proc_name_ours(pid_t pid, const char *procname) { pa_snprintf(bn, sizeof(bn), "/proc/%lu/stat", (unsigned long) pid); - if (!(f = fopen(bn, "r"))) { + if (!(f = pa_fopen_cloexec(bn, "r"))) { pa_log_info("Failed to open %s: %s", bn, pa_cstrerror(errno)); return -1; } else { diff --git a/src/pulsecore/random.c b/src/pulsecore/random.c index 518c281a..a87d24e3 100644 --- a/src/pulsecore/random.c +++ b/src/pulsecore/random.c @@ -62,11 +62,7 @@ static int random_proper(void *ret_data, size_t length) { while (*device) { ret = 0; - if ((fd = open(*device, O_RDONLY -#ifdef O_NOCTTY - | O_NOCTTY -#endif - )) >= 0) { + if ((fd = pa_open_cloexec(*device, O_RDONLY, 0)) >= 0) { if ((r = pa_loop_read(fd, ret_data, length, NULL)) < 0 || (size_t) r != length) ret = -1; diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index a26dc876..74600dec 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -1007,7 +1007,7 @@ void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn) { /* Only for debugging purposes */ - f = fopen(fn, "a"); + f = pa_fopen_cloexec(fn, "a"); if (!f) { pa_log_warn("Failed to open '%s': %s", fn, pa_cstrerror(errno)); diff --git a/src/pulsecore/semaphore-osx.c b/src/pulsecore/semaphore-osx.c new file mode 100644 index 00000000..73f43559 --- /dev/null +++ b/src/pulsecore/semaphore-osx.c @@ -0,0 +1,63 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Kim Lester <kim@dfusion.com.au> + + 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.1 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 + +#include <Multiprocessing.h> + +#include <pulse/xmalloc.h> +#include <pulsecore/macro.h> + +#include "semaphore.h" + +struct pa_semaphore +{ + MPSemaphoreID sema; +}; + +pa_semaphore* pa_semaphore_new(unsigned int value) { + /* NOTE: Can't assume boolean - ie value = 0,1, so use UINT_MAX (boolean more efficient ?) */ + pa_semaphore *s; + + s = pa_xnew(pa_semaphore, 1); + pa_assert_se(MPCreateSemaphore(UINT_MAX, value, &s->sema) == 0); + + return s; +} + +void pa_semaphore_free(pa_semaphore *s) { + pa_assert(s); + pa_assert_se(MPDeleteSemaphore(s->sema) == 0); + pa_xfree(s); +} + +void pa_semaphore_post(pa_semaphore *s) { + pa_assert(s); + pa_assert_se(MPSignalSemaphore(s->sema) == 0); +} + +void pa_semaphore_wait(pa_semaphore *s) { + pa_assert(s); + /* should probably check return value (-ve is error), noErr is ok. */ + pa_assert_se(MPWaitOnSemaphore(s->sema, kDurationForever) == 0); +} diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index bda92fcc..971436d3 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -926,18 +926,16 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume); - if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&volume)) { - if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) { - pa_memblock_unref(result->memblock); - pa_silence_memchunk_get(&s->core->silence_cache, - s->core->mempool, - result, - &s->sample_spec, - result->length); - } else { - pa_memchunk_make_writable(result, 0); - pa_volume_memchunk(result, &s->sample_spec, &volume); - } + if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) { + pa_memblock_unref(result->memblock); + pa_silence_memchunk_get(&s->core->silence_cache, + s->core->mempool, + result, + &s->sample_spec, + result->length); + } else if (!pa_cvolume_is_norm(&volume)) { + pa_memchunk_make_writable(result, 0); + pa_volume_memchunk(result, &s->sample_spec, &volume); } } else { void *ptr; @@ -1342,7 +1340,7 @@ static void propagate_reference_volume(pa_sink *s) { void pa_sink_set_volume( pa_sink *s, const pa_cvolume *volume, - pa_bool_t sendmsg, + pa_bool_t send_msg, pa_bool_t save) { pa_cvolume old_reference_volume; @@ -1411,7 +1409,7 @@ void pa_sink_set_volume( s->soft_volume = s->real_volume; /* This tells the sink that soft and/or virtual volume changed */ - if (sendmsg) + if (send_msg) pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0); if (reference_changed) diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index b9d69505..ef3c29ee 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -257,13 +257,11 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size c->local = pa_socket_address_is_local(sa); - if ((c->fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) { + if ((c->fd = pa_socket_cloexec(sa->sa_family, SOCK_STREAM, 0)) < 0) { pa_log("socket(): %s", pa_cstrerror(errno)); return -1; } - pa_make_fd_cloexec(c->fd); - #ifdef HAVE_IPV6 if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6) #else diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c index e660700c..5d55de3e 100644 --- a/src/pulsecore/socket-server.c +++ b/src/pulsecore/socket-server.c @@ -104,13 +104,11 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_ev pa_socket_server_ref(s); - if ((nfd = accept(fd, NULL, NULL)) < 0) { + if ((nfd = pa_accept_cloexec(fd, NULL, NULL)) < 0) { pa_log("accept(): %s", pa_cstrerror(errno)); goto finish; } - pa_make_fd_cloexec(nfd); - if (!s->on_connection) { pa_close(nfd); goto finish; @@ -186,13 +184,11 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file pa_assert(m); pa_assert(filename); - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) { pa_log("socket(): %s", pa_cstrerror(errno)); goto fail; } - pa_make_fd_cloexec(fd); - memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_UNIX; pa_strlcpy(sa.sun_path, filename, sizeof(sa.sun_path)); @@ -246,13 +242,11 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address pa_assert(m); pa_assert(port); - if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + if ((fd = pa_socket_cloexec(PF_INET, SOCK_STREAM, 0)) < 0) { pa_log("socket(PF_INET): %s", pa_cstrerror(errno)); goto fail; } - pa_make_fd_cloexec(fd); - #ifdef SO_REUSEADDR if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) pa_log("setsockopt(): %s", pa_cstrerror(errno)); @@ -299,13 +293,11 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad pa_assert(m); pa_assert(port > 0); - if ((fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0) { + if ((fd = pa_socket_cloexec(PF_INET6, SOCK_STREAM, 0)) < 0) { pa_log("socket(PF_INET6): %s", pa_cstrerror(errno)); goto fail; } - pa_make_fd_cloexec(fd); - #ifdef IPV6_V6ONLY on = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) diff --git a/src/pulsecore/socket-util.c b/src/pulsecore/socket-util.c index 5fd5dd67..2cc9882a 100644 --- a/src/pulsecore/socket-util.c +++ b/src/pulsecore/socket-util.c @@ -85,12 +85,11 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { #ifndef OS_IS_WIN32 pa_assert_se(fstat(fd, &st) == 0); -#endif -#ifndef OS_IS_WIN32 if (S_ISSOCK(st.st_mode)) { #endif union { + struct sockaddr_storage storage; struct sockaddr sa; struct sockaddr_in in; #ifdef HAVE_IPV6 @@ -152,7 +151,7 @@ void pa_make_socket_low_delay(int fd) { pa_assert(fd >= 0); priority = 6; - if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < 0) pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno)); #endif } @@ -166,9 +165,9 @@ void pa_make_tcp_socket_low_delay(int fd) { { int on = 1; #if defined(SOL_TCP) - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) + if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) #else - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) #endif pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno)); } @@ -178,9 +177,9 @@ void pa_make_tcp_socket_low_delay(int fd) { { int tos = IPTOS_LOWDELAY; #ifdef SOL_IP - if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) + if (setsockopt(fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0) #else - if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) #endif pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno)); } @@ -196,9 +195,9 @@ void pa_make_udp_socket_low_delay(int fd) { { int tos = IPTOS_LOWDELAY; #ifdef SOL_IP - if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) + if (setsockopt(fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0) #else - if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) #endif pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno)); } @@ -206,11 +205,11 @@ void pa_make_udp_socket_low_delay(int fd) { } int pa_socket_set_rcvbuf(int fd, size_t l) { - int bufsz = (int)l; + int bufsz = (int) l; pa_assert(fd >= 0); - if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&bufsz, sizeof(bufsz)) < 0) { + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsz, sizeof(bufsz)) < 0) { pa_log_warn("SO_RCVBUF: %s", pa_cstrerror(errno)); return -1; } @@ -219,12 +218,12 @@ int pa_socket_set_rcvbuf(int fd, size_t l) { } int pa_socket_set_sndbuf(int fd, size_t l) { - int bufsz = (int)l; + int bufsz = (int) l; pa_assert(fd >= 0); - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&bufsz, sizeof(bufsz)) < 0) { - pa_log("SO_SNDBUF: %s", pa_cstrerror(errno)); + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bufsz, sizeof(bufsz)) < 0) { + pa_log_warn("SO_SNDBUF: %s", pa_cstrerror(errno)); return -1; } @@ -239,7 +238,7 @@ int pa_unix_socket_is_stale(const char *fn) { pa_assert(fn); - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) { pa_log("socket(): %s", pa_cstrerror(errno)); goto finish; } @@ -315,6 +314,7 @@ pa_bool_t pa_socket_address_is_local(const struct sockaddr *sa) { pa_bool_t pa_socket_is_local(int fd) { union { + struct sockaddr_storage storage; struct sockaddr sa; struct sockaddr_in in; #ifdef HAVE_IPV6 diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 16de4923..53674ba1 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -252,11 +252,7 @@ int pa_play_file( u->readf_function = NULL; u->memblockq = NULL; - if ((fd = open(fname, O_RDONLY -#ifdef O_NOCTTY - |O_NOCTTY -#endif - )) < 0) { + if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) { pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno)); goto fail; } diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index 2d9b76ad..d8c10b1e 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -62,11 +62,7 @@ int pa_sound_file_load( pa_memchunk_reset(chunk); - if ((fd = open(fname, O_RDONLY -#ifdef O_NOCTTY - |O_NOCTTY -#endif - )) < 0) { + if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) { pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno)); goto finish; } diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c index 5bf72ed0..a011789c 100644 --- a/src/pulsecore/svolume_mmx.c +++ b/src/pulsecore/svolume_mmx.c @@ -62,7 +62,9 @@ " movq "#s", %%mm5 \n\t" \ " pmulhw "#v", "#s" \n\t" /* .. | 0 | vl*p0 | */ \ " paddw %%mm4, "#s" \n\t" /* .. | 0 | vl*p0 | + sign correct */ \ + " pslld $16, "#s" \n\t" /* .. | vl*p0 | 0 | */ \ " psrld $16, "#v" \n\t" /* .. | 0 | vh | */ \ + " psrad $16, "#s" \n\t" /* .. | vl*p0 | sign extend */ \ " pmaddwd %%mm5, "#v" \n\t" /* .. | p0 * vh | */ \ " paddd "#s", "#v" \n\t" /* .. | p0 * v0 | */ \ " packssdw "#v", "#v" \n\t" /* .. | p1*v1 | p0*v0 | */ @@ -257,11 +259,14 @@ static void run_test (void) { printf ("checking MMX %zd\n", sizeof (samples)); pa_random (samples, sizeof (samples)); + /* for (i = 0; i < SAMPLES; i++) + samples[i] = -1; */ memcpy (samples_ref, samples, sizeof (samples)); memcpy (samples_orig, samples, sizeof (samples)); for (i = 0; i < CHANNELS; i++) volumes[i] = rand() >> 1; + /* volumes[i] = 0x0000ffff; */ for (padding = 0; padding < PADDING; padding++, i++) volumes[i] = volumes[padding]; @@ -269,7 +274,7 @@ static void run_test (void) { pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples)); for (i = 0; i < SAMPLES; i++) { if (samples[i] != samples_ref[i]) { - printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], + printf ("%d: %04x != %04x (%04x * %08x)\n", i, samples[i], samples_ref[i], samples_orig[i], volumes[i % CHANNELS]); } } diff --git a/src/pulsecore/x11prop.c b/src/pulsecore/x11prop.c index 873a76e7..dc8ec294 100644 --- a/src/pulsecore/x11prop.c +++ b/src/pulsecore/x11prop.c @@ -32,12 +32,12 @@ void pa_x11_set_prop(Display *d, const char *name, const char *data) { Atom a = XInternAtom(d, name, False); - XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, (int) (strlen(data)+1)); + XChangeProperty(d, DefaultRootWindow(d), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, (int) (strlen(data)+1)); } void pa_x11_del_prop(Display *d, const char *name) { Atom a = XInternAtom(d, name, False); - XDeleteProperty(d, RootWindow(d, 0), a); + XDeleteProperty(d, DefaultRootWindow(d), a); } char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) { @@ -47,13 +47,21 @@ char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) { unsigned long nbytes_after; unsigned char *prop = NULL; char *ret = NULL; + int window_ret; Atom a = XInternAtom(d, name, False); - if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success) - goto finish; - if (actual_type != XA_STRING) - goto finish; + window_ret = XGetWindowProperty(d, DefaultRootWindow(d), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop); + + if (window_ret != Success || actual_type != XA_STRING) { + if (DefaultScreen(d) != 0) { + window_ret = XGetWindowProperty(d, RootWindow(d, 0), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop); + + if (window_ret != Success || actual_type != XA_STRING) + goto finish; + } else + goto finish; + } memcpy(p, prop, nitems); p[nitems] = 0; diff --git a/src/utils/pacat.c b/src/utils/pacat.c index 5f29ba39..d348c16a 100644 --- a/src/utils/pacat.c +++ b/src/utils/pacat.c @@ -906,7 +906,7 @@ int main(int argc, char *argv[]) { filename = argv[optind]; - if ((fd = open(argv[optind], mode == PLAYBACK ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) { + if ((fd = pa_open_cloexec(argv[optind], mode == PLAYBACK ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) { pa_log(_("open(): %s"), strerror(errno)); goto quit; } diff --git a/src/utils/pacmd.c b/src/utils/pacmd.c index 5ef57e3b..ef58e9ce 100644 --- a/src/utils/pacmd.c +++ b/src/utils/pacmd.c @@ -70,7 +70,7 @@ int main(int argc, char*argv[]) { goto fail; } - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) { pa_log(_("socket(PF_UNIX, SOCK_STREAM, 0): %s"), strerror(errno)); goto fail; } |