From: Jaroslav Kysela Date: Mon, 9 Feb 2004 13:07:27 +0000 (+0000) Subject: More complete code X-Git-Tag: v1.0.3~36 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=b82bf8d46f0c5fa732a9f5c08ccf85405d831d59;p=alsa-oss.git More complete code --- diff --git a/oss-redir/oss-redir.c b/oss-redir/oss-redir.c index 4e26acd..9ab0b9c 100644 --- a/oss-redir/oss-redir.c +++ b/oss-redir/oss-redir.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -35,10 +36,14 @@ static int initialized = 0; static int native_oss = 1; +static int open_count = 0; static char hal[64]; +static void *dl_handle = NULL; -int (*oss_pcm_open)(const char *pathname, int flags, ...); -int (*oss_pcm_close)(int fd); +static void initialize(void); + +static int (*x_oss_pcm_open)(const char *pathname, int flags); +static int (*x_oss_pcm_close)(int fd); ssize_t (*oss_pcm_read)(int fd, void *buf, size_t count); ssize_t (*oss_pcm_write)(int fd, const void *buf, size_t count); void * (*oss_pcm_mmap)(void *start, size_t length, int prot, int flags, int fd, off_t offset); @@ -50,8 +55,8 @@ int (*oss_pcm_poll_fds)(int fd); int (*oss_pcm_poll_prepare)(int fd, struct pollfd *ufds); int (*oss_pcm_poll_result)(int fd, struct pollfd *ufds); -int (*oss_mixer_open)(const char *pathname, int flags, ...); -int (*oss_mixer_close)(int fd); +static int (*x_oss_mixer_open)(const char *pathname, int flags); +static int (*x_oss_mixer_close)(int fd); int (*oss_mixer_ioctl)(int fd, unsigned long int request, ...); int native_pcm_select_prepare(int fd, fd_set *readfds, fd_set *writefds) @@ -107,7 +112,79 @@ int native_pcm_poll_result(int fd, struct pollfd *ufds) return result; } -static void initialize() +static inline void check_initialized(void) +{ + if (!initialized) + initialize(); +} + +int oss_pcm_open(const char *pathname, int flags, ...) +{ + int result; + + check_initialized(); + if (native_oss) + return open(pathname, flags); + result = x_oss_pcm_open(pathname, flags); + if (result >= 0) { + open_count++; + } else { + if (open_count == 0) { + dlclose(dl_handle); + dl_handle = NULL; + } + } + return result; +} + +int oss_pcm_close(int fd) +{ + int result; + + if (native_oss) + return close(fd); + result = x_oss_pcm_close(fd); + if (--open_count) + dlclose(dl_handle); + return result; +} + +int oss_mixer_open(const char *pathname, int flags, ...) +{ + int result; + + check_initialized(); + if (native_oss) + return open(pathname, flags); + result = x_oss_mixer_open(pathname, flags); + if (result >= 0) { + open_count++; + } else { + if (open_count == 0) { + dlclose(dl_handle); + dl_handle = NULL; + } + } + return result; +} + +int oss_mixer_close(int fd) +{ + int result; + + if (fd < 0) + return -EINVAL; + if (native_oss) + return close(fd); + result = x_oss_mixer_close(fd); + if (--open_count) { + dlclose(dl_handle); + dl_handle = NULL; + } + return result; +} + +static void initialize(void) { char *s = getenv("OSS_REDIRECTOR"); if (s) { @@ -119,9 +196,8 @@ static void initialize() native_oss = 1; } if (native_oss) { - oss_pcm_open = open; - oss_pcm_close = close; - oss_pcm_read = read; + __native: + oss_pcm_read = read; oss_pcm_write = write; oss_pcm_mmap = mmap; oss_pcm_munmap = munmap; @@ -131,14 +207,29 @@ static void initialize() oss_pcm_poll_fds = native_pcm_poll_fds; oss_pcm_poll_prepare = native_pcm_poll_prepare; oss_pcm_poll_result = native_pcm_poll_result; - oss_mixer_open = open; - oss_mixer_close = close; oss_mixer_ioctl = ioctl; + } else { + dl_handle = dlopen(hal, RTLD_NOW); + if (dl_handle == NULL) { + fprintf(stderr, "ERROR: dlopen failed for sound (OSS) redirector: %s\n", dlerror()); + fprintf(stderr, " reverting to native OSS mode\n"); + native_oss = 1; + goto __native; + } + x_oss_pcm_open = dlsym(dl_handle, "lib_oss_pcm_open"); + x_oss_pcm_close = dlsym(dl_handle, "lib_oss_pcm_close"); + oss_pcm_read = dlsym(dl_handle, "lib_oss_pcm_read"); + oss_pcm_write = dlsym(dl_handle, "lib_oss_pcm_write"); + oss_pcm_mmap = dlsym(dl_handle, "lib_oss_pcm_mmap"); + oss_pcm_munmap = dlsym(dl_handle, "lib_oss_pcm_munmap"); + oss_pcm_ioctl = dlsym(dl_handle, "lib_oss_pcm_ioctl"); + oss_pcm_select_prepare = dlsym(dl_handle, "lib_oss_select_prepare"); + oss_pcm_select_result = dlsym(dl_handle, "lib_oss_select_result"); + oss_pcm_poll_fds = dlsym(dl_handle, "lib_oss_poll_fds"); + oss_pcm_poll_prepare = dlsym(dl_handle, "lib_oss_poll_prepare"); + oss_pcm_poll_result = dlsym(dl_handle, "lib_oss_poll_result"); + x_oss_mixer_open = dlsym(dl_handle, "lib_oss_mixer_open"); + x_oss_mixer_close = dlsym(dl_handle, "lib_oss_mixer_close"); + oss_mixer_ioctl = dlsym(dl_handle, "lib_oss_mixer_ioctl"); } } - -static inline void check_initialized(void) -{ - if (!initialized) - initialize(); -} diff --git a/oss-redir/oss-redir.h b/oss-redir/oss-redir.h index 1035338..f99a4a7 100644 --- a/oss-redir/oss-redir.h +++ b/oss-redir/oss-redir.h @@ -28,8 +28,8 @@ struct pollfd; #define OSS_WAIT_EVENT_READ (1<<0) #define OSS_WAIT_EVENT_WRITE (1<<1) -extern int (*oss_pcm_open)(const char *pathname, int flags, ...); -extern int (*oss_pcm_close)(int fd); +extern int oss_pcm_open(const char *pathname, int flags, ...); +extern int oss_pcm_close(int fd); extern ssize_t (*oss_pcm_read)(int fd, void *buf, size_t count); extern ssize_t (*oss_pcm_write)(int fd, const void *buf, size_t count); extern void * (*oss_pcm_mmap)(void *start, size_t length, int prot, int flags, int fd, off_t offset); @@ -41,8 +41,8 @@ extern int (*oss_pcm_poll_fds)(int fd); extern int (*oss_pcm_poll_prepare)(int fd, struct pollfd *ufds); extern int (*oss_pcm_poll_result)(int fd, struct pollfd *ufds); -extern int (*oss_mixer_open)(const char *pathname, int flags, ...); -extern int (*oss_mixer_close)(int fd); +extern int oss_mixer_open(const char *pathname, int flags, ...); +extern int oss_mixer_close(int fd); extern int (*oss_mixer_ioctl)(int fd, unsigned long int request, ...);