summaryrefslogtreecommitdiffstats
path: root/mpg123_artsplugin/mpg123/xfermem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mpg123_artsplugin/mpg123/xfermem.c')
-rw-r--r--mpg123_artsplugin/mpg123/xfermem.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/mpg123_artsplugin/mpg123/xfermem.c b/mpg123_artsplugin/mpg123/xfermem.c
new file mode 100644
index 00000000..8e43dab4
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/xfermem.c
@@ -0,0 +1,275 @@
+/*
+ * xfermem.c
+ *
+ * Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
+ * Sun Apr 6 02:26:26 MET DST 1997
+ *
+ * See xfermem.h for documentation/description.
+ */
+
+#ifndef NOXFERMEM
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+
+#ifdef AIX
+#include <sys/select.h>
+#endif
+
+#include "mpg123.h"
+
+#ifndef USE_MMAP
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+
+extern int errno;
+
+#if defined (USE_MMAP) && defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+
+void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf)
+{
+ int regsize = bufsize + msize + skipbuf + sizeof(txfermem);
+ extern int preload;
+
+#ifdef USE_MMAP
+# ifdef MAP_ANON
+ if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == (txfermem *) -1) {
+ perror ("mmap()");
+ exit (1);
+ }
+# else
+ int devzero;
+ if ((devzero = open("/dev/zero", O_RDWR, 0)) == -1) {
+ perror ("open(/dev/zero)");
+ exit (1);
+ }
+ if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE,
+ MAP_SHARED, devzero, 0)) == (txfermem *) -1) {
+ perror ("mmap()");
+ exit (1);
+ }
+ close (devzero);
+# endif
+#else
+ struct shmid_ds shmemds;
+ int shmemid;
+ if ((shmemid = shmget(IPC_PRIVATE, regsize, IPC_CREAT | 0600)) == -1) {
+ perror ("shmget()");
+ exit (1);
+ }
+ if ((*xf = (txfermem *) shmat(shmemid, 0, 0)) == (txfermem *) -1) {
+ perror ("shmat()");
+ shmctl (shmemid, IPC_RMID, &shmemds);
+ exit (1);
+ }
+ if (shmctl(shmemid, IPC_RMID, &shmemds) == -1) {
+ perror ("shmctl()");
+ xfermem_done (*xf);
+ exit (1);
+ }
+#endif
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, (*xf)->fd) < 0) {
+ perror ("socketpair()");
+ xfermem_done (*xf);
+ exit (1);
+ }
+ (*xf)->freeindex = (*xf)->readindex = 0;
+ (*xf)->wakeme[0] = (*xf)->wakeme[1] = FALSE;
+ (*xf)->data = ((byte *) *xf) + sizeof(txfermem) + msize;
+ (*xf)->metadata = ((byte *) *xf) + sizeof(txfermem);
+ (*xf)->size = bufsize;
+ (*xf)->metasize = msize + skipbuf;
+ preload = bufsize>>3;
+}
+
+void xfermem_done (txfermem *xf)
+{
+ if(!xf)
+ return;
+#ifdef USE_MMAP
+ munmap ((caddr_t) xf, xf->size + xf->metasize + sizeof(txfermem));
+#else
+ if (shmdt((void *) xf) == -1) {
+ perror ("shmdt()");
+ exit (1);
+ }
+#endif
+}
+
+void xfermem_init_writer (txfermem *xf)
+{
+ if(xf)
+ close (xf->fd[XF_READER]);
+}
+
+void xfermem_init_reader (txfermem *xf)
+{
+ if(xf)
+ close (xf->fd[XF_WRITER]);
+}
+
+int xfermem_get_freespace (txfermem *xf)
+{
+ int freeindex, readindex;
+
+ if(!xf)
+ return 0;
+
+ if ((freeindex = xf->freeindex) < 0
+ || (readindex = xf->readindex) < 0)
+ return (0);
+ if (readindex > freeindex)
+ return ((readindex - freeindex) - 1);
+ else
+ return ((xf->size - (freeindex - readindex)) - 1);
+}
+
+int xfermem_get_usedspace (txfermem *xf)
+{
+ int freeindex, readindex;
+
+ if(!xf)
+ return 0;
+
+ if ((freeindex = xf->freeindex) < 0
+ || (readindex = xf->readindex) < 0)
+ return (0);
+ if (freeindex >= readindex)
+ return (freeindex - readindex);
+ else
+ return (xf->size - (readindex - freeindex));
+}
+
+int xfermem_getcmd (int fd, int block)
+{
+ fd_set selfds;
+ byte cmd;
+
+ for (;;) {
+ struct timeval selto = {0, 0};
+
+ FD_ZERO (&selfds);
+ FD_SET (fd, &selfds);
+ /* #ifdef HPUX */ /* seems to trigger performance problems? strange */
+#if 0
+ switch (select(FD_SETSIZE, (int *) &selfds, NULL, NULL, block ? NULL : &selto)) {
+#else
+ switch (select(FD_SETSIZE, &selfds, NULL, NULL, block ? NULL : &selto)) {
+#endif
+ case 0:
+ if (!block)
+ return (0);
+ continue;
+ case -1:
+ if (errno == EINTR)
+ continue;
+ return (-2);
+ case 1:
+ if (FD_ISSET(fd, &selfds))
+ switch (read(fd, &cmd, 1)) {
+ case 0: /* EOF */
+ return (-1);
+ case -1:
+ if (errno == EINTR)
+ continue;
+ return (-3);
+ case 1:
+ return (cmd);
+ default: /* ?!? */
+ return (-4);
+ }
+ else /* ?!? */
+ return (-5);
+ default: /* ?!? */
+ return (-6);
+ }
+ }
+}
+
+int xfermem_putcmd (int fd, byte cmd)
+{
+ for (;;) {
+ switch (write(fd, &cmd, 1)) {
+ case 1:
+ return (1);
+ case -1:
+ if (errno != EINTR)
+ return (-1);
+ }
+ }
+}
+
+int xfermem_block (int readwrite, txfermem *xf)
+{
+ int myfd = xf->fd[readwrite];
+ int result;
+
+ xf->wakeme[readwrite] = TRUE;
+ if (xf->wakeme[1 - readwrite])
+ xfermem_putcmd (myfd, XF_CMD_WAKEUP);
+ result = xfermem_getcmd(myfd, TRUE);
+ xf->wakeme[readwrite] = FALSE;
+ return ((result <= 0) ? -1 : result);
+}
+
+#elif defined(WIN32)
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "mpg123.h"
+
+extern int errno;
+
+void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf)
+{
+}
+void xfermem_done (txfermem *xf)
+{
+}
+void xfermem_init_writer (txfermem *xf)
+{
+}
+void xfermem_init_reader (txfermem *xf)
+{
+}
+int xfermem_get_freespace (txfermem *xf)
+{
+ return 0;
+}
+int xfermem_get_usedspace (txfermem *xf)
+{
+ return 0;
+}
+int xfermem_getcmd (int fd, int block)
+{
+ return 0;
+}
+int xfermem_putcmd (int fd, byte cmd)
+{
+ return 0;
+}
+int xfermem_block (int readwrite, txfermem *xf)
+{
+ return 0;
+}
+#endif
+
+/* eof */
+