diff -Nur oss2jack.old/oss2jack.c oss2jack/oss2jack.c --- oss2jack.old/oss2jack.c 2006-09-24 17:52:47.000000000 +0200 +++ oss2jack/oss2jack.c 2006-09-24 18:04:29.000000000 +0200 @@ -628,6 +628,9 @@ info->restart_interval = 2; } +#ifdef OSS2JACK_WRAPPER +static char buf[255]; +#endif /* OSS2JACK_WRAPPER */ void jack_init(struct device_info* info) { @@ -635,7 +638,13 @@ jack_set_error_function(jack_error); +#ifdef OSS2JACK_WRAPPER + /* We need distinct names for different clients, pid is perfect for that */ + snprintf(buf, 255, "oss-dsp wrapper (%d)", getpid()); + info->client = jack_client_new(buf); +#else info->client = jack_client_new("oss-dsp"); +#endif /*OSS2JACK_WRAPPER*/ if(info->client == NULL) { @@ -724,14 +733,20 @@ * @param argv Array of string containing the arguments * @return Program return value */ +#ifndef OSS2JACK_WRAPPER int main(int argc, char *argv[]) +#else +struct device_info* oss2jack_init(void) +#endif { int dspnum, detach; pthread_t thread; pthread_attr_t thread_attributes; +#ifndef OSS2JACK_WRAPPER // Allow users to provide some options parse_arguments(argc, argv, &detach, &dspnum); +#endif /* !OSS2JACK_WRAPPER */ mlockall(MCL_CURRENT | MCL_FUTURE); @@ -757,6 +772,7 @@ pthread_attr_init(&thread_attributes); pthread_create(&thread, &thread_attributes, jack_restart_thread, info); +#ifndef OSS2JACK_WRAPPER int dsp_fd = 0; int mixer_fd = 0; char dsp_device[20]; @@ -816,4 +832,9 @@ fusd_unregister(mixer_fd); pthread_mutex_destroy(&info->mutex); return 0; +#else /* !OSS2JACK_WRAPPER */ + + setscheduler(); + return info; +#endif /* !OSS2JACK_WRAPPER */ } diff -Nur oss2jack.old/oss2jackdsp.c oss2jack/oss2jackdsp.c --- oss2jack.old/oss2jackdsp.c 1970-01-01 01:00:00.000000000 +0100 +++ oss2jack/oss2jackdsp.c 2006-09-24 18:05:11.000000000 +0200 @@ -0,0 +1,372 @@ +/* + Copyright (C) 2006 Fabian Franz + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "oss2jack.h" + +#include +#include +#include +#include +#include + +#include "fcntl.h" + +#include +#include + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + +#define _GNU_SOURCE 1 + +/* #define DSP_DEBUG */ + +#ifdef DSP_DEBUG +#define DPRINTF(format, args...) printf(format, ## args) +#else +#define DPRINTF(format, args...) +#endif + +/* BSDI has this functionality, but not define :() */ +#if defined(RTLD_NEXT) +#define REAL_LIBC RTLD_NEXT +#else +#define REAL_LIBC ((void *) -1L) +#endif + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__bsdi__) +typedef unsigned long request_t; +#else +typedef int request_t; +#endif + +/* + * FUSD - Compatibility layer part + */ + +static struct fusd_file_info file; + +struct device_info* oss2jack_init(); + +static int fusd_inited = 0; + +static void fusd_init(void) +{ + if (fusd_inited) + return; + + file.device_info = oss2jack_init(); + file.private_data = NULL; + file.flags = 0; + file.pid = getpid(); + file.uid = getuid(); + file.gid = getgid(); + file.fd = -1; + file.fusd_msg = NULL; + fusd_inited = 1; +} + +/* ... We assume here that the using oss process is single threaded ... */ + +static int fusd_ret = -FUSD_NOREPLY; + +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; + +int fusd_return(struct fusd_file_info *file, ssize_t retval) +{ + /* Knock, Knock ... Wake up Neo */ + + pthread_mutex_lock(&cond_mutex); + + fusd_ret=retval; + + pthread_cond_signal(&cond); + pthread_mutex_unlock(&cond_mutex); + + return 0; +} + +int fusd_block(struct fusd_file_info *file) +{ + int ret; + + pthread_mutex_lock(&cond_mutex); + if (fusd_ret == -FUSD_NOREPLY) + pthread_cond_wait(&cond, &cond_mutex); + pthread_mutex_unlock(&cond_mutex); + + ret = fusd_ret; + fusd_ret = -FUSD_NOREPLY; + + return ret; +} + +void fusd_destroy(struct fusd_file_info *file) +{ + pthread_mutex_lock(&cond_mutex); + + fusd_ret=-EOF; + + pthread_cond_broadcast(&cond); + pthread_mutex_unlock(&cond_mutex); + + return; +} + + +static int sndfd = -1; + +typedef int (*open_funcptr_t) (const char *, int, mode_t); + + +/* The wrap_* functions act as wrapper for both the 32-bit versions of + * the functions (open/mmap/fopen), as well as for the 64-bit ones + * (open64/mmap64/fopen64). Just to avoid massive code duplication. + * -- Sebastian Schmidt , 2005-12-15 + */ +static int +wrap_open (const char *symname, open_funcptr_t *func, const char *pathname, + int flags, mode_t mode) +{ + if (!*func) { + *func = (open_funcptr_t) dlsym (REAL_LIBC, symname); + } + + if (!strcmp (pathname, "/dev/dsp")) + { + int err; + + fusd_init(); + DPRINTF ("hijacking /dev/dsp %s, and taking it to esd...\n", symname); + + file.flags = flags; + err=do_dsp_open(&file); + + if (err) + return err; + + return (sndfd = open ("/dev/null", flags, mode)); + } + else + return (**func) (pathname, flags, mode); +} + +int +open (const char *pathname, int flags, ...) +{ + static open_funcptr_t func = NULL; + mode_t mode = 0; + va_list args; + + if (flags & O_CREAT) { + va_start(args, flags); + mode = va_arg(args, mode_t); + va_end(args); + } + + return wrap_open("open", &func, pathname, flags, mode); +} + +#ifdef HAVE_OPEN64 +int +open64 (const char *pathname, int flags, ...) +{ + static open_funcptr_t func = NULL; + mode_t mode = 0; + va_list args; + + if (flags & O_CREAT) { + va_start(args, flags); + mode = va_arg(args, mode_t); + va_end(args); + } + + return wrap_open("open64", &func, pathname, flags, mode); +} +#endif + +int +write (int fd, const void* data, size_t len) +{ + int ret; + static int (*func) (int, const void*, size_t) = NULL; + + if (!func) + func = (int (*) (int, const void*, size_t)) dlsym (REAL_LIBC, "write"); + + if (fd != sndfd || sndfd == -1) + return (*func)(fd, data, len); + + ret=do_dsp_write(&file, data, len, 0); + + if ( ret == -FUSD_NOREPLY ) + return fusd_block(&file); + + return ret; +} + +int +ioctl (int fd, request_t request, ...) +{ + static int (*func) (int, request_t, void *) = NULL; + va_list args; + void *argp; + + if (!func) + func = (int (*) (int, request_t, void *)) dlsym (REAL_LIBC, "ioctl"); + va_start (args, request); + argp = va_arg (args, void *); + va_end (args); + + if (fd == sndfd) + return do_dsp_ioctl (&file, request, argp); + else + return (*func) (fd, request, argp); +} + +int +close (int fd) +{ + static int (*func) (int) = NULL; + + if (!func) + func = (int (*) (int)) dlsym (REAL_LIBC, "close"); + + if (fd == sndfd) + { + sndfd = -1; + do_dsp_close(&file); + } + + return (*func) (fd); +} + +/* +typedef void *(*mmap_funcptr_t) (void *, size_t, int, int, int, off_t); + +void * +wrap_mmap (const char *symname, mmap_funcptr_t *func, void *start, + size_t length, int prot, int flags, int fd, off_t offset) +{ + if (!*func) + *func = (mmap_funcptr_t) dlsym (REAL_LIBC, symname); + + if(fd != sndfd || sndfd == -1) + return (**func)(start,length,prot,flags,fd,offset); + else + { + return -EINVAL; //FIXME + } +} + +void * +mmap (void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + static mmap_funcptr_t func = NULL; + return wrap_mmap("mmap", &func, start, length, prot, flags, fd, offset); +} + +#ifdef HAVE_MMAP64 +void * +mmap64 (void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + static mmap_funcptr_t func = NULL; + return wrap_mmap("mmap64", &func, start, length, prot, flags, fd, offset); +} +#endif + + +int +munmap (void *start, size_t length) +{ + static int (*func) (void *, size_t) = NULL; + + if (!func) + func = (int (*) (void *, size_t)) dlsym (REAL_LIBC, "munmap"); + + if(start != mmapemu_obuffer || mmapemu_obuffer == 0) + return (*func)(start,length); + + DPRINTF ("esddsp: /dev/dsp munmap...\n"); + mmapemu_obuffer = NULL; + mmap_active = 0; + esd_play_start.tv_sec = 0; + free(start); + + return 0; +}*/ + +#undef ESDDSP_STDIO_EMU + +#if ESDDSP_STDIO_EMU +/* + * use #include rather than linking, because we want to keep everything + * static inside esddsp to be sure that we don't override application symbols + */ +#include "stdioemu.c" + +typdef FILE *(*fopen_funcptr_t) (const char *, const char *); + +FILE * +wrap_fopen (const char *symname, fopen_funcptr_t *func, const char *pathname, + const char *mode) +{ + static FILE *(*func) (const char *, const char *) = NULL; + + if (!*func) { + *func = (fopen_funcptr_t) dlsym (REAL_LIBC, symname); + dsp_init (); + } + + if (!strcmp (pathname, "/dev/dsp")) + { + return fake_fopen(pathname,mode); + } + else if (use_mixer && !strcmp (pathname, "/dev/mixer")) + { + return fake_fopen(pathname,mode); + } + else + return (**func) (pathname, mode); +} +FILE * +fopen(const char *pathname, const char *mode) +{ + static fopen_funcptr_t func; + return wrap_fopen("fopen", &func, pathname, mode); +} + +#ifdef HAVE_FOPEN64 +FILE * +fopen64(const char *pathname, const char *mode) +{ + static fopen_funcptr_t func; + return wrap_fopen("fopen64", &func, pathname, mode); +} +#endif +#endif + +#else /* __GNUC__ */ + +void +nogcc (void) +{ + ident = NULL; +} + +#endif