mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-05 13:29:57 -05:00
Port to Windows. This is mostly glue layers for the poor POSIX support
on Windows. A few notes * Only sockets behave somewhat like file descriptors in UNIX. * There are no fixed paths. Closes thing is environment variables that point to system directories. We also figure out where the binary/dll is located and use that as configuration directory. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/ossman@418 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
2f74bb9d43
commit
19d9fcbda8
22 changed files with 712 additions and 58 deletions
|
|
@ -138,7 +138,7 @@ AC_CHECK_HEADERS([linux/input.h], [HAVE_EVDEV=1], [HAVE_EVDEV=0])
|
||||||
AM_CONDITIONAL([HAVE_EVDEV], [test "x$HAVE_EVDEV" = "x1"])
|
AM_CONDITIONAL([HAVE_EVDEV], [test "x$HAVE_EVDEV" = "x1"])
|
||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
AC_CHECK_HEADERS([winsock2.h ws2tcpip.h])
|
AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h])
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
AC_CHECK_HEADERS([sys/ioctl.h])
|
AC_CHECK_HEADERS([sys/ioctl.h])
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,7 @@ libpolyp_@PA_MAJORMINOR@_la_SOURCES = \
|
||||||
cdecl.h \
|
cdecl.h \
|
||||||
client-conf.c client-conf.h \
|
client-conf.c client-conf.h \
|
||||||
conf-parser.c conf-parser.h \
|
conf-parser.c conf-parser.h \
|
||||||
|
dllmain.c \
|
||||||
dynarray.c dynarray.h \
|
dynarray.c dynarray.h \
|
||||||
gcc-printf.h \
|
gcc-printf.h \
|
||||||
idxset.c idxset.h \
|
idxset.c idxset.h \
|
||||||
|
|
@ -432,6 +433,7 @@ libpolypcore_la_SOURCES = \
|
||||||
cli-text.c cli-text.h \
|
cli-text.c cli-text.h \
|
||||||
client.c client.h \
|
client.c client.h \
|
||||||
core.c core.h \
|
core.c core.h \
|
||||||
|
dllmain.c \
|
||||||
dynarray.c dynarray.h \
|
dynarray.c dynarray.h \
|
||||||
endianmacros.h \
|
endianmacros.h \
|
||||||
g711.c g711.h \
|
g711.c g711.h \
|
||||||
|
|
@ -562,7 +564,7 @@ libpdispatch_la_LIBADD = $(AM_LIBADD) libtagstruct.la libpolypcore.la
|
||||||
|
|
||||||
libiochannel_la_SOURCES = iochannel.c iochannel.h
|
libiochannel_la_SOURCES = iochannel.c iochannel.h
|
||||||
libiochannel_la_LDFLAGS = -avoid-version
|
libiochannel_la_LDFLAGS = -avoid-version
|
||||||
libiochannel_la_LIBADD = $(AM_LIBADD) libsocket-util.la libpolypcore.la
|
libiochannel_la_LIBADD = $(AM_LIBADD) libsocket-util.la libpolypcore.la $(WINSOCK_LIBS)
|
||||||
|
|
||||||
libpacket_la_SOURCES = packet.c packet.h
|
libpacket_la_SOURCES = packet.c packet.h
|
||||||
libpacket_la_LDFLAGS = -avoid-version
|
libpacket_la_LDFLAGS = -avoid-version
|
||||||
|
|
@ -727,6 +729,11 @@ modlib_LTLIBRARIES += \
|
||||||
module-mmkbd-evdev.la
|
module-mmkbd-evdev.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if OS_IS_WIN32
|
||||||
|
modlib_LTLIBRARIES += \
|
||||||
|
module-waveout.la
|
||||||
|
endif
|
||||||
|
|
||||||
# These are generated by a M4 script
|
# These are generated by a M4 script
|
||||||
|
|
||||||
SYMDEF_FILES = \
|
SYMDEF_FILES = \
|
||||||
|
|
@ -766,7 +773,8 @@ SYMDEF_FILES = \
|
||||||
module-oss-symdef.h \
|
module-oss-symdef.h \
|
||||||
module-oss-mmap-symdef.h \
|
module-oss-mmap-symdef.h \
|
||||||
module-alsa-sink-symdef.h \
|
module-alsa-sink-symdef.h \
|
||||||
module-alsa-source-symdef.h
|
module-alsa-source-symdef.h \
|
||||||
|
module-waveout-symdef.h
|
||||||
|
|
||||||
EXTRA_DIST += $(SYMDEF_FILES)
|
EXTRA_DIST += $(SYMDEF_FILES)
|
||||||
BUILT_SOURCES += $(SYMDEF_FILES)
|
BUILT_SOURCES += $(SYMDEF_FILES)
|
||||||
|
|
@ -974,6 +982,13 @@ module_mmkbd_evdev_la_LDFLAGS = -module -avoid-version
|
||||||
module_mmkbd_evdev_la_LIBADD = $(AM_LIBADD)
|
module_mmkbd_evdev_la_LIBADD = $(AM_LIBADD)
|
||||||
module_mmkbd_evdev_la_CFLAGS = $(AM_CFLAGS)
|
module_mmkbd_evdev_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
|
# Windows waveout
|
||||||
|
|
||||||
|
module_waveout_la_SOURCES = module-waveout.c
|
||||||
|
module_waveout_la_LDFLAGS = -module -avoid-version
|
||||||
|
module_waveout_la_LIBADD = $(AM_LIBADD) libpolypcore.la -lwinmm
|
||||||
|
module_waveout_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
# Some minor stuff #
|
# Some minor stuff #
|
||||||
###################################
|
###################################
|
||||||
|
|
@ -990,8 +1005,13 @@ esdcompat.sh: esdcompat.sh.in Makefile
|
||||||
client.conf: client.conf.in Makefile
|
client.conf: client.conf.in Makefile
|
||||||
sed -e 's,@POLYPAUDIO_BINARY\@,$(POLYPAUDIO_BINARY),g' < $< > $@
|
sed -e 's,@POLYPAUDIO_BINARY\@,$(POLYPAUDIO_BINARY),g' < $< > $@
|
||||||
|
|
||||||
|
if OS_IS_WIN32
|
||||||
|
default.pa: default.pa.win32
|
||||||
|
cp $< $@
|
||||||
|
else
|
||||||
default.pa: default.pa.in Makefile
|
default.pa: default.pa.in Makefile
|
||||||
sed -e 's,@POLYPAUDIO_BINARY\@,$(POLYPAUDIO_BINARY),g' < $< > $@
|
sed -e 's,@POLYPAUDIO_BINARY\@,$(POLYPAUDIO_BINARY),g' < $< > $@
|
||||||
|
endif
|
||||||
|
|
||||||
daemon.conf: daemon.conf.in Makefile
|
daemon.conf: daemon.conf.in Makefile
|
||||||
sed -e 's,@DLSEARCHPATH\@,$(modlibdir),g' \
|
sed -e 's,@DLSEARCHPATH\@,$(modlibdir),g' \
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@
|
||||||
USA.
|
USA.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -33,11 +37,21 @@
|
||||||
#include "authkey.h"
|
#include "authkey.h"
|
||||||
|
|
||||||
#ifndef DEFAULT_CONFIG_DIR
|
#ifndef DEFAULT_CONFIG_DIR
|
||||||
|
# ifndef OS_IS_WIN32
|
||||||
# define DEFAULT_CONFIG_DIR "/etc/polypaudio"
|
# define DEFAULT_CONFIG_DIR "/etc/polypaudio"
|
||||||
|
# else
|
||||||
|
# define DEFAULT_CONFIG_DIR "%POLYP_ROOT%"
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_CLIENT_CONFIG_FILE DEFAULT_CONFIG_DIR"/client.conf"
|
#ifndef OS_IS_WIN32
|
||||||
#define DEFAULT_CLIENT_CONFIG_FILE_USER ".polypaudio/client.conf"
|
# define PATH_SEP "/"
|
||||||
|
#else
|
||||||
|
# define PATH_SEP "\\"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_CLIENT_CONFIG_FILE DEFAULT_CONFIG_DIR PATH_SEP "client.conf"
|
||||||
|
#define DEFAULT_CLIENT_CONFIG_FILE_USER ".polypaudio" PATH_SEP "client.conf"
|
||||||
|
|
||||||
#define ENV_CLIENT_CONFIG_FILE "POLYP_CLIENTCONFIG"
|
#define ENV_CLIENT_CONFIG_FILE "POLYP_CLIENTCONFIG"
|
||||||
#define ENV_DEFAULT_SINK "POLYP_SINK"
|
#define ENV_DEFAULT_SINK "POLYP_SINK"
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,23 @@
|
||||||
#include "resampler.h"
|
#include "resampler.h"
|
||||||
|
|
||||||
#ifndef DEFAULT_CONFIG_DIR
|
#ifndef DEFAULT_CONFIG_DIR
|
||||||
|
# ifndef OS_IS_WIN32
|
||||||
# define DEFAULT_CONFIG_DIR "/etc/polypaudio"
|
# define DEFAULT_CONFIG_DIR "/etc/polypaudio"
|
||||||
|
# else
|
||||||
|
# define DEFAULT_CONFIG_DIR "%POLYP_ROOT%"
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_SCRIPT_FILE DEFAULT_CONFIG_DIR"/default.pa"
|
#ifndef OS_IS_WIN32
|
||||||
#define DEFAULT_SCRIPT_FILE_USER ".polypaudio/default.pa"
|
# define PATH_SEP "/"
|
||||||
#define DEFAULT_CONFIG_FILE DEFAULT_CONFIG_DIR"/daemon.conf"
|
#else
|
||||||
#define DEFAULT_CONFIG_FILE_USER ".polypaudio/daemon.conf"
|
# define PATH_SEP "\\"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_SCRIPT_FILE DEFAULT_CONFIG_DIR PATH_SEP "default.pa"
|
||||||
|
#define DEFAULT_SCRIPT_FILE_USER ".polypaudio" PATH_SEP "default.pa"
|
||||||
|
#define DEFAULT_CONFIG_FILE DEFAULT_CONFIG_DIR PATH_SEP "daemon.conf"
|
||||||
|
#define DEFAULT_CONFIG_FILE_USER ".polypaudio" PATH_SEP "daemon.conf"
|
||||||
|
|
||||||
#define ENV_SCRIPT_FILE "POLYP_SCRIPT"
|
#define ENV_SCRIPT_FILE "POLYP_SCRIPT"
|
||||||
#define ENV_CONFIG_FILE "POLYP_CONFIG"
|
#define ENV_CONFIG_FILE "POLYP_CONFIG"
|
||||||
|
|
|
||||||
43
polyp/default.pa.win32
Normal file
43
polyp/default.pa.win32
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#
|
||||||
|
# This file is part of polypaudio.
|
||||||
|
#
|
||||||
|
# polypaudio is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# polypaudio 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 polypaudio; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||||
|
|
||||||
|
|
||||||
|
# Load audio drivers statically
|
||||||
|
|
||||||
|
load-module module-waveout sink_name=output source_name=input
|
||||||
|
load-module module-null-sink
|
||||||
|
|
||||||
|
# Load audio drivers automatically on access
|
||||||
|
|
||||||
|
#add-autoload-sink output module-waveout sink_name=output source_name=input
|
||||||
|
#add-autoload-source input module-waveout sink_name=output source_name=input
|
||||||
|
|
||||||
|
# Load several protocols
|
||||||
|
#load-module module-esound-protocol-tcp
|
||||||
|
#load-module module-native-protocol-tcp
|
||||||
|
#load-module module-simple-protocol-tcp
|
||||||
|
#load-module module-cli-protocol-tcp
|
||||||
|
|
||||||
|
# Make some devices default
|
||||||
|
set-default-sink output
|
||||||
|
set-default-source input
|
||||||
|
|
||||||
|
.nofail
|
||||||
|
|
||||||
|
# Load something to the sample cache
|
||||||
|
load-sample x11-bell %WINDIR%\Media\ding.wav
|
||||||
|
load-sample-dir-lazy %WINDIR%\Media\*.wav
|
||||||
46
polyp/dllmain.c
Normal file
46
polyp/dllmain.c
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* $Id: dllmain.c 317 2004-12-11 00:10:41Z lennart $ */
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of polypaudio.
|
||||||
|
|
||||||
|
polypaudio is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published
|
||||||
|
by the Free Software Foundation; either version 2 of the License,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
polypaudio 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 polypaudio; 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
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
extern pa_set_root(HANDLE handle);
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||||
|
if (fdwReason != DLL_PROCESS_ATTACH)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!pa_set_root(hinstDLL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* OS_IS_WIN32 */
|
||||||
|
|
@ -28,6 +28,10 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "iochannel.h"
|
#include "iochannel.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
|
|
@ -189,7 +193,19 @@ ssize_t pa_iochannel_write(struct pa_iochannel*io, const void*data, size_t l) {
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
assert(io && data && l && io->ofd >= 0);
|
assert(io && data && l && io->ofd >= 0);
|
||||||
|
|
||||||
if ((r = write(io->ofd, data, l)) >= 0) {
|
#ifdef OS_IS_WIN32
|
||||||
|
r = send(io->ofd, data, l, 0);
|
||||||
|
if (r < 0) {
|
||||||
|
if (WSAGetLastError() != WSAENOTSOCK) {
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
#endif
|
||||||
|
r = write(io->ofd, data, l);
|
||||||
|
if (r >= 0) {
|
||||||
io->writable = 0;
|
io->writable = 0;
|
||||||
enable_mainloop_sources(io);
|
enable_mainloop_sources(io);
|
||||||
}
|
}
|
||||||
|
|
@ -201,7 +217,19 @@ ssize_t pa_iochannel_read(struct pa_iochannel*io, void*data, size_t l) {
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
assert(io && data && io->ifd >= 0);
|
assert(io && data && io->ifd >= 0);
|
||||||
|
|
||||||
if ((r = read(io->ifd, data, l)) >= 0) {
|
#ifdef OS_IS_WIN32
|
||||||
|
r = recv(io->ifd, data, l, 0);
|
||||||
|
if (r < 0) {
|
||||||
|
if (WSAGetLastError() != WSAENOTSOCK) {
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
#endif
|
||||||
|
r = read(io->ifd, data, l);
|
||||||
|
if (r >= 0) {
|
||||||
io->readable = 0;
|
io->readable = 0;
|
||||||
enable_mainloop_sources(io);
|
enable_mainloop_sources(io);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
67
polyp/main.c
67
polyp/main.c
|
|
@ -35,7 +35,16 @@
|
||||||
#include <memblock.h>
|
#include <memblock.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_IOCTL_H
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBWRAP
|
#ifdef HAVE_LIBWRAP
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
@ -66,6 +75,23 @@ int allow_severity = LOG_INFO;
|
||||||
int deny_severity = LOG_WARNING;
|
int deny_severity = LOG_WARNING;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
|
||||||
|
static void message_cb(struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata) {
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
|
if (msg.message == WM_QUIT)
|
||||||
|
raise(SIGTERM);
|
||||||
|
else {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) {
|
static void signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) {
|
||||||
pa_log_info(__FILE__": Got signal %s.\n", pa_strsignal(sig));
|
pa_log_info(__FILE__": Got signal %s.\n", pa_strsignal(sig));
|
||||||
|
|
||||||
|
|
@ -124,6 +150,10 @@ int main(int argc, char *argv[]) {
|
||||||
gid_t gid = (gid_t) -1;
|
gid_t gid = (gid_t) -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
struct pa_defer_event *defer;
|
||||||
|
#endif
|
||||||
|
|
||||||
pa_limit_caps();
|
pa_limit_caps();
|
||||||
|
|
||||||
#ifdef HAVE_GETUID
|
#ifdef HAVE_GETUID
|
||||||
|
|
@ -142,6 +172,13 @@ int main(int argc, char *argv[]) {
|
||||||
r = lt_dlinit();
|
r = lt_dlinit();
|
||||||
assert(r == 0);
|
assert(r == 0);
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
{
|
||||||
|
WSADATA data;
|
||||||
|
WSAStartup(MAKEWORD(2, 0), &data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pa_log_set_ident("polypaudio");
|
pa_log_set_ident("polypaudio");
|
||||||
|
|
||||||
conf = pa_daemon_conf_new();
|
conf = pa_daemon_conf_new();
|
||||||
|
|
@ -230,6 +267,7 @@ int main(int argc, char *argv[]) {
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_FORK
|
||||||
if (pipe(daemon_pipe) < 0) {
|
if (pipe(daemon_pipe) < 0) {
|
||||||
pa_log(__FILE__": failed to create pipe.\n");
|
pa_log(__FILE__": failed to create pipe.\n");
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
@ -261,6 +299,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
close(daemon_pipe[0]);
|
close(daemon_pipe[0]);
|
||||||
daemon_pipe[0] = -1;
|
daemon_pipe[0] = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (conf->auto_log_target)
|
if (conf->auto_log_target)
|
||||||
pa_log_set_target(PA_LOG_SYSLOG, NULL);
|
pa_log_set_target(PA_LOG_SYSLOG, NULL);
|
||||||
|
|
@ -272,6 +311,7 @@ int main(int argc, char *argv[]) {
|
||||||
setpgid(0,0);
|
setpgid(0,0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
close(0);
|
close(0);
|
||||||
close(1);
|
close(1);
|
||||||
close(2);
|
close(2);
|
||||||
|
|
@ -279,6 +319,9 @@ int main(int argc, char *argv[]) {
|
||||||
open("/dev/null", O_RDONLY);
|
open("/dev/null", O_RDONLY);
|
||||||
open("/dev/null", O_WRONLY);
|
open("/dev/null", O_WRONLY);
|
||||||
open("/dev/null", O_WRONLY);
|
open("/dev/null", O_WRONLY);
|
||||||
|
#else
|
||||||
|
FreeConsole();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SIGTTOU
|
#ifdef SIGTTOU
|
||||||
signal(SIGTTOU, SIG_IGN);
|
signal(SIGTTOU, SIG_IGN);
|
||||||
|
|
@ -290,18 +333,23 @@ int main(int argc, char *argv[]) {
|
||||||
signal(SIGTSTP, SIG_IGN);
|
signal(SIGTSTP, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TIOCNOTTY
|
||||||
if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
|
if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
|
||||||
ioctl(tty_fd, TIOCNOTTY, (char*) 0);
|
ioctl(tty_fd, TIOCNOTTY, (char*) 0);
|
||||||
close(tty_fd);
|
close(tty_fd);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
chdir("/");
|
chdir("/");
|
||||||
|
|
||||||
if (conf->use_pid_file) {
|
if (conf->use_pid_file) {
|
||||||
if (pa_pid_file_create() < 0) {
|
if (pa_pid_file_create() < 0) {
|
||||||
|
pa_log(__FILE__": pa_pid_file_create() failed.\n");
|
||||||
|
#ifdef HAVE_FORK
|
||||||
if (conf->daemonize)
|
if (conf->daemonize)
|
||||||
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
||||||
|
#endif
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,6 +370,11 @@ int main(int argc, char *argv[]) {
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
defer = pa_mainloop_get_api(mainloop)->defer_new(pa_mainloop_get_api(mainloop), message_cb, NULL);
|
||||||
|
assert(defer);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (conf->daemonize)
|
if (conf->daemonize)
|
||||||
c->running_as_daemon = 1;
|
c->running_as_daemon = 1;
|
||||||
|
|
||||||
|
|
@ -350,17 +403,23 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (r < 0 && conf->fail) {
|
if (r < 0 && conf->fail) {
|
||||||
pa_log(__FILE__": failed to initialize daemon.\n");
|
pa_log(__FILE__": failed to initialize daemon.\n");
|
||||||
|
#ifdef HAVE_FORK
|
||||||
if (conf->daemonize)
|
if (conf->daemonize)
|
||||||
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
||||||
|
#endif
|
||||||
} else if (!c->modules || pa_idxset_ncontents(c->modules) == 0) {
|
} else if (!c->modules || pa_idxset_ncontents(c->modules) == 0) {
|
||||||
pa_log(__FILE__": daemon startup without any loaded modules, refusing to work.\n");
|
pa_log(__FILE__": daemon startup without any loaded modules, refusing to work.\n");
|
||||||
|
#ifdef HAVE_FORK
|
||||||
if (conf->daemonize)
|
if (conf->daemonize)
|
||||||
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
#ifdef HAVE_FORK
|
||||||
if (conf->daemonize)
|
if (conf->daemonize)
|
||||||
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
||||||
|
#endif
|
||||||
|
|
||||||
c->disallow_module_loading = conf->disallow_module_loading;
|
c->disallow_module_loading = conf->disallow_module_loading;
|
||||||
c->exit_idle_time = conf->exit_idle_time;
|
c->exit_idle_time = conf->exit_idle_time;
|
||||||
|
|
@ -379,6 +438,10 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
pa_mainloop_get_api(mainloop)->defer_free(defer);
|
||||||
|
#endif
|
||||||
|
|
||||||
pa_core_free(c);
|
pa_core_free(c);
|
||||||
|
|
||||||
pa_cpu_limit_done();
|
pa_cpu_limit_done();
|
||||||
|
|
@ -397,6 +460,10 @@ finish:
|
||||||
|
|
||||||
close_pipe(daemon_pipe);
|
close_pipe(daemon_pipe);
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
WSACleanup();
|
||||||
|
#endif
|
||||||
|
|
||||||
lt_dlexit();
|
lt_dlexit();
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mainloop-signal.h"
|
#include "mainloop-signal.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
@ -53,19 +57,70 @@ struct pa_signal_event {
|
||||||
static struct pa_mainloop_api *api = NULL;
|
static struct pa_mainloop_api *api = NULL;
|
||||||
static int signal_pipe[2] = { -1, -1 };
|
static int signal_pipe[2] = { -1, -1 };
|
||||||
static struct pa_io_event* io_event = NULL;
|
static struct pa_io_event* io_event = NULL;
|
||||||
|
static struct pa_defer_event *defer_event = NULL;
|
||||||
static struct pa_signal_event *signals = NULL;
|
static struct pa_signal_event *signals = NULL;
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
static unsigned int waiting_signals = 0;
|
||||||
|
static CRITICAL_SECTION crit;
|
||||||
|
#endif
|
||||||
|
|
||||||
static void signal_handler(int sig) {
|
static void signal_handler(int sig) {
|
||||||
#ifndef HAVE_SIGACTION
|
#ifndef HAVE_SIGACTION
|
||||||
signal(sig, signal_handler);
|
signal(sig, signal_handler);
|
||||||
#endif
|
#endif
|
||||||
write(signal_pipe[1], &sig, sizeof(sig));
|
write(signal_pipe[1], &sig, sizeof(sig));
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
EnterCriticalSection(&crit);
|
||||||
|
waiting_signals++;
|
||||||
|
LeaveCriticalSection(&crit);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dispatch(struct pa_mainloop_api*a, int sig) {
|
||||||
|
struct pa_signal_event*s;
|
||||||
|
|
||||||
|
for (s = signals; s; s = s->next)
|
||||||
|
if (s->sig == sig) {
|
||||||
|
assert(s->callback);
|
||||||
|
s->callback(a, s, sig, s->userdata);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void defer(struct pa_mainloop_api*a, struct pa_defer_event*e, void *userdata) {
|
||||||
|
ssize_t r;
|
||||||
|
int sig;
|
||||||
|
unsigned int sigs;
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
EnterCriticalSection(&crit);
|
||||||
|
sigs = waiting_signals;
|
||||||
|
waiting_signals = 0;
|
||||||
|
LeaveCriticalSection(&crit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (sigs) {
|
||||||
|
if ((r = read(signal_pipe[0], &sig, sizeof(sig))) < 0) {
|
||||||
|
pa_log(__FILE__": read(): %s\n", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r != sizeof(sig)) {
|
||||||
|
pa_log(__FILE__": short read()\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(a, sig);
|
||||||
|
|
||||||
|
sigs--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd, enum pa_io_event_flags f, void *userdata) {
|
static void callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd, enum pa_io_event_flags f, void *userdata) {
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
int sig;
|
int sig;
|
||||||
struct pa_signal_event*s;
|
|
||||||
assert(a && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == signal_pipe[0]);
|
assert(a && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == signal_pipe[0]);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -82,18 +137,17 @@ static void callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd, enu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s = signals; s; s = s->next)
|
dispatch(a, sig);
|
||||||
if (s->sig == sig) {
|
|
||||||
assert(s->callback);
|
|
||||||
s->callback(a, s, sig, s->userdata);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pa_signal_init(struct pa_mainloop_api *a) {
|
int pa_signal_init(struct pa_mainloop_api *a) {
|
||||||
assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event);
|
assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event && !defer_event);
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
if (_pipe(signal_pipe, 200, _O_BINARY) < 0) {
|
||||||
|
#else
|
||||||
if (pipe(signal_pipe) < 0) {
|
if (pipe(signal_pipe) < 0) {
|
||||||
|
#endif
|
||||||
pa_log(__FILE__": pipe() failed: %s\n", strerror(errno));
|
pa_log(__FILE__": pipe() failed: %s\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -104,20 +158,36 @@ int pa_signal_init(struct pa_mainloop_api *a) {
|
||||||
pa_fd_set_cloexec(signal_pipe[1], 1);
|
pa_fd_set_cloexec(signal_pipe[1], 1);
|
||||||
|
|
||||||
api = a;
|
api = a;
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL);
|
io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL);
|
||||||
assert(io_event);
|
assert(io_event);
|
||||||
|
#else
|
||||||
|
defer_event = api->defer_new(api, defer, NULL);
|
||||||
|
assert(defer_event);
|
||||||
|
|
||||||
|
InitializeCriticalSection(&crit);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pa_signal_done(void) {
|
void pa_signal_done(void) {
|
||||||
assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && io_event);
|
assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && (io_event || defer_event));
|
||||||
|
|
||||||
while (signals)
|
while (signals)
|
||||||
pa_signal_free(signals);
|
pa_signal_free(signals);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
api->io_free(io_event);
|
api->io_free(io_event);
|
||||||
io_event = NULL;
|
io_event = NULL;
|
||||||
|
#else
|
||||||
|
api->defer_free(defer_event);
|
||||||
|
defer_event = NULL;
|
||||||
|
|
||||||
|
DeleteCriticalSection(&crit);
|
||||||
|
#endif
|
||||||
|
|
||||||
close(signal_pipe[0]);
|
close(signal_pipe[0]);
|
||||||
close(signal_pipe[1]);
|
close(signal_pipe[1]);
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,10 @@
|
||||||
#include "poll.h"
|
#include "poll.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mainloop.h"
|
#include "mainloop.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "idxset.h"
|
#include "idxset.h"
|
||||||
|
|
@ -108,6 +112,26 @@ static struct pa_io_event* mainloop_io_new(struct pa_mainloop_api*a, int fd, enu
|
||||||
e->destroy_callback = NULL;
|
e->destroy_callback = NULL;
|
||||||
e->pollfd = NULL;
|
e->pollfd = NULL;
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
{
|
||||||
|
fd_set xset;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO (&xset);
|
||||||
|
FD_SET (fd, &xset);
|
||||||
|
|
||||||
|
if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset,
|
||||||
|
SELECT_TYPE_ARG5 &tv) == -1) &&
|
||||||
|
(WSAGetLastError() == WSAENOTSOCK)) {
|
||||||
|
pa_log_warn(__FILE__": WARNING: cannot monitor non-socket file descriptors.\n");
|
||||||
|
e->dead = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pa_idxset_put(m->io_events, e, NULL);
|
pa_idxset_put(m->io_events, e, NULL);
|
||||||
m->rebuild_pollfds = 1;
|
m->rebuild_pollfds = 1;
|
||||||
return e;
|
return e;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,13 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "socket-server.h"
|
#include "socket-server.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
|
|
|
||||||
29
polyp/pid.c
29
polyp/pid.c
|
|
@ -35,6 +35,10 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "pid.h"
|
#include "pid.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
@ -130,6 +134,10 @@ int pa_pid_file_create(void) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
HANDLE process;
|
||||||
|
#endif
|
||||||
|
|
||||||
pa_runtime_path("pid", fn, sizeof(fn));
|
pa_runtime_path("pid", fn, sizeof(fn));
|
||||||
|
|
||||||
if ((fd = open_pid_file(fn, O_CREAT|O_RDWR)) < 0)
|
if ((fd = open_pid_file(fn, O_CREAT|O_RDWR)) < 0)
|
||||||
|
|
@ -138,7 +146,12 @@ int pa_pid_file_create(void) {
|
||||||
if ((pid = read_pid(fn, fd)) == (pid_t) -1)
|
if ((pid = read_pid(fn, fd)) == (pid_t) -1)
|
||||||
pa_log(__FILE__": corrupt PID file, overwriting.\n");
|
pa_log(__FILE__": corrupt PID file, overwriting.\n");
|
||||||
else if (pid > 0) {
|
else if (pid > 0) {
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
if ((process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)) != NULL) {
|
||||||
|
CloseHandle(process);
|
||||||
|
#else
|
||||||
if (kill(pid, 0) >= 0 || errno != ESRCH) {
|
if (kill(pid, 0) >= 0 || errno != ESRCH) {
|
||||||
|
#endif
|
||||||
pa_log(__FILE__": daemon already running.\n");
|
pa_log(__FILE__": daemon already running.\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -198,6 +211,12 @@ int pa_pid_file_remove(void) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
pa_lock_fd(fd, 0);
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (unlink(fn) < 0) {
|
if (unlink(fn) < 0) {
|
||||||
pa_log(__FILE__": failed to remove PID file '%s': %s\n", fn, strerror(errno));
|
pa_log(__FILE__": failed to remove PID file '%s': %s\n", fn, strerror(errno));
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -223,6 +242,8 @@ int pa_pid_file_check_running(pid_t *pid) {
|
||||||
return pa_pid_file_kill(0, pid);
|
return pa_pid_file_kill(0, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
|
|
||||||
/* Kill a current running daemon. Return non-zero on success, -1
|
/* Kill a current running daemon. Return non-zero on success, -1
|
||||||
* otherwise. If successful *pid contains the PID of the daemon
|
* otherwise. If successful *pid contains the PID of the daemon
|
||||||
* process. */
|
* process. */
|
||||||
|
|
@ -255,3 +276,11 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* OS_IS_WIN32 */
|
||||||
|
|
||||||
|
int pa_pid_file_kill(int sig, pid_t *pid) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
24
polyp/poll.c
24
polyp/poll.c
|
|
@ -36,6 +36,17 @@
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
|
#define EBADF WSAEBADF
|
||||||
|
#define ESHUTDOWN WSAESHUTDOWN
|
||||||
|
#define ECONNRESET WSAECONNRESET
|
||||||
|
#define ECONNABORTED WSAECONNABORTED
|
||||||
|
#define ENETRESET WSAENETRESET
|
||||||
|
|
||||||
|
#endif /* HAVE_WINSOCK2_H */
|
||||||
|
|
||||||
#ifndef HAVE_SYS_POLL_H
|
#ifndef HAVE_SYS_POLL_H
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
@ -59,7 +70,16 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
/*
|
||||||
|
* Windows does not support signals properly so waiting for them would
|
||||||
|
* mean a deadlock.
|
||||||
|
*/
|
||||||
|
pa_msleep(100);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
return select(0, NULL, NULL, NULL, NULL);
|
return select(0, NULL, NULL, NULL, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (f = fds; f < &fds[nfds]; ++f) {
|
for (f = fds; f < &fds[nfds]; ++f) {
|
||||||
|
|
@ -138,6 +158,10 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ready > 0) {
|
if (ready > 0) {
|
||||||
ready = 0;
|
ready = 0;
|
||||||
for (f = fds; f < &fds[nfds]; ++f) {
|
for (f = fds; f < &fds[nfds]; ++f) {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifdef HAVE_SYS_WAIT_H
|
#ifdef HAVE_SYS_WAIT_H
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
@ -44,6 +45,13 @@
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#define ETIMEDOUT WSAETIMEDOUT
|
||||||
|
#define ECONNREFUSED WSAECONNREFUSED
|
||||||
|
#define EHOSTUNREACH WSAEHOSTUNREACH
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "polyplib-internal.h"
|
#include "polyplib-internal.h"
|
||||||
#include "polyplib-context.h"
|
#include "polyplib-context.h"
|
||||||
#include "native-common.h"
|
#include "native-common.h"
|
||||||
|
|
@ -382,6 +390,8 @@ finish:
|
||||||
|
|
||||||
static void on_connection(struct pa_socket_client *client, struct pa_iochannel*io, void *userdata);
|
static void on_connection(struct pa_socket_client *client, struct pa_iochannel*io, void *userdata);
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
|
|
||||||
static int context_connect_spawn(struct pa_context *c) {
|
static int context_connect_spawn(struct pa_context *c) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status, r;
|
int status, r;
|
||||||
|
|
@ -495,6 +505,8 @@ fail:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* OS_IS_WIN32 */
|
||||||
|
|
||||||
static int try_next_connection(struct pa_context *c) {
|
static int try_next_connection(struct pa_context *c) {
|
||||||
char *u = NULL;
|
char *u = NULL;
|
||||||
int r = -1;
|
int r = -1;
|
||||||
|
|
@ -509,10 +521,12 @@ static int try_next_connection(struct pa_context *c) {
|
||||||
|
|
||||||
if (!u) {
|
if (!u) {
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
if (c->do_autospawn) {
|
if (c->do_autospawn) {
|
||||||
r = context_connect_spawn(c);
|
r = context_connect_spawn(c);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pa_context_fail(c, PA_ERROR_CONNECTIONREFUSED);
|
pa_context_fail(c, PA_ERROR_CONNECTIONREFUSED);
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "pstream.h"
|
#include "pstream.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@
|
||||||
USA.
|
USA.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
@ -31,13 +35,16 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
#define RANDOM_DEVICE "/dev/urandom"
|
#define RANDOM_DEVICE "/dev/urandom"
|
||||||
|
#endif
|
||||||
|
|
||||||
void pa_random(void *ret_data, size_t length) {
|
void pa_random(void *ret_data, size_t length) {
|
||||||
int fd;
|
int fd;
|
||||||
ssize_t r = 0;
|
ssize_t r = 0;
|
||||||
assert(ret_data && length);
|
assert(ret_data && length);
|
||||||
|
|
||||||
|
#ifdef RANDOM_DEVICE
|
||||||
if ((fd = open(RANDOM_DEVICE, O_RDONLY)) >= 0) {
|
if ((fd = open(RANDOM_DEVICE, O_RDONLY)) >= 0) {
|
||||||
|
|
||||||
if ((r = pa_loop_read(fd, ret_data, length)) < 0 || (size_t) r != length)
|
if ((r = pa_loop_read(fd, ret_data, length)) < 0 || (size_t) r != length)
|
||||||
|
|
@ -45,17 +52,20 @@ void pa_random(void *ret_data, size_t length) {
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((size_t) r != length) {
|
if ((size_t) r != length) {
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
|
#ifdef RANDOM_DEVICE
|
||||||
pa_log_warn(__FILE__": WARNING: Failed to open entropy device '"RANDOM_DEVICE"': %s"
|
pa_log_warn(__FILE__": WARNING: Failed to open entropy device '"RANDOM_DEVICE"': %s"
|
||||||
", falling back to unsecure pseudo RNG.\n", strerror(errno));
|
", falling back to unsecure pseudo RNG.\n", strerror(errno));
|
||||||
|
#endif
|
||||||
|
|
||||||
srandom(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
for (p = ret_data, l = length; l > 0; p++, l--)
|
for (p = ret_data, l = length; l > 0; p++, l--)
|
||||||
*p = (uint8_t) random();
|
*p = (uint8_t) rand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,10 @@
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "scache.h"
|
#include "scache.h"
|
||||||
#include "sink-input.h"
|
#include "sink-input.h"
|
||||||
#include "mainloop.h"
|
#include "mainloop.h"
|
||||||
|
|
@ -147,6 +151,13 @@ int pa_scache_add_file(struct pa_core *c, const char *name, const char *filename
|
||||||
struct pa_memchunk chunk;
|
struct pa_memchunk chunk;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
if (ExpandEnvironmentStrings(filename, buf, MAX_PATH))
|
||||||
|
filename = buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pa_sound_file_load(filename, &ss, &chunk, c->memblock_stat) < 0)
|
if (pa_sound_file_load(filename, &ss, &chunk, c->memblock_stat) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
@ -158,6 +169,14 @@ int pa_scache_add_file(struct pa_core *c, const char *name, const char *filename
|
||||||
|
|
||||||
int pa_scache_add_file_lazy(struct pa_core *c, const char *name, const char *filename, uint32_t *index) {
|
int pa_scache_add_file_lazy(struct pa_core *c, const char *name, const char *filename, uint32_t *index) {
|
||||||
struct pa_scache_entry *e;
|
struct pa_scache_entry *e;
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
if (ExpandEnvironmentStrings(filename, buf, MAX_PATH))
|
||||||
|
filename = buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(c && name);
|
assert(c && name);
|
||||||
|
|
||||||
if (!(e = scache_add_item(c, name)))
|
if (!(e = scache_add_item(c, name)))
|
||||||
|
|
@ -313,7 +332,9 @@ static void add_file(struct pa_core *c, const char *pathname) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(S_ISREG) && defined(S_ISLNK)
|
||||||
if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))
|
if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))
|
||||||
|
#endif
|
||||||
pa_scache_add_file_lazy(c, e, pathname, NULL);
|
pa_scache_add_file_lazy(c, e, pathname, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,15 @@
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#define EINPROGRESS WSAEINPROGRESS
|
||||||
|
#define ETIMEDOUT WSAETIMEDOUT
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBASYNCNS
|
#ifdef HAVE_LIBASYNCNS
|
||||||
#include <asyncns.h>
|
#include <asyncns.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,13 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBWRAP
|
#ifdef HAVE_LIBWRAP
|
||||||
#include <tcpd.h>
|
#include <tcpd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,11 @@
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#define ETIMEDOUT WSAETIMEDOUT
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
@ -72,6 +77,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
if (S_ISSOCK(st.st_mode)) {
|
if (S_ISSOCK(st.st_mode)) {
|
||||||
union {
|
union {
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
|
|
@ -104,6 +110,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
|
||||||
snprintf(c, l, "STDIN/STDOUT client");
|
snprintf(c, l, "STDIN/STDOUT client");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif /* OS_IS_WIN32 */
|
||||||
|
|
||||||
snprintf(c, l, "Unknown client");
|
snprintf(c, l, "Unknown client");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,10 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "tagstruct.h"
|
#include "tagstruct.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
|
|
|
||||||
232
polyp/util.c
232
polyp/util.c
|
|
@ -32,12 +32,12 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SCHED_H
|
#ifdef HAVE_SCHED_H
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
|
@ -55,6 +55,17 @@
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <samplerate.h>
|
#include <samplerate.h>
|
||||||
|
|
||||||
#ifdef HAVE_PWD_H
|
#ifdef HAVE_PWD_H
|
||||||
|
|
@ -68,16 +79,56 @@
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
#define PA_RUNTIME_PATH_PREFIX "/tmp/polypaudio-"
|
#define PA_RUNTIME_PATH_PREFIX "/tmp/polypaudio-"
|
||||||
|
#define PATH_SEP '/'
|
||||||
|
#else
|
||||||
|
#define PA_RUNTIME_PATH_PREFIX "%TEMP%\\polypaudio-"
|
||||||
|
#define PATH_SEP '\\'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
|
||||||
|
#define POLYP_ROOTENV "POLYP_ROOT"
|
||||||
|
|
||||||
|
int pa_set_root(HANDLE handle) {
|
||||||
|
char library_path[MAX_PATH + sizeof(POLYP_ROOTENV) + 1], *sep;
|
||||||
|
|
||||||
|
strcpy(library_path, POLYP_ROOTENV "=");
|
||||||
|
|
||||||
|
if (!GetModuleFileName(handle, library_path + sizeof(POLYP_ROOTENV), MAX_PATH))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sep = strrchr(library_path, '\\');
|
||||||
|
if (sep)
|
||||||
|
*sep = '\0';
|
||||||
|
|
||||||
|
if (_putenv(library_path) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Make a file descriptor nonblock. Doesn't do any error checking */
|
/** Make a file descriptor nonblock. Doesn't do any error checking */
|
||||||
void pa_make_nonblock_fd(int fd) {
|
void pa_make_nonblock_fd(int fd) {
|
||||||
|
#ifdef O_NONBLOCK
|
||||||
int v;
|
int v;
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
|
|
||||||
if ((v = fcntl(fd, F_GETFL)) >= 0)
|
if ((v = fcntl(fd, F_GETFL)) >= 0)
|
||||||
if (!(v & O_NONBLOCK))
|
if (!(v & O_NONBLOCK))
|
||||||
fcntl(fd, F_SETFL, v|O_NONBLOCK);
|
fcntl(fd, F_SETFL, v|O_NONBLOCK);
|
||||||
|
#elif defined(OS_IS_WIN32)
|
||||||
|
u_long arg = 1;
|
||||||
|
if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
|
||||||
|
if (WSAGetLastError() == WSAENOTSOCK)
|
||||||
|
pa_log_warn(__FILE__": WARNING: Only sockets can be made non-blocking!\n");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
pa_log_warn(__FILE__": WARNING: Non-blocking I/O not supported.!\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a directory securely */
|
/** Creates a directory securely */
|
||||||
|
|
@ -85,15 +136,27 @@ int pa_make_secure_dir(const char* dir) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
assert(dir);
|
assert(dir);
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
if (mkdir(dir) < 0)
|
||||||
|
#else
|
||||||
if (mkdir(dir, 0700) < 0)
|
if (mkdir(dir, 0700) < 0)
|
||||||
|
#endif
|
||||||
if (errno != EEXIST)
|
if (errno != EEXIST)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
if (stat(dir, &st) < 0)
|
||||||
|
#else
|
||||||
if (lstat(dir, &st) < 0)
|
if (lstat(dir, &st) < 0)
|
||||||
|
#endif
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
if (!S_ISDIR(st.st_mode) || (st.st_uid != getuid()) || ((st.st_mode & 0777) != 0700))
|
if (!S_ISDIR(st.st_mode) || (st.st_uid != getuid()) || ((st.st_mode & 0777) != 0700))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "FIXME: pa_make_secure_dir()\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -107,9 +170,10 @@ int pa_make_secure_parent_dir(const char *fn) {
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
char *slash, *dir = pa_xstrdup(fn);
|
char *slash, *dir = pa_xstrdup(fn);
|
||||||
|
|
||||||
if (!(slash = strrchr(dir, '/')))
|
slash = pa_path_get_filename(dir);
|
||||||
|
if (slash == fn)
|
||||||
goto finish;
|
goto finish;
|
||||||
*slash = 0;
|
*(slash-1) = 0;
|
||||||
|
|
||||||
if (pa_make_secure_dir(dir) < 0)
|
if (pa_make_secure_dir(dir) < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
@ -285,6 +349,15 @@ char *pa_get_user_name(char *s, size_t l) {
|
||||||
}
|
}
|
||||||
|
|
||||||
p = r->pw_name;
|
p = r->pw_name;
|
||||||
|
|
||||||
|
#elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
|
||||||
|
DWORD size = sizeof(buf);
|
||||||
|
|
||||||
|
if (!GetUserName(buf, &size))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
#else /* HAVE_PWD_H */
|
#else /* HAVE_PWD_H */
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif /* HAVE_PWD_H */
|
#endif /* HAVE_PWD_H */
|
||||||
|
|
@ -318,6 +391,9 @@ char *pa_get_home_dir(char *s, size_t l) {
|
||||||
if ((e = getenv("HOME")))
|
if ((e = getenv("HOME")))
|
||||||
return pa_strlcpy(s, e, l);
|
return pa_strlcpy(s, e, l);
|
||||||
|
|
||||||
|
if ((e = getenv("USERPROFILE")))
|
||||||
|
return pa_strlcpy(s, e, l);
|
||||||
|
|
||||||
#ifdef HAVE_PWD_H
|
#ifdef HAVE_PWD_H
|
||||||
#ifdef HAVE_GETPWUID_R
|
#ifdef HAVE_GETPWUID_R
|
||||||
if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
|
if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
|
||||||
|
|
@ -349,6 +425,34 @@ char *pa_strlcpy(char *b, const char *s, size_t l) {
|
||||||
int pa_gettimeofday(struct timeval *tv) {
|
int pa_gettimeofday(struct timeval *tv) {
|
||||||
#ifdef HAVE_GETTIMEOFDAY
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
return gettimeofday(tv, NULL);
|
return gettimeofday(tv, NULL);
|
||||||
|
#elif defined(OS_IS_WIN32)
|
||||||
|
/*
|
||||||
|
* Copied from implementation by Steven Edwards (LGPL).
|
||||||
|
* Found on wine mailing list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
|
#define EPOCHFILETIME (116444736000000000i64)
|
||||||
|
#else
|
||||||
|
#define EPOCHFILETIME (116444736000000000LL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FILETIME ft;
|
||||||
|
LARGE_INTEGER li;
|
||||||
|
__int64 t;
|
||||||
|
|
||||||
|
if (tv) {
|
||||||
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
li.LowPart = ft.dwLowDateTime;
|
||||||
|
li.HighPart = ft.dwHighDateTime;
|
||||||
|
t = li.QuadPart; /* In 100-nanosecond intervals */
|
||||||
|
t -= EPOCHFILETIME; /* Offset to the Epoch time */
|
||||||
|
t /= 10; /* In microseconds */
|
||||||
|
tv->tv_sec = (long)(t / 1000000);
|
||||||
|
tv->tv_usec = (long)(t % 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
#else
|
#else
|
||||||
#error "Platform lacks gettimeofday() or equivalent function."
|
#error "Platform lacks gettimeofday() or equivalent function."
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -432,10 +536,12 @@ sensible: set the nice level to -15 and enable realtime scheduling if
|
||||||
supported.*/
|
supported.*/
|
||||||
void pa_raise_priority(void) {
|
void pa_raise_priority(void) {
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_RESOURCE_H
|
||||||
if (setpriority(PRIO_PROCESS, 0, NICE_LEVEL) < 0)
|
if (setpriority(PRIO_PROCESS, 0, NICE_LEVEL) < 0)
|
||||||
pa_log_warn(__FILE__": setpriority() failed: %s\n", strerror(errno));
|
pa_log_warn(__FILE__": setpriority() failed: %s\n", strerror(errno));
|
||||||
else
|
else
|
||||||
pa_log_info(__FILE__": Successfully gained nice level %i.\n", NICE_LEVEL);
|
pa_log_info(__FILE__": Successfully gained nice level %i.\n", NICE_LEVEL);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||||
{
|
{
|
||||||
|
|
@ -455,10 +561,21 @@ void pa_raise_priority(void) {
|
||||||
pa_log_info(__FILE__": Successfully enabled SCHED_FIFO scheduling.\n");
|
pa_log_info(__FILE__": Successfully enabled SCHED_FIFO scheduling.\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS))
|
||||||
|
pa_log_warn(__FILE__": SetPriorityClass() failed: 0x%08X\n", GetLastError());
|
||||||
|
else
|
||||||
|
pa_log_info(__FILE__": Successfully gained high priority class.\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the priority to normal, inverting the changes made by pa_raise_priority() */
|
/* Reset the priority to normal, inverting the changes made by pa_raise_priority() */
|
||||||
void pa_reset_priority(void) {
|
void pa_reset_priority(void) {
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||||
{
|
{
|
||||||
struct sched_param sp;
|
struct sched_param sp;
|
||||||
|
|
@ -468,11 +585,15 @@ void pa_reset_priority(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_RESOURCE_H
|
||||||
setpriority(PRIO_PROCESS, 0, 0);
|
setpriority(PRIO_PROCESS, 0, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the FD_CLOEXEC flag for a fd */
|
/* Set the FD_CLOEXEC flag for a fd */
|
||||||
int pa_fd_set_cloexec(int fd, int b) {
|
int pa_fd_set_cloexec(int fd, int b) {
|
||||||
|
|
||||||
|
#ifdef FD_CLOEXEC
|
||||||
int v;
|
int v;
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
|
|
||||||
|
|
@ -483,6 +604,7 @@ int pa_fd_set_cloexec(int fd, int b) {
|
||||||
|
|
||||||
if (fcntl(fd, F_SETFD, v) < 0)
|
if (fcntl(fd, F_SETFD, v) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -491,6 +613,8 @@ int pa_fd_set_cloexec(int fd, int b) {
|
||||||
* only. This shoul be used for eyecandy only, don't rely on return
|
* only. This shoul be used for eyecandy only, don't rely on return
|
||||||
* non-NULL! */
|
* non-NULL! */
|
||||||
char *pa_get_binary_name(char *s, size_t l) {
|
char *pa_get_binary_name(char *s, size_t l) {
|
||||||
|
|
||||||
|
#ifdef HAVE_READLINK
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
int i;
|
int i;
|
||||||
assert(s && l);
|
assert(s && l);
|
||||||
|
|
@ -503,6 +627,15 @@ char *pa_get_binary_name(char *s, size_t l) {
|
||||||
|
|
||||||
s[i] = 0;
|
s[i] = 0;
|
||||||
return s;
|
return s;
|
||||||
|
#elif defined(OS_IS_WIN32)
|
||||||
|
char path[PATH_MAX];
|
||||||
|
if (!GetModuleFileName(NULL, path, PATH_MAX))
|
||||||
|
return NULL;
|
||||||
|
pa_strlcpy(s, pa_path_get_filename(path), l);
|
||||||
|
return s;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a pointer to the filename inside a path (which is the last
|
/* Return a pointer to the filename inside a path (which is the last
|
||||||
|
|
@ -510,7 +643,7 @@ char *pa_get_binary_name(char *s, size_t l) {
|
||||||
char *pa_path_get_filename(const char *p) {
|
char *pa_path_get_filename(const char *p) {
|
||||||
char *fn;
|
char *fn;
|
||||||
|
|
||||||
if ((fn = strrchr(p, '/')))
|
if ((fn = strrchr(p, PATH_SEP)))
|
||||||
return fn+1;
|
return fn+1;
|
||||||
|
|
||||||
return (char*) p;
|
return (char*) p;
|
||||||
|
|
@ -684,6 +817,7 @@ int pa_uid_in_group(const char *name, gid_t *gid) {
|
||||||
|
|
||||||
/* Lock or unlock a file entirely. (advisory) */
|
/* Lock or unlock a file entirely. (advisory) */
|
||||||
int pa_lock_fd(int fd, int b) {
|
int pa_lock_fd(int fd, int b) {
|
||||||
|
#ifdef F_SETLKW
|
||||||
struct flock flock;
|
struct flock flock;
|
||||||
|
|
||||||
/* Try a R/W lock first */
|
/* Try a R/W lock first */
|
||||||
|
|
@ -704,6 +838,19 @@ int pa_lock_fd(int fd, int b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_log(__FILE__": %slock failed: %s\n", !b ? "un" : "", strerror(errno));
|
pa_log(__FILE__": %slock failed: %s\n", !b ? "un" : "", strerror(errno));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
HANDLE h = (HANDLE)_get_osfhandle(fd);
|
||||||
|
|
||||||
|
if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
|
||||||
|
return 0;
|
||||||
|
if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pa_log(__FILE__": %slock failed: 0x%08X\n", !b ? "un" : "", GetLastError());
|
||||||
|
#endif
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -795,31 +942,51 @@ int pa_unlock_lockfile(const char *fn, int fd) {
|
||||||
* allocated buffer containing the used configuration file is
|
* allocated buffer containing the used configuration file is
|
||||||
* stored there.*/
|
* stored there.*/
|
||||||
FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
|
FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
|
||||||
const char *e;
|
const char *fn;
|
||||||
char h[PATH_MAX];
|
char h[PATH_MAX];
|
||||||
|
|
||||||
if (env && (e = getenv(env))) {
|
#ifdef OS_IS_WIN32
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
|
if (!getenv(POLYP_ROOTENV))
|
||||||
|
pa_set_root(NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (env && (fn = getenv(env))) {
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
|
||||||
|
return NULL;
|
||||||
|
fn = buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
*result = pa_xstrdup(e);
|
*result = pa_xstrdup(fn);
|
||||||
return fopen(e, "r");
|
|
||||||
|
return fopen(fn, "r");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local && pa_get_home_dir(h, sizeof(h))) {
|
if (local && pa_get_home_dir(h, sizeof(h))) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *l;
|
char *lfn;
|
||||||
|
|
||||||
l = pa_sprintf_malloc("%s/%s", h, local);
|
lfn = pa_sprintf_malloc("%s/%s", h, local);
|
||||||
f = fopen(l, "r");
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX))
|
||||||
|
return NULL;
|
||||||
|
lfn = buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
f = fopen(lfn, "r");
|
||||||
|
|
||||||
if (f || errno != ENOENT) {
|
if (f || errno != ENOENT) {
|
||||||
if (result)
|
if (result)
|
||||||
*result = l;
|
*result = pa_xstrdup(lfn);
|
||||||
else
|
pa_xfree(lfn);
|
||||||
pa_xfree(l);
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_xfree(l);
|
pa_xfree(lfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!global) {
|
if (!global) {
|
||||||
|
|
@ -829,6 +996,12 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
|
||||||
|
return NULL;
|
||||||
|
global = buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
*result = pa_xstrdup(global);
|
*result = pa_xstrdup(global);
|
||||||
|
|
||||||
|
|
@ -934,21 +1107,44 @@ int pa_startswith(const char *s, const char *pfx) {
|
||||||
char *pa_runtime_path(const char *fn, char *s, size_t l) {
|
char *pa_runtime_path(const char *fn, char *s, size_t l) {
|
||||||
char u[256];
|
char u[256];
|
||||||
|
|
||||||
|
#ifndef OS_IS_WIN32
|
||||||
if (fn && *fn == '/')
|
if (fn && *fn == '/')
|
||||||
|
#else
|
||||||
|
if (fn && strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\')
|
||||||
|
#endif
|
||||||
return pa_strlcpy(s, fn, l);
|
return pa_strlcpy(s, fn, l);
|
||||||
|
|
||||||
snprintf(s, l, PA_RUNTIME_PATH_PREFIX"%s%s%s", pa_get_user_name(u, sizeof(u)), fn ? "/" : "", fn ? fn : "");
|
if (fn)
|
||||||
|
snprintf(s, l, "%s%s%c%s", PA_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PATH_SEP, fn);
|
||||||
|
else
|
||||||
|
snprintf(s, l, "%s%s", PA_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)));
|
||||||
|
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
{
|
||||||
|
char buf[l];
|
||||||
|
strcpy(buf, s);
|
||||||
|
ExpandEnvironmentStrings(buf, s, l);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait t milliseconds */
|
/* Wait t milliseconds */
|
||||||
int pa_msleep(unsigned long t) {
|
int pa_msleep(unsigned long t) {
|
||||||
|
#ifdef OS_IS_WIN32
|
||||||
|
Sleep(t);
|
||||||
|
return 0;
|
||||||
|
#elif defined(HAVE_NANOSLEEP)
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
ts.tv_sec = t/1000;
|
ts.tv_sec = t/1000;
|
||||||
ts.tv_nsec = (t % 1000) * 1000000;
|
ts.tv_nsec = (t % 1000) * 1000000;
|
||||||
|
|
||||||
return nanosleep(&ts, NULL);
|
return nanosleep(&ts, NULL);
|
||||||
|
#else
|
||||||
|
#error "Platform lacks a sleep function."
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the string s to a signed integer in *ret_i */
|
/* Convert the string s to a signed integer in *ret_i */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue