123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /*
- * 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
- 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) || defined(PLAN9)
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include "mpg123.h"
- #include "xfermem.h"
- extern int errno;
- void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf)
- {
- return;
- }
- void xfermem_done (txfermem *xf)
- {
- return;
- }
- void xfermem_init_writer (txfermem *xf)
- {
- return;
- }
- void xfermem_init_reader (txfermem *xf)
- {
- return;
- }
- 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 */
|