mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
Merge branch 'master' of git://0pointer.de/pulseaudio
This commit is contained in:
commit
c4e276edbd
60 changed files with 565 additions and 202 deletions
6
PROTOCOL
6
PROTOCOL
|
|
@ -188,3 +188,9 @@ new messages:
|
|||
|
||||
PA_COMMAND_SET_SINK_PORT
|
||||
PA_COMMAND_SET_SOURCE_PORT
|
||||
|
||||
## v17, implemented by >= 0.9.20
|
||||
|
||||
new flag at end of CREATE_PLAYBACK_STREAM:
|
||||
|
||||
bool relative_volume
|
||||
|
|
|
|||
32
configure.ac
32
configure.ac
|
|
@ -40,7 +40,7 @@ AC_SUBST(PA_MAJORMINORMICRO, pa_major.pa_minor.pa_micro)
|
|||
AC_SUBST(PACKAGE_URL, [http://pulseaudio.org/])
|
||||
|
||||
AC_SUBST(PA_API_VERSION, 12)
|
||||
AC_SUBST(PA_PROTOCOL_VERSION, 16)
|
||||
AC_SUBST(PA_PROTOCOL_VERSION, 17)
|
||||
|
||||
# The stable ABI for client applications, for the version info x:y:z
|
||||
# always will hold y=z
|
||||
|
|
@ -445,7 +445,7 @@ AC_CHECK_FUNCS_ONCE([lstat])
|
|||
|
||||
# Non-standard
|
||||
|
||||
AC_CHECK_FUNCS_ONCE([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str strtof_l])
|
||||
AC_CHECK_FUNCS_ONCE([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str strtof_l pipe2 accept4])
|
||||
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
|
|
@ -742,6 +742,28 @@ AC_SUBST(HAVE_OSS)
|
|||
AM_CONDITIONAL([HAVE_OSS_OUTPUT], [test "x$HAVE_OSS" = x1 && test "x${oss_output}" != "xno"])
|
||||
AM_CONDITIONAL([HAVE_OSS_WRAPPER], [test "x$HAVE_OSS" = x1 && test "x${oss_wrapper}" != "xno"])
|
||||
|
||||
#### CoreAudio support (optional) ####
|
||||
|
||||
AC_ARG_ENABLE([coreaudio-output],
|
||||
AS_HELP_STRING([--disable-coreaudio-output],[Disable optional CoreAudio output support]),
|
||||
[
|
||||
case "${enableval}" in
|
||||
yes) coreaudio_enabled=yes ;;
|
||||
no) coreaudio_enabled=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --disable-coreaudio-output) ;;
|
||||
esac
|
||||
],
|
||||
[coreaudio_enabled=auto])
|
||||
|
||||
if test "x${coreaudio_enabled}" != xno ; then
|
||||
AC_CHECK_HEADERS([CoreAudio/CoreAudio.h], HAVE_COREAUDIO=1)
|
||||
else
|
||||
HAVE_COREAUDIO=0
|
||||
fi
|
||||
|
||||
AC_SUBST(HAVE_COREAUDIO)
|
||||
AM_CONDITIONAL([HAVE_COREAUDIO], [test "x$HAVE_COREAUDIO" = x1 && test "x${coreaudio_enabled}" != "xno"])
|
||||
|
||||
#### ALSA support (optional) ####
|
||||
|
||||
AC_ARG_ENABLE([alsa],
|
||||
|
|
@ -1423,6 +1445,11 @@ if test "x$HAVE_OSS" = "x1" ; then
|
|||
fi
|
||||
fi
|
||||
|
||||
ENABLE_COREAUDIO=no
|
||||
if test "x$HAVE_COREAUDIO" = "x1" ; then
|
||||
ENABLE_COREAUDIO=yes
|
||||
fi
|
||||
|
||||
ENABLE_ALSA=no
|
||||
if test "x$HAVE_ALSA" = "x1" ; then
|
||||
ENABLE_ALSA=yes
|
||||
|
|
@ -1548,6 +1575,7 @@ echo "
|
|||
Have X11: ${ENABLE_X11}
|
||||
Enable OSS Output: ${ENABLE_OSS_OUTPUT}
|
||||
Enable OSS Wrapper: ${ENABLE_OSS_WRAPPER}
|
||||
Enable CoreAudio: ${ENABLE_COREAUDIO}
|
||||
Enable Alsa: ${ENABLE_ALSA}
|
||||
Enable Solaris: ${ENABLE_SOLARIS}
|
||||
Enable GLib 2.0: ${ENABLE_GLIB20}
|
||||
|
|
|
|||
1
src/.gitignore
vendored
1
src/.gitignore
vendored
|
|
@ -63,4 +63,5 @@ thread-test
|
|||
utf8-test
|
||||
voltest
|
||||
start-pulseaudio-x11
|
||||
start-pulseaudio-kde
|
||||
vector-test
|
||||
|
|
|
|||
1
src/daemon/.gitignore
vendored
1
src/daemon/.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
org.pulseaudio.policy
|
||||
pulseaudio.desktop
|
||||
pulseaudio-kde.desktop
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()?");
|
||||
|
||||
pa_xfree(canonical_rp);
|
||||
|
||||
} else
|
||||
pa_log_warn("Couldn't read /proc/self/exe, cannot self execute. Running in a chroot()?");
|
||||
|
||||
pa_xfree(canonical_rp);
|
||||
pa_log_warn("Couldn't canonicalize binary path, cannot self execute.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ pa_context_get_source_info_list;
|
|||
pa_context_get_source_output_info;
|
||||
pa_context_get_source_output_info_list;
|
||||
pa_context_get_state;
|
||||
pa_context_get_tile_size;
|
||||
pa_context_is_local;
|
||||
pa_context_is_pending;
|
||||
pa_context_kill_client;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1488,6 +1488,7 @@ pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_even
|
|||
struct timeval tv;
|
||||
|
||||
pa_assert(c);
|
||||
pa_assert(PA_REFCNT_VALUE(c) >= 1);
|
||||
pa_assert(c->mainloop);
|
||||
|
||||
if (usec == PA_USEC_INVALID)
|
||||
|
|
@ -1502,8 +1503,10 @@ void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec)
|
|||
struct timeval tv;
|
||||
|
||||
pa_assert(c);
|
||||
pa_assert(PA_REFCNT_VALUE(c) >= 1);
|
||||
pa_assert(c->mainloop);
|
||||
|
||||
|
||||
if (usec == PA_USEC_INVALID)
|
||||
c->mainloop->time_restart(e, NULL);
|
||||
else {
|
||||
|
|
@ -1511,3 +1514,17 @@ void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec)
|
|||
c->mainloop->time_restart(e, &tv);
|
||||
}
|
||||
}
|
||||
|
||||
size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss) {
|
||||
size_t fs, mbs;
|
||||
|
||||
pa_assert(c);
|
||||
pa_assert(PA_REFCNT_VALUE(c) >= 1);
|
||||
|
||||
PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, (size_t) -1);
|
||||
PA_CHECK_VALIDITY_RETURN_ANY(c, !ss || pa_sample_spec_valid(ss), PA_ERR_INVALID, (size_t) -1);
|
||||
|
||||
fs = ss ? pa_frame_size(ss) : 1;
|
||||
mbs = PA_ROUND_DOWN(pa_mempool_block_size_max(c->mempool), fs);
|
||||
return PA_MAX(mbs, fs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,12 +255,28 @@ pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[]
|
|||
uint32_t pa_context_get_index(pa_context *s);
|
||||
|
||||
/** Create a new timer event source for the specified time (wrapper
|
||||
for mainloop->time_new). \since 0.9.16 */
|
||||
* for mainloop->time_new). \since 0.9.16 */
|
||||
pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata);
|
||||
/** Restart a running or expired timer event source (wrapper
|
||||
for mainloop->time_restart). \since 0.9.16 */
|
||||
|
||||
/** Restart a running or expired timer event source (wrapper for
|
||||
* mainloop->time_restart). \since 0.9.16 */
|
||||
void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec);
|
||||
|
||||
/* Return the optimal block size for passing around audio buffers. It
|
||||
* is recommended to allocate buffers of the size returned here when
|
||||
* writing audio data to playback streams, if the latency constraints
|
||||
* permit this. It is not recommended writing larger blocks than this
|
||||
* because usually they will then be split up internally into chunks
|
||||
* of this size. It is not recommended writing smaller blocks than
|
||||
* this (unless required due to latency demands) because this
|
||||
* increases CPU usage. If ss is NULL you will be returned the
|
||||
* byte-exact tile size. If you pass a valid ss, then the tile size
|
||||
* will be rounded down to multiple of the frame size. This is
|
||||
* supposed to be used in a construct such as
|
||||
* pa_context_get_tile_size(pa_stream_get_context(s),
|
||||
* pa_stream_get_sample_spec(ss)); \since 0.9.20 */
|
||||
size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss);
|
||||
|
||||
PA_C_DECL_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -276,11 +276,18 @@ typedef enum pa_stream_flags {
|
|||
* whether to create the stream in muted or in unmuted
|
||||
* state. \since 0.9.15 */
|
||||
|
||||
PA_STREAM_FAIL_ON_SUSPEND = 0x20000U
|
||||
PA_STREAM_FAIL_ON_SUSPEND = 0x20000U,
|
||||
/**< If the sink/source this stream is connected to is suspended
|
||||
* during the creation of this stream, cause it to fail. If the
|
||||
* sink/source is being suspended during creation of this stream,
|
||||
* make sure this stream is terminated. \since 0.9.15 */
|
||||
|
||||
PA_STREAM_RELATIVE_VOLUME = 0x40000U,
|
||||
/**< If a volume is passed when this stream is created, consider
|
||||
* it relative to the sink's current volume, never as absolute
|
||||
* device volume. If this is not specified the volume will be
|
||||
* consider absolute when the sink is in flat volume mode,
|
||||
* relative otherwise. \since 0.9.20 */
|
||||
} pa_stream_flags_t;
|
||||
|
||||
/** \cond fulldocs */
|
||||
|
|
@ -307,6 +314,7 @@ typedef enum pa_stream_flags {
|
|||
#define PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND
|
||||
#define PA_STREAM_START_UNMUTED PA_STREAM_START_UNMUTED
|
||||
#define PA_STREAM_FAIL_ON_SUSPEND PA_STREAM_FAIL_ON_SUSPEND
|
||||
#define PA_STREAM_RELATIVE_VOLUME PA_STREAM_RELATIVE_VOLUME
|
||||
|
||||
/** \endcond */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1025,7 +1025,8 @@ static int create_stream(
|
|||
PA_STREAM_EARLY_REQUESTS|
|
||||
PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND|
|
||||
PA_STREAM_START_UNMUTED|
|
||||
PA_STREAM_FAIL_ON_SUSPEND)), PA_ERR_INVALID);
|
||||
PA_STREAM_FAIL_ON_SUSPEND|
|
||||
PA_STREAM_RELATIVE_VOLUME)), PA_ERR_INVALID);
|
||||
|
||||
PA_CHECK_VALIDITY(s->context, s->context->version >= 12 || !(flags & PA_STREAM_VARIABLE_RATE), PA_ERR_NOTSUPPORTED);
|
||||
PA_CHECK_VALIDITY(s->context, s->context->version >= 13 || !(flags & PA_STREAM_PEAK_DETECT), PA_ERR_NOTSUPPORTED);
|
||||
|
|
@ -1158,6 +1159,13 @@ static int create_stream(
|
|||
pa_tagstruct_put_boolean(t, flags & PA_STREAM_FAIL_ON_SUSPEND);
|
||||
}
|
||||
|
||||
if (s->context->version >= 17) {
|
||||
|
||||
if (s->direction == PA_STREAM_PLAYBACK)
|
||||
pa_tagstruct_put_boolean(t, flags & PA_STREAM_RELATIVE_VOLUME);
|
||||
|
||||
}
|
||||
|
||||
pa_pstream_send_tagstruct(s->context->pstream, t);
|
||||
pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -401,7 +401,22 @@ int pa_stream_is_suspended(pa_stream *s);
|
|||
* not, and negative on error. \since 0.9.11 */
|
||||
int pa_stream_is_corked(pa_stream *s);
|
||||
|
||||
/** Connect the stream to a sink */
|
||||
/** Connect the stream to a sink. It is strongly recommended to pass
|
||||
* NULL in both dev and volume and not to set either
|
||||
* PA_STREAM_START_MUTED nor PA_STREAM_START_UNMUTED -- unless these
|
||||
* options are directly dependant on user input or configuration. If
|
||||
* you follow this rule then the sound server will have the full
|
||||
* flexibility to choose the device, volume and mute status
|
||||
* automatically, based on server-side policies, heuristics and stored
|
||||
* information from previous uses. Also the server may choose to
|
||||
* reconfigure audio devices to make other sinks/sources or
|
||||
* capabilities available to be able to accept the stream. Before
|
||||
* 0.9.20 it was not defined whether the 'volume' parameter was
|
||||
* interpreted relative to the sink's current volume or treated as
|
||||
* absolute device volume. Since 0.9.20 it is an absolute volume when
|
||||
* the sink is in flat volume mode, and relative otherwise, thus
|
||||
* making sure the volume passed here has always the same semantics as
|
||||
* the volume passed to pa_context_set_sink_input_volume(). */
|
||||
int pa_stream_connect_playback(
|
||||
pa_stream *s /**< The stream to connect to a sink */,
|
||||
const char *dev /**< Name of the sink to connect to, or NULL for default */ ,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,116 @@ 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,10 @@ 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);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
* stored in SHM and our OS does not commit the memory before we use
|
||||
* it for the first time. */
|
||||
#define PA_MEMPOOL_SLOTS_MAX 1024
|
||||
#define PA_MEMPOOL_SLOT_SIZE (128*1024)
|
||||
#define PA_MEMPOOL_SLOT_SIZE (64*1024)
|
||||
|
||||
#define PA_MEMEXPORT_SLOTS_MAX 128
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1002,6 +1002,7 @@ static playback_stream* playback_stream_new(
|
|||
pa_proplist *p,
|
||||
pa_bool_t adjust_latency,
|
||||
pa_bool_t early_requests,
|
||||
pa_bool_t relative_volume,
|
||||
int *ret) {
|
||||
|
||||
playback_stream *s, *ssync;
|
||||
|
|
@ -1044,13 +1045,21 @@ static playback_stream* playback_stream_new(
|
|||
data.driver = __FILE__;
|
||||
data.module = c->options->module;
|
||||
data.client = c->client;
|
||||
data.sink = sink;
|
||||
if (sink) {
|
||||
data.sink = sink;
|
||||
data.save_sink = TRUE;
|
||||
}
|
||||
pa_sink_input_new_data_set_sample_spec(&data, ss);
|
||||
pa_sink_input_new_data_set_channel_map(&data, map);
|
||||
if (volume)
|
||||
if (volume) {
|
||||
pa_sink_input_new_data_set_volume(&data, volume);
|
||||
if (muted_set)
|
||||
data.volume_is_absolute = !relative_volume;
|
||||
data.save_volume = TRUE;
|
||||
}
|
||||
if (muted_set) {
|
||||
pa_sink_input_new_data_set_muted(&data, muted);
|
||||
data.save_muted = TRUE;
|
||||
}
|
||||
data.sync_base = ssync ? ssync->sink_input : NULL;
|
||||
data.flags = flags;
|
||||
|
||||
|
|
@ -1838,7 +1847,8 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
|
|||
early_requests = FALSE,
|
||||
dont_inhibit_auto_suspend = FALSE,
|
||||
muted_set = FALSE,
|
||||
fail_on_suspend = FALSE;
|
||||
fail_on_suspend = FALSE,
|
||||
relative_volume = FALSE;
|
||||
pa_sink_input_flags_t flags = 0;
|
||||
pa_proplist *p;
|
||||
pa_bool_t volume_set = TRUE;
|
||||
|
|
@ -1931,6 +1941,15 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
|
|||
}
|
||||
}
|
||||
|
||||
if (c->version >= 17) {
|
||||
|
||||
if (pa_tagstruct_get_boolean(t, &relative_volume) < 0) {
|
||||
protocol_error(c);
|
||||
pa_proplist_free(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pa_tagstruct_eof(t)) {
|
||||
protocol_error(c);
|
||||
pa_proplist_free(p);
|
||||
|
|
@ -1970,7 +1989,7 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
|
|||
* flag. For older versions we synthesize it here */
|
||||
muted_set = muted_set || muted;
|
||||
|
||||
s = playback_stream_new(c, sink, &ss, &map, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, &ret);
|
||||
s = playback_stream_new(c, sink, &ss, &map, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, relative_volume, &ret);
|
||||
pa_proplist_free(p);
|
||||
|
||||
CHECK_VALIDITY(c->pstream, s, tag, ret);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
63
src/pulsecore/semaphore-osx.c
Normal file
63
src/pulsecore/semaphore-osx.c
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#endif
|
||||
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/rtclock.h>
|
||||
|
||||
#include <pulsecore/random.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/g711.h>
|
||||
|
|
@ -60,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 | */
|
||||
|
|
@ -255,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];
|
||||
|
||||
|
|
@ -267,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]);
|
||||
}
|
||||
}
|
||||
|
|
@ -287,6 +294,8 @@ static void run_test (void) {
|
|||
}
|
||||
stop = pa_rtclock_now();
|
||||
pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
|
||||
|
||||
pa_assert_se(memcmp(samples_ref, samples, sizeof(samples)) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#endif
|
||||
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/rtclock.h>
|
||||
|
||||
#include <pulsecore/random.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/g711.h>
|
||||
|
|
@ -261,7 +263,7 @@ static void run_test (void) {
|
|||
|
||||
func = pa_get_volume_func (PA_SAMPLE_S16NE);
|
||||
|
||||
printf ("checking SSE %zd\n", sizeof (samples));
|
||||
printf ("checking SSE2 %zd\n", sizeof (samples));
|
||||
|
||||
pa_random (samples, sizeof (samples));
|
||||
memcpy (samples_ref, samples, sizeof (samples));
|
||||
|
|
@ -273,7 +275,7 @@ static void run_test (void) {
|
|||
volumes[i] = volumes[padding];
|
||||
|
||||
func (samples_ref, volumes, CHANNELS, sizeof (samples));
|
||||
pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
|
||||
pa_volume_s16ne_sse2 (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],
|
||||
|
|
@ -284,7 +286,7 @@ static void run_test (void) {
|
|||
start = pa_rtclock_now();
|
||||
for (j = 0; j < TIMES; j++) {
|
||||
memcpy (samples, samples_orig, sizeof (samples));
|
||||
pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
|
||||
pa_volume_s16ne_sse2 (samples, volumes, CHANNELS, sizeof (samples));
|
||||
}
|
||||
stop = pa_rtclock_now();
|
||||
pa_log_info("SSE: %llu usec.", (long long unsigned int)(stop - start));
|
||||
|
|
@ -296,6 +298,8 @@ static void run_test (void) {
|
|||
}
|
||||
stop = pa_rtclock_now();
|
||||
pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
|
||||
|
||||
pa_assert_se(memcmp(samples_ref, samples, sizeof(samples)) == 0);
|
||||
}
|
||||
#endif
|
||||
#endif /* defined (__i386__) || defined (__amd64__) */
|
||||
|
|
|
|||
|
|
@ -196,6 +196,13 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {
|
|||
int64_t ax = 0, ay = 0, k, t;
|
||||
double r;
|
||||
|
||||
/* FIXME: Optimization: Jason Newton suggested that instead of
|
||||
* going through the history on each iteration we could calculated
|
||||
* avg_gradient() as we go.
|
||||
*
|
||||
* Second idea: it might make sense to weight history entries:
|
||||
* more recent entries should matter more than old ones. */
|
||||
|
||||
/* Too few measurements, assume gradient of 1 */
|
||||
if (s->n_history < s->min_history)
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,6 @@
|
|||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/sndfile-util.h>
|
||||
|
||||
#define BUFSIZE (16*1024)
|
||||
|
||||
static pa_context *context = NULL;
|
||||
static pa_mainloop_api *mainloop_api = NULL;
|
||||
|
||||
|
|
@ -158,10 +156,23 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi
|
|||
return;
|
||||
}
|
||||
|
||||
printf(_("Server String: %s\n"
|
||||
"Library Protocol Version: %u\n"
|
||||
"Server Protocol Version: %u\n"
|
||||
"Is Local: %s\n"
|
||||
"Client Index: %u\n"
|
||||
"Tile Size: %zu\n"),
|
||||
pa_context_get_server(c),
|
||||
pa_context_get_protocol_version(c),
|
||||
pa_context_get_server_protocol_version(c),
|
||||
pa_yes_no(pa_context_is_local(c)),
|
||||
pa_context_get_index(c),
|
||||
pa_context_get_tile_size(c, NULL));
|
||||
|
||||
pa_sample_spec_snprint(ss, sizeof(ss), &i->sample_spec);
|
||||
pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map);
|
||||
|
||||
printf(_("User name: %s\n"
|
||||
printf(_("User Name: %s\n"
|
||||
"Host Name: %s\n"
|
||||
"Server Name: %s\n"
|
||||
"Server Version: %s\n"
|
||||
|
|
@ -169,7 +180,7 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi
|
|||
"Default Channel Map: %s\n"
|
||||
"Default Sink: %s\n"
|
||||
"Default Source: %s\n"
|
||||
"Cookie: %08x\n"),
|
||||
"Cookie: %04x:%04x\n"),
|
||||
i->user_name,
|
||||
i->host_name,
|
||||
i->server_name,
|
||||
|
|
@ -178,7 +189,8 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi
|
|||
cm,
|
||||
i->default_sink_name,
|
||||
i->default_source_name,
|
||||
i->cookie);
|
||||
i->cookie >> 16,
|
||||
i->cookie & 0xFFFFU);
|
||||
|
||||
complete_action();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,8 +45,6 @@
|
|||
#include <pulse/pulseaudio.h>
|
||||
#include <pulsecore/macro.h>
|
||||
|
||||
#define BUFSIZE 1024
|
||||
|
||||
static pa_context *context = NULL;
|
||||
static pa_mainloop_api *mainloop_api = NULL;
|
||||
static char **child_argv = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue