~ubuntu-branches/ubuntu/lucid/mpg123/lucid

« back to all changes in this revision

Viewing changes to xfermem.c

Tags: upstream-0.60
ImportĀ upstreamĀ versionĀ 0.60

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *   xfermem.c
3
 
 *
4
 
 *   Oliver Fromme  <oliver.fromme@heim3.tu-clausthal.de>
5
 
 *   Sun Apr  6 02:26:26 MET DST 1997
6
 
 *
7
 
 *   See xfermem.h for documentation/description.
8
 
 */
9
 
 
10
 
#ifndef NOXFERMEM
11
 
 
12
 
#include <stdio.h>
13
 
#include <stdlib.h>
14
 
#include <string.h>
15
 
#include <unistd.h>
16
 
#include <errno.h>
17
 
#include <sys/types.h>
18
 
#include <sys/time.h>
19
 
#include <sys/uio.h>
20
 
#include <sys/mman.h>
21
 
#include <sys/socket.h>
22
 
#include <fcntl.h>
23
 
 
24
 
#ifdef AIX
25
 
#include <sys/select.h>
26
 
#endif
27
 
 
28
 
#include "mpg123.h"
29
 
 
30
 
#ifndef USE_MMAP
31
 
#include <sys/ipc.h>
32
 
#include <sys/shm.h>
33
 
#endif
34
 
 
35
 
extern int errno;
36
 
 
37
 
#if defined (USE_MMAP) && defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
38
 
#define MAP_ANON MAP_ANONYMOUS
39
 
#endif
40
 
 
41
 
void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf)
42
 
{
43
 
        int regsize = bufsize + msize + skipbuf + sizeof(txfermem);
44
 
        extern int preload;
45
 
 
46
 
#ifdef USE_MMAP
47
 
#  ifdef MAP_ANON
48
 
        if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE,
49
 
                        MAP_ANON | MAP_SHARED, -1, 0)) == (txfermem *) -1) {
50
 
                perror ("mmap()");
51
 
                exit (1);
52
 
        }
53
 
#  else
54
 
        int devzero;
55
 
        if ((devzero = open("/dev/zero", O_RDWR, 0)) == -1) {
56
 
                perror ("open(/dev/zero)");
57
 
                exit (1);
58
 
        }
59
 
        if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE,
60
 
                        MAP_SHARED, devzero, 0)) == (txfermem *) -1) {
61
 
                perror ("mmap()");
62
 
                exit (1);
63
 
        }
64
 
        close (devzero);
65
 
#  endif
66
 
#else
67
 
        struct shmid_ds shmemds;
68
 
        int shmemid;
69
 
        if ((shmemid = shmget(IPC_PRIVATE, regsize, IPC_CREAT | 0600)) == -1) {
70
 
                perror ("shmget()");
71
 
                exit (1);
72
 
        }
73
 
        if ((*xf = (txfermem *) shmat(shmemid, 0, 0)) == (txfermem *) -1) {
74
 
                perror ("shmat()");
75
 
                shmctl (shmemid, IPC_RMID, &shmemds);
76
 
                exit (1);
77
 
        }
78
 
        if (shmctl(shmemid, IPC_RMID, &shmemds) == -1) {
79
 
                perror ("shmctl()");
80
 
                xfermem_done (*xf);
81
 
                exit (1);
82
 
        }
83
 
#endif
84
 
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, (*xf)->fd) < 0) {
85
 
                perror ("socketpair()");
86
 
                xfermem_done (*xf);
87
 
                exit (1);
88
 
        }
89
 
        (*xf)->freeindex = (*xf)->readindex = 0;
90
 
        (*xf)->wakeme[0] = (*xf)->wakeme[1] = FALSE;
91
 
        (*xf)->data = ((byte *) *xf) + sizeof(txfermem) + msize;
92
 
        (*xf)->metadata = ((byte *) *xf) + sizeof(txfermem);
93
 
        (*xf)->size = bufsize;
94
 
        (*xf)->metasize = msize + skipbuf;
95
 
        preload = bufsize>>3;
96
 
}
97
 
 
98
 
void xfermem_done (txfermem *xf)
99
 
{
100
 
        if(!xf)
101
 
                return;
102
 
#ifdef USE_MMAP
103
 
        munmap ((caddr_t) xf, xf->size + xf->metasize + sizeof(txfermem));
104
 
#else
105
 
        if (shmdt((void *) xf) == -1) {
106
 
                perror ("shmdt()");
107
 
                exit (1);
108
 
        }
109
 
#endif
110
 
}
111
 
 
112
 
void xfermem_init_writer (txfermem *xf)
113
 
{
114
 
        if(xf)
115
 
                close (xf->fd[XF_READER]);
116
 
}
117
 
 
118
 
void xfermem_init_reader (txfermem *xf)
119
 
{
120
 
        if(xf)
121
 
                close (xf->fd[XF_WRITER]);
122
 
}
123
 
 
124
 
int xfermem_get_freespace (txfermem *xf)
125
 
{
126
 
        int freeindex, readindex;
127
 
 
128
 
        if(!xf)
129
 
                return 0;
130
 
 
131
 
        if ((freeindex = xf->freeindex) < 0
132
 
                        || (readindex = xf->readindex) < 0)
133
 
                return (0);
134
 
        if (readindex > freeindex)
135
 
                return ((readindex - freeindex) - 1);
136
 
        else
137
 
                return ((xf->size - (freeindex - readindex)) - 1);
138
 
}
139
 
 
140
 
int xfermem_get_usedspace (txfermem *xf)
141
 
{
142
 
        int freeindex, readindex;
143
 
 
144
 
        if(!xf)
145
 
                return 0;
146
 
 
147
 
        if ((freeindex = xf->freeindex) < 0
148
 
                        || (readindex = xf->readindex) < 0)
149
 
                return (0);
150
 
        if (freeindex >= readindex)
151
 
                return (freeindex - readindex);
152
 
        else
153
 
                return (xf->size - (readindex - freeindex));
154
 
}
155
 
 
156
 
int xfermem_getcmd (int fd, int block)
157
 
{
158
 
        fd_set selfds;
159
 
        byte cmd;
160
 
 
161
 
        for (;;) {
162
 
                struct timeval selto = {0, 0};
163
 
 
164
 
                FD_ZERO (&selfds);
165
 
                FD_SET (fd, &selfds);
166
 
#ifdef HPUX
167
 
                switch (select(FD_SETSIZE, (int *) &selfds, NULL, NULL, block ? NULL : &selto)) {
168
 
#else
169
 
                switch (select(FD_SETSIZE, &selfds, NULL, NULL, block ? NULL : &selto)) {
170
 
#endif
171
 
                        case 0:
172
 
                                if (!block)
173
 
                                        return (0);
174
 
                                continue;
175
 
                        case -1:
176
 
                                if (errno == EINTR)
177
 
                                        continue;
178
 
                                return (-2);
179
 
                        case 1:
180
 
                                if (FD_ISSET(fd, &selfds))
181
 
                                        switch (read(fd, &cmd, 1)) {
182
 
                                                case 0: /* EOF */
183
 
                                                        return (-1);
184
 
                                                case -1:
185
 
                                                        if (errno == EINTR)
186
 
                                                                continue;
187
 
                                                        return (-3);
188
 
                                                case 1:
189
 
                                                        return (cmd);
190
 
                                                default: /* ?!? */
191
 
                                                        return (-4);
192
 
                                        }
193
 
                                else /* ?!? */
194
 
                                        return (-5);
195
 
                        default: /* ?!? */
196
 
                                return (-6);
197
 
                }
198
 
        }
199
 
}
200
 
 
201
 
int xfermem_putcmd (int fd, byte cmd)
202
 
{
203
 
        for (;;) {
204
 
                switch (write(fd, &cmd, 1)) {
205
 
                        case 1:
206
 
                                return (1);
207
 
                        case -1:
208
 
                                if (errno != EINTR)
209
 
                                        return (-1);
210
 
                }
211
 
        }
212
 
}
213
 
 
214
 
int xfermem_block (int readwrite, txfermem *xf)
215
 
{
216
 
        int myfd = xf->fd[readwrite];
217
 
        int result;
218
 
 
219
 
        xf->wakeme[readwrite] = TRUE;
220
 
        if (xf->wakeme[1 - readwrite])
221
 
                xfermem_putcmd (myfd, XF_CMD_WAKEUP);
222
 
        result = xfermem_getcmd(myfd, TRUE);
223
 
        xf->wakeme[readwrite] = FALSE;
224
 
        return ((result <= 0) ? -1 : result);
225
 
}
226
 
 
227
 
#elif defined(WIN32)
228
 
#include <stdio.h>
229
 
#include <stdlib.h>
230
 
#include <string.h>
231
 
#include <errno.h>
232
 
#include <sys/types.h>
233
 
#include <fcntl.h>
234
 
 
235
 
#include "xfermem.h"
236
 
 
237
 
extern int errno;
238
 
 
239
 
void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf)
240
 
{
241
 
  return 0;
242
 
}
243
 
void xfermem_done (txfermem *xf)
244
 
{
245
 
  return 0;
246
 
}
247
 
void xfermem_init_writer (txfermem *xf)
248
 
{
249
 
  return 0;
250
 
}
251
 
void xfermem_init_reader (txfermem *xf)
252
 
{
253
 
  return 0;
254
 
}
255
 
int xfermem_get_freespace (txfermem *xf)
256
 
{
257
 
  return 0;
258
 
}
259
 
int xfermem_get_usedspace (txfermem *xf)
260
 
{
261
 
  return 0;
262
 
}
263
 
int xfermem_getcmd (int fd, int block)
264
 
{
265
 
  return 0;
266
 
}
267
 
int xfermem_putcmd (int fd, byte cmd)
268
 
{
269
 
  return 0;
270
 
}
271
 
int xfermem_block (int readwrite, txfermem *xf)
272
 
{
273
 
  return 0;
274
 
}
275
 
#endif
276
 
 
277
 
/* eof */
278