it's broken and it failed to load during the last few months. If anyone wants to revive it, have fun finding it back ...

Original commit message from CVS:
Remove ossgst... It's a crude hack (beyond ugly), it's broken and it failed to load during the last few months. If anyone wants to revive it, have fun finding it back in the CVS history
This commit is contained in:
Ronald S. Bultje 2003-12-14 22:48:18 +00:00
parent 7c399e62b5
commit c7177d2392
6 changed files with 2 additions and 1018 deletions

View file

@ -1,25 +1,16 @@
plugin_LTLIBRARIES = libgstossaudio.la
EXTRA_LTLIBRARIES = libgstosshelper.la
libgstossaudio_la_SOURCES = gstossaudio.c \
gstosselement.c \
gstossmixer.c \
gstosssink.c \
gstosssrc.c \
gstossgst.c
gstosssrc.c
libgstossaudio_la_CFLAGS = $(GST_CFLAGS)
libgstossaudio_la_LIBADD = $(top_builddir)/gst-libs/gst/libgstinterfaces-@GST_MAJORMINOR@.la
libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstosshelper_la_SOURCES = gstosshelper.c
libgstosshelper_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstosssink.h \
gstosssrc.h \
gstossgst.h \
gstosshelper.h \
gstosselement.h\
gstossmixer.h

View file

@ -24,40 +24,21 @@
#include "gstosselement.h"
#include "gstosssink.h"
#include "gstosssrc.h"
#include "gstossgst.h"
extern gchar *__gst_oss_plugin_dir;
static gboolean
plugin_init (GstPlugin *plugin)
{
guint i = 0;
gchar **path;
if (!gst_library_load ("gstaudio"))
return FALSE;
/* get the path of this plugin, we assume the helper progam lives in the */
/* same directory. */
path = g_strsplit (plugin->filename, G_DIR_SEPARATOR_S, 0);
while (path[i]) {
i++;
if (path[i] == NULL) {
g_free (path[i-1]);
path[i-1] = NULL;
}
}
__gst_oss_plugin_dir = g_strjoinv (G_DIR_SEPARATOR_S, path);
g_strfreev (path);
if (!gst_element_register (plugin, "ossmixer", GST_RANK_PRIMARY,
GST_TYPE_OSSELEMENT) ||
!gst_element_register (plugin, "osssrc", GST_RANK_PRIMARY,
GST_TYPE_OSSSRC) ||
!gst_element_register (plugin, "osssink", GST_RANK_PRIMARY,
GST_TYPE_OSSSINK) ||
!gst_element_register (plugin, "ossgst", GST_RANK_MARGINAL,
GST_TYPE_OSSGST)) {
GST_TYPE_OSSSINK)) {
return FALSE;
}

View file

@ -1,459 +0,0 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wim.taymans@chello.be>
*
* gstossgst.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; 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 <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include "gstossgst.h"
#include "gstosshelper.h"
static GstElementDetails gst_ossgst_details = GST_ELEMENT_DETAILS (
"Audio Wrapper (OSS)",
"Source/Audio",
"Hijacks /dev/dsp to get the output of OSS apps into GStreamer",
"Wim Taymans <wim.taymans@chello.be>"
);
static void gst_ossgst_base_init (gpointer g_class);
static void gst_ossgst_class_init (GstOssGstClass *klass);
static void gst_ossgst_init (GstOssGst *ossgst);
static GstElementStateReturn gst_ossgst_change_state (GstElement *element);
static void gst_ossgst_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_ossgst_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static GstData* gst_ossgst_get (GstPad *pad);
/* OssGst signals and args */
enum {
LAST_SIGNAL
};
enum {
ARG_0,
ARG_MUTE,
ARG_PROGRAM,
/* FILL ME */
};
static GstPadTemplate*
ossgst_src_factory (void)
{
return
gst_pad_template_new (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
gst_caps_new (
"ossgst_src",
"audio/x-raw-int",
gst_props_new (
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_LIST (
GST_PROPS_BOOLEAN (FALSE),
GST_PROPS_BOOLEAN (TRUE)
),
"width", GST_PROPS_LIST (
GST_PROPS_INT (8),
GST_PROPS_INT (16)
),
"depth", GST_PROPS_LIST (
GST_PROPS_INT (8),
GST_PROPS_INT (16)
),
"rate", GST_PROPS_INT_RANGE (8000, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
NULL)),
gst_caps_new (
"ossgst_src",
"audio/x-mulaw",
gst_props_new (
"rate", GST_PROPS_INT_RANGE (8000, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
NULL)),
gst_caps_new (
"ossgst_src",
"audio/x-alaw",
gst_props_new (
"rate", GST_PROPS_INT_RANGE (8000, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
NULL)),
NULL);
}
static GstElementClass *parent_class = NULL;
static GstPadTemplate *gst_ossgst_src_template;
gchar *__gst_oss_plugin_dir = NULL;
GType
gst_ossgst_get_type (void)
{
static GType ossgst_type = 0;
if (!ossgst_type) {
static const GTypeInfo ossgst_info = {
sizeof(GstOssGstClass),
gst_ossgst_base_init,
NULL,
(GClassInitFunc)gst_ossgst_class_init,
NULL,
NULL,
sizeof(GstOssGst),
0,
(GInstanceInitFunc)gst_ossgst_init,
};
ossgst_type = g_type_register_static (GST_TYPE_ELEMENT, "GstOssGst", &ossgst_info, 0);
}
return ossgst_type;
}
static void
gst_ossgst_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (element_class, &gst_ossgst_details);
gst_element_class_add_pad_template (element_class, GST_PAD_TEMPLATE_GET (ossgst_src_factory));
}
static void
gst_ossgst_class_init (GstOssGstClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MUTE,
g_param_spec_boolean("mute","mute","mute",
TRUE,G_PARAM_READWRITE)); /* CHECKME */
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PROGRAM,
g_param_spec_string("command","command","command",
NULL, G_PARAM_READWRITE)); /* CHECKME */
gobject_class->set_property = gst_ossgst_set_property;
gobject_class->get_property = gst_ossgst_get_property;
gstelement_class->change_state = gst_ossgst_change_state;
}
static void
gst_ossgst_init (GstOssGst *ossgst)
{
ossgst->srcpad = gst_pad_new_from_template (gst_ossgst_src_template, "src");
gst_element_add_pad (GST_ELEMENT (ossgst), ossgst->srcpad);
gst_pad_set_get_function (ossgst->srcpad, gst_ossgst_get);
ossgst->command = NULL;
}
static GstCaps*
gst_ossgst_format_to_caps (gint format, gint stereo, gint rate)
{
GstCaps *caps = NULL;
gint law = 0;
gulong endianness = G_BYTE_ORDER;
gboolean is_signed = TRUE;
gint width = 16;
gboolean supported = TRUE;
GST_DEBUG ("have format 0x%08x %d %d", format, stereo, rate);
switch (format) {
case AFMT_MU_LAW:
law = 1;
break;
case AFMT_A_LAW:
law = 2;
break;
case AFMT_U8:
width = 8;
is_signed = FALSE;
break;
case AFMT_S16_LE:
width = 16;
endianness = G_LITTLE_ENDIAN;
is_signed = TRUE;
break;
case AFMT_S16_BE:
endianness = G_BIG_ENDIAN;
width = 16;
is_signed = TRUE;
break;
case AFMT_S8:
width = 8;
is_signed = TRUE;
break;
case AFMT_U16_LE:
width = 16;
endianness = G_LITTLE_ENDIAN;
is_signed = FALSE;
break;
case AFMT_U16_BE:
width = 16;
endianness = G_BIG_ENDIAN;
is_signed = FALSE;
break;
case AFMT_IMA_ADPCM:
case AFMT_MPEG:
#ifdef AFMT_AC3
case AFMT_AC3:
#endif
default:
supported = FALSE;
break;
}
if (supported) {
switch (law) {
case 0:
caps = gst_caps_new (
"ossgst_caps",
"audio/x-raw-int",
gst_props_new (
"endianness", GST_PROPS_INT (endianness),
"signed", GST_PROPS_BOOLEAN (is_signed),
"width", GST_PROPS_INT (width),
"depth", GST_PROPS_INT (width),
"rate", GST_PROPS_INT (rate),
"channels", GST_PROPS_INT (stereo?2:1),
NULL));
break;
case 1:
caps = gst_caps_new (
"ossgst_caps",
"audio/x-mulaw",
gst_props_new (
"rate", GST_PROPS_INT (rate),
"channels", GST_PROPS_INT (stereo?2:1),
NULL));
break;
case 2:
caps = gst_caps_new (
"ossgst_caps",
"audio/x-alaw",
gst_props_new (
"rate", GST_PROPS_INT (rate),
"channels", GST_PROPS_INT (stereo?2:1),
NULL));
break;
}
}
else {
g_warning ("gstossgst: program tried to use unsupported format %x\n", format);
}
return caps;
}
static GstData*
gst_ossgst_get (GstPad *pad)
{
GstOssGst *ossgst;
GstBuffer *buf = NULL;
command cmd;
gboolean have_data = FALSE;
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
/* this has to be an audio buffer */
ossgst = GST_OSSGST (gst_pad_get_parent (pad));
while (!have_data) {
/* read the command */
read (ossgst->fdout[0], &cmd, sizeof (command));
switch (cmd.id) {
case CMD_DATA:
buf = gst_buffer_new ();
GST_BUFFER_SIZE (buf) = cmd.cmd.length;
GST_BUFFER_DATA (buf) = g_malloc (GST_BUFFER_SIZE (buf));
GST_BUFFER_SIZE (buf) = read (ossgst->fdout[0], GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
have_data = TRUE;
break;
case CMD_FORMAT:
{
GstCaps *caps;
caps = gst_ossgst_format_to_caps (cmd.cmd.format.format,
cmd.cmd.format.stereo,
cmd.cmd.format.rate);
gst_pad_try_set_caps (ossgst->srcpad, caps);
}
break;
default:
break;
}
}
return GST_DATA (buf);
}
static void
gst_ossgst_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
GstOssGst *ossgst;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_OSSGST (object));
ossgst = GST_OSSGST (object);
switch (prop_id) {
case ARG_MUTE:
ossgst->mute = g_value_get_boolean (value);
break;
case ARG_PROGRAM:
if (ossgst->command)
g_free (ossgst->command);
ossgst->command = g_strdup (g_value_get_string (value));
break;
default:
break;
}
}
static void
gst_ossgst_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
GstOssGst *ossgst;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_OSSGST (object));
ossgst = GST_OSSGST (object);
switch (prop_id) {
case ARG_MUTE:
g_value_set_boolean (value, ossgst->mute);
break;
case ARG_PROGRAM:
g_value_set_string (value, ossgst->command);
break;
default:
break;
}
}
static gboolean
gst_ossgst_spawn_process (GstOssGst *ossgst)
{
static gchar *ld_preload;
pipe(ossgst->fdin);
pipe(ossgst->fdout);
GST_DEBUG ("about to fork");
if((ossgst->childpid = fork()) == -1)
{
perror("fork");
gst_element_error(GST_ELEMENT(ossgst),"forking");
return FALSE;
}
GST_DEBUG ("forked %d", ossgst->childpid);
if(ossgst->childpid == 0)
{
gchar **args;
GST_DEBUG ("fork command %d", ossgst->childpid);
ld_preload = getenv ("LD_PRELOAD");
if (ld_preload == NULL) {
ld_preload = "";
}
ld_preload = g_strconcat (ld_preload, " ", __gst_oss_plugin_dir, G_DIR_SEPARATOR_S,
"libgstosshelper.so", NULL);
setenv ("LD_PRELOAD", ld_preload, TRUE);
/* child */
dup2(ossgst->fdin[0], HELPER_MAGIC_IN); /* set the childs input stream */
dup2(ossgst->fdout[1], HELPER_MAGIC_OUT); /* set the childs output stream */
/* split the arguments */
args = g_strsplit (ossgst->command, " ", 0);
execvp(args[0], args);
/* will only reach if error */
perror("exec");
gst_element_error(GST_ELEMENT(ossgst),"starting child process");
return FALSE;
}
GST_FLAG_SET(ossgst,GST_OSSGST_OPEN);
return TRUE;
}
static gboolean
gst_ossgst_kill_process (GstOssGst *ossgst)
{
return TRUE;
}
static GstElementStateReturn
gst_ossgst_change_state (GstElement *element)
{
g_return_val_if_fail (GST_IS_OSSGST (element), FALSE);
if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
if (GST_FLAG_IS_SET (element, GST_OSSGST_OPEN))
gst_ossgst_kill_process (GST_OSSGST (element));
} else {
if (!GST_FLAG_IS_SET (element, GST_OSSGST_OPEN)) {
if (!gst_ossgst_spawn_process (GST_OSSGST (element))) {
return GST_STATE_FAILURE;
}
}
}
if (GST_ELEMENT_CLASS (parent_class)->change_state)
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
return GST_STATE_SUCCESS;
}

View file

@ -1,84 +0,0 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* gstossgst.h:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_OSSGST_H__
#define __GST_OSSGST_H__
#include <gst/gst.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_OSSGST \
(gst_ossgst_get_type())
#define GST_OSSGST(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSSGST,GstOssGst))
#define GST_OSSGST_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSSGST,GstOssGstClass))
#define GST_IS_OSSGST(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSSGST))
#define GST_IS_OSSGST_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSSGST))
typedef enum {
GST_OSSGST_OPEN = GST_ELEMENT_FLAG_LAST,
GST_OSSGST_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2,
} GstOssGstFlags;
typedef struct _GstOssGst GstOssGst;
typedef struct _GstOssGstClass GstOssGstClass;
struct _GstOssGst {
GstElement element;
GstPad *srcpad;
gint fdout[2];
gint fdin[2];
pid_t childpid;
/* soundcard state */
gboolean mute;
gchar *command;
};
struct _GstOssGstClass {
GstElementClass parent_class;
/* signals */
};
GType gst_ossgst_get_type(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_OSSGST_H__ */

View file

@ -1,401 +0,0 @@
/* Evil evil evil hack to get OSS apps to cooperate with esd
* Copyright (C) 1998, 1999 Manish Singh <yosh@gimp.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*#define DSP_DEBUG */
/* This lets you run multiple instances of x11amp by setting the X11AMPNUM
environment variable. Only works on glibc2.
*/
/* #define MULTIPLE_X11AMP */
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#ifdef DSP_DEBUG
#define DPRINTF(format, args...) printf(format, ## args)
#else
#define DPRINTF(format, args...)
#endif
#include "config.h"
#include <dlfcn.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#ifdef HAVE_MACHINE_SOUNDCARD_H
# include <machine/soundcard.h>
#else
# ifdef HAVE_SOUNDCARD_H
# include <soundcard.h>
# else
# include <sys/soundcard.h>
# endif
#endif
#include "gstosshelper.h"
/* 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(__bsdi__)
typedef unsigned long request_t;
#else
typedef int request_t;
#endif
static int sndfd = -1;
static int new_format = 1;
static int fmt = AFMT_S16_LE;
static int speed = 44100;
static int stereo = 1;
int
open (const char *pathname, int flags, ...)
{
static int (*func) (const char *, int, mode_t) = NULL;
va_list args;
mode_t mode;
if (!func)
func = (int (*) (const char *, int, mode_t)) dlsym (REAL_LIBC, "open");
va_start (args, flags);
mode = va_arg (args, mode_t);
va_end (args);
if (!strcmp (pathname, "/dev/dsp")) {
DPRINTF ("hijacking /dev/dsp open, and taking it to GStreamer...\n");
return (sndfd = HELPER_MAGIC_SNDFD);
}
return (sndfd = (*func) (pathname, flags, mode));
}
static int
dspctl (int fd, request_t request, void *argp)
{
int *arg = (int *) argp;
DPRINTF ("hijacking /dev/dsp ioctl, and sending it to GStreamer "
"(%d : %x - %p)\n", fd, request, argp);
switch (request)
{
case SNDCTL_DSP_RESET:
case SNDCTL_DSP_POST:
break;
case SNDCTL_DSP_SETFMT:
fmt = *arg;
new_format = 1;
break;
case SNDCTL_DSP_SPEED:
speed = *arg;
new_format = 1;
break;
case SNDCTL_DSP_STEREO:
stereo = *arg;
new_format = 1;
break;
case SNDCTL_DSP_GETBLKSIZE:
*arg = 4096;
break;
case SNDCTL_DSP_GETFMTS:
*arg = 0x38;
break;
#ifdef SNDCTL_DSP_GETCAPS
case SNDCTL_DSP_GETCAPS:
*arg = 0;
break;
#endif
case SNDCTL_DSP_GETOSPACE:
{
audio_buf_info *bufinfo = (audio_buf_info *) argp;
bufinfo->bytes = 4096;
}
break;
default:
DPRINTF ("unhandled /dev/dsp ioctl (%x - %p)\n", request, argp);
break;
}
return 0;
}
void *
mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)
{
static void * (*func) (void *, size_t, int, int, int, off_t) = NULL;
if (!func)
func = (void * (*) (void *, size_t, int, int, int, off_t)) dlsym (REAL_LIBC, "mmap");
if ((fd == sndfd) && (sndfd != -1))
{
DPRINTF("MMAP: oops... we're in trouble here. /dev/dsp mmap()ed. Not supported yet.\n");
errno = EACCES;
return (void *)-1; /* Better causing an error than silently not working, in this case */
}
return (*func) (start, length, prot, flags, fd, offset);
}
ssize_t
write (int fd, const void *buf, size_t len)
{
static int (*func) (int, const void *, size_t) = NULL;
command cmd;
if (!func)
func = (int (*) (int, const void *, size_t)) dlsym (REAL_LIBC, "write");
if ((fd != sndfd) || (sndfd == -1))
{
return (*func) (fd, buf, len);
}
DPRINTF("WRITE: called for %d bytes\n", len);
if (new_format) {
new_format = 0;
cmd.id = CMD_FORMAT;
cmd.cmd.format.format = fmt;
cmd.cmd.format.stereo = stereo;
cmd.cmd.format.rate = speed;
(*func) (HELPER_MAGIC_OUT, &cmd, sizeof(command));
}
cmd.id = CMD_DATA;
cmd.cmd.length = len;
(*func) (HELPER_MAGIC_OUT, &cmd, sizeof(command));
(*func) (HELPER_MAGIC_OUT, buf, len);
/*return (*func) (fd, buf, len); */
return len;
}
int
select (int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
{
static int (*func) (int, fd_set *, fd_set *, fd_set *, struct timeval *) = NULL;
if (!func)
func = (int (*) (int, fd_set *, fd_set *, fd_set *, struct timeval *)) dlsym (REAL_LIBC, "select");
if (n == sndfd) {
DPRINTF ("audiooss: hijacking /dev/dsp select() [output]\n");
}
return (*func) (n, readfds, writefds, exceptfds, timeout);
}
int
dup2 (int oldfd, int newfd)
{
static int (*func) (int, int) = NULL;
if (!func)
func = (int (*) (int, int)) dlsym (REAL_LIBC, "dup2");
if ((oldfd == sndfd) && (oldfd != -1) && (newfd != -1))
{
DPRINTF("dup2(%d,%d) (oldfd == sndfd) called\n", oldfd, newfd);
/* Do not close(newfd) as that would mark it available for reuse by the system -
* just tell the program that yes, we got the fd you asked for. Hackish. */
sndfd = newfd;
return newfd;
}
return (*func) (oldfd, newfd);
}
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 dspctl (fd, request, argp);
return (*func) (fd, request, argp);
}
int
fcntl(int fd, int cmd, ...)
{
static int (*func) (int, int, void *) = NULL;
va_list args;
void *argp;
if (!func)
func = (int (*) (int, int, void *)) dlsym (REAL_LIBC, "fcntl");
va_start (args, cmd);
argp = va_arg (args, void *);
va_end (args);
if ((fd != -1) && (fd == sndfd))
{
DPRINTF ("hijacking /dev/dsp fcntl() "
"(%d : %x - %p)\n", fd, cmd, argp);
if (cmd == F_GETFL) return O_RDWR;
if (cmd == F_GETFD) return sndfd;
return 0;
}
else
{
return (*func) (fd, cmd, argp);
}
return 0;
}
int
close (int fd)
{
static int (*func) (int) = NULL;
if (!func)
func = (int (*) (int)) dlsym (REAL_LIBC, "close");
if (fd == sndfd)
sndfd = -1;
return (*func) (fd);
}
#ifdef MULTIPLE_X11AMP
#include <socketbits.h>
#include <sys/param.h>
#include <sys/un.h>
#define ENVSET "X11AMPNUM"
int
unlink (const char *filename)
{
static int (*func) (const char *) = NULL;
char *num;
if (!func)
func = (int (*) (const char *)) dlsym (REAL_LIBC, "unlink");
if (!strcmp (filename, "/tmp/X11Amp_CTRL") && (num = getenv (ENVSET)))
{
char buf[PATH_MAX] = "/tmp/X11Amp_CTRL";
strcat (buf, num);
return (*func) (buf);
}
else
return (*func) (filename);
}
typedef int (*sa_func_t) (int, struct sockaddr *, int);
static int
sockaddr_mangle (sa_func_t func, int fd, struct sockaddr *addr, int len)
{
char *num;
if (!strcmp (((struct sockaddr_un *) addr)->sun_path, "/tmp/X11Amp_CTRL")
&& (num = getenv(ENVSET)))
{
int ret;
char buf[PATH_MAX] = "/tmp/X11Amp_CTRL";
struct sockaddr_un *new_addr = malloc (len);
strcat (buf, num);
memcpy (new_addr, addr, len);
strcpy (new_addr->sun_path, buf);
ret = (*func) (fd, (struct sockaddr *) new_addr, len);
free (new_addr);
return ret;
}
else
return (*func) (fd, addr, len);
}
int
bind (int fd, struct sockaddr *addr, int len)
{
static sa_func_t func = NULL;
if (!func)
func = (sa_func_t) dlsym (REAL_LIBC, "bind");
return sockaddr_mangle (func, fd, addr, len);
}
int
connect (int fd, struct sockaddr *addr, int len)
{
static sa_func_t func = NULL;
if (!func)
func = (sa_func_t) dlsym (REAL_LIBC, "connect");
return sockaddr_mangle (func, fd, addr, len);
}
#endif /* MULTIPLE_X11AMP */
#else /* __GNUC__ */
static char *ident = NULL;
void
nogcc (void)
{
ident = NULL;
}
#endif /* __GNUC__ */

View file

@ -1,44 +0,0 @@
/* Evil evil evil hack to get OSS apps to cooperate with esd
* Copyright (C) 1998, 1999 Manish Singh <yosh@gimp.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_OSSGST_HELPER_H__
#define __GST_OSSGST_HELPER_H__
#define HELPER_MAGIC_IN 500
#define HELPER_MAGIC_OUT 501
#define HELPER_MAGIC_SNDFD 502
#define CMD_DATA 1
#define CMD_FORMAT 2
typedef struct {
char id;
union {
unsigned int length;
struct {
int format;
int stereo;
int rate;
} format;
} cmd;
} command;
#endif /* __GST_OSSGST_HELPER_H__ */