"Fossies" - the Fresh Open Source Software Archive 
Member "alsa-oss-1.1.8/alsa/alsa-oss.c" (7 Jan 2019, 18801 Bytes) of package /linux/misc/alsa-oss-1.1.8.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "alsa-oss.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.0.28_vs_1.1.6.
1 /*
2 * OSS -> ALSA compatibility layer
3 * Copyright (c) by Abramo Bagnara <abramo@alsa-project.org>,
4 * Jaroslav Kysela <perex@perex.cz>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23 #define _GNU_SOURCE
24
25 #include <sys/types.h>
26 #include <sys/time.h>
27 #include <sys/stat.h>
28 #include <sys/poll.h>
29 #include <sys/select.h>
30 #include <sys/mman.h>
31 #include <stdarg.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <dlfcn.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <limits.h>
39 #include <errno.h>
40 #include <assert.h>
41
42 #include "alsa-oss-emul.h"
43
44 #ifndef ATTRIBUTE_UNUSED
45 /** do not print warning (gcc) when function parameter is not used */
46 #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
47 #endif
48
49 #if 1
50 #define DEBUG_POLL
51 #define DEBUG_SELECT
52 #ifdef NEW_MACRO_VARARGS
53 #define DEBUG(...) do { if (oss_wrapper_debug) fprintf(stderr, __VA_ARGS__); } while (0)
54 #else /* !NEW_MACRO_VARARGS */
55 #define DEBUG(args...) do { if (oss_wrapper_debug) fprintf(stderr, ##args); } while (0)
56 #endif
57 #else
58 #ifdef NEW_MACRO_VARARGS
59 #define DEBUG(...)
60 #else /* !NEW_MACRO_VARARGS */
61 #define DEBUG(args...)
62 #endif
63 #endif
64
65 #ifndef O_LARGEFILE
66 #define O_LARGEFILE 0100000
67 #endif
68
69 static int (*_select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
70 static int (*_poll)(struct pollfd *ufds, unsigned int nfds, int timeout);
71 static int (*_open)(const char *file, int oflag, ...);
72 static int (*_open64)(const char *file, int oflag, ...);
73 static int (*_close)(int fd);
74 static ssize_t (*_write)(int fd, const void *buf, size_t n);
75 static ssize_t (*_read)(int fd, void *buf, size_t n);
76 static int (*_ioctl)(int fd, unsigned long request, ...);
77 static int (*_fcntl)(int fd, int cmd, ...);
78 static void *(*_mmap)(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
79 static int (*_munmap)(void* addr, size_t len);
80
81 static FILE *(*_fopen)(const char *path, const char *mode);
82 static FILE *(*_fopen64)(const char *path, const char *mode);
83
84 typedef struct ops {
85 int (*close)(int fd);
86 ssize_t (*write)(int fd, const void *buf, size_t n);
87 ssize_t (*read)(int fd, void *buf, size_t n);
88 int (*ioctl)(int fd, unsigned long request, ...);
89 int (*fcntl)(int fd, int cmd, ...);
90 void *(*mmap)(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
91 int (*munmap)(void* addr, size_t len);
92 } ops_t;
93
94 typedef enum {
95 FD_OSS_DSP,
96 FD_OSS_MIXER,
97 FD_CLASSES,
98 } fd_class_t;
99
100 static ops_t ops[FD_CLASSES];
101
102 typedef struct {
103 fd_class_t class;
104 int oflags;
105 void *mmap_area;
106 int poll_fds;
107 } fd_t;
108
109 static void initialize(void);
110 static int initialized = 0;
111
112 static int oss_wrapper_debug = 0;
113 static int open_max;
114 static int poll_fds_add = 0;
115 static fd_t **fds;
116
117 static inline int is_oss_device(int fd)
118 {
119 return fd >= 0 && fd < open_max && fds[fd];
120 }
121
122 static int is_dsp_device(const char *pathname)
123 {
124 if(!pathname) return 0;
125 if(strncmp(pathname,"/dev/dsp",8) == 0) return 1;
126 if(strncmp(pathname,"/dev/adsp",9) == 0) return 1;
127 if(strncmp(pathname,"/dev/audio",10) == 0) return 1;
128 if(strncmp(pathname,"/dev/sound/dsp",14) == 0) return 1;
129 if(strncmp(pathname,"/dev/sound/adsp",15) == 0) return 1;
130 if(strncmp(pathname,"/dev/sound/audio",16) == 0) return 1;
131 return 0;
132 }
133
134 static int is_mixer_device(const char *pathname)
135 {
136 if(!pathname) return 0;
137 if(strncmp(pathname,"/dev/mixer",10) == 0) return 1;
138 if(strncmp(pathname,"/dev/sound/mixer",16) == 0) return 1;
139 return 0;
140 }
141
142 static int oss_pcm_fcntl(int fd, int cmd, ...)
143 {
144 int result;
145 va_list args;
146 long arg;
147
148 if (!initialized)
149 initialize();
150
151 va_start(args, cmd);
152 arg = va_arg(args, long);
153 va_end(args);
154
155 switch (cmd) {
156 case F_GETFL:
157 return fds[fd]->oflags;
158 case F_SETFL:
159 result = lib_oss_pcm_nonblock(fd, (arg & O_NONBLOCK) ? 1 : 0);
160 if (result < 0) {
161 errno = -result;
162 return -1;
163 }
164 return 0;
165 default:
166 DEBUG("pcm_fcntl(%d, ", fd);
167 result = _fcntl(fd, cmd, arg);
168 if (result < 0)
169 return result;
170 DEBUG("%x, %ld)\n", cmd, arg);
171 return result;
172 }
173 return -1;
174 }
175
176 static int oss_mixer_fcntl(int fd, int cmd, ...)
177 {
178 int result;
179 va_list args;
180 long arg;
181
182 va_start(args, cmd);
183 arg = va_arg(args, long);
184 va_end(args);
185
186 switch (cmd) {
187 case F_GETFL:
188 return fds[fd]->oflags;
189 default:
190 DEBUG("mixer_fcntl(%d, ", fd);
191 result = _fcntl(fd, cmd, arg);
192 if (result < 0)
193 return result;
194 DEBUG("%x, %ld)\n", cmd, arg);
195 return result;
196 }
197 return -1;
198 }
199
200 static ssize_t bad_write(int fd ATTRIBUTE_UNUSED, const void *buf ATTRIBUTE_UNUSED, size_t n ATTRIBUTE_UNUSED)
201 {
202 errno = EBADFD;
203 return -1;
204 }
205
206 static ssize_t bad_read(int fd ATTRIBUTE_UNUSED, void *buf ATTRIBUTE_UNUSED, size_t n ATTRIBUTE_UNUSED)
207 {
208 errno = EBADFD;
209 return -1;
210 }
211
212 static void *bad_mmap(void *addr ATTRIBUTE_UNUSED, size_t len ATTRIBUTE_UNUSED,
213 int prot ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED,
214 int fd ATTRIBUTE_UNUSED, off_t offset ATTRIBUTE_UNUSED)
215 {
216 errno = EBADFD;
217 return MAP_FAILED;
218 }
219
220 static int bad_munmap(void* addr ATTRIBUTE_UNUSED, size_t len ATTRIBUTE_UNUSED)
221 {
222 errno = EBADFD;
223 return -1;
224 }
225
226 static ops_t ops[FD_CLASSES] = {
227 [FD_OSS_DSP] = {
228 .close = lib_oss_pcm_close,
229 .write = lib_oss_pcm_write,
230 .read = lib_oss_pcm_read,
231 .ioctl = lib_oss_pcm_ioctl,
232 .fcntl = oss_pcm_fcntl,
233 .mmap = lib_oss_pcm_mmap,
234 .munmap = lib_oss_pcm_munmap,
235 },
236 [FD_OSS_MIXER] = {
237 .close = lib_oss_mixer_close,
238 .write = bad_write,
239 .read = bad_read,
240 .ioctl = lib_oss_mixer_ioctl,
241 .fcntl = oss_mixer_fcntl,
242 .mmap = bad_mmap,
243 .munmap = bad_munmap,
244 },
245 };
246
247 static int dsp_open_helper(const char *file, int oflag)
248 {
249 int fd;
250 fd = lib_oss_pcm_open(file, oflag);
251 if (fd >= 0) {
252 int nfds;
253 fds[fd] = calloc(sizeof(fd_t), 1);
254 if (fds[fd] == NULL) {
255 ops[FD_OSS_DSP].close(fd);
256 errno = ENOMEM;
257 return -1;
258 }
259 fds[fd]->class = FD_OSS_DSP;
260 fds[fd]->oflags = oflag;
261 nfds = lib_oss_pcm_poll_fds(fd);
262 if (nfds > 0) {
263 fds[fd]->poll_fds = nfds;
264 poll_fds_add += nfds;
265 }
266 }
267 return fd;
268 }
269
270 static int mixer_open_helper(const char *file, int oflag)
271 {
272 int fd;
273 fd = lib_oss_mixer_open(file, oflag);
274 if (fd >= 0) {
275 fds[fd] = calloc(sizeof(fd_t), 1);
276 if (fds[fd] == NULL) {
277 ops[FD_OSS_MIXER].close(fd);
278 errno = ENOMEM;
279 return -1;
280 }
281 fds[fd]->class = FD_OSS_MIXER;
282 fds[fd]->oflags = oflag;
283 }
284 return fd;
285 }
286
287 #define DECL_OPEN(name, callback) \
288 int name(const char *file, int oflag, ...) \
289 { \
290 va_list args; \
291 mode_t mode = 0; \
292 int fd; \
293 if (!initialized) \
294 initialize(); \
295 if (oflag & O_CREAT) { \
296 va_start(args, oflag); \
297 mode = va_arg(args, mode_t); \
298 va_end(args); \
299 } \
300 if (is_dsp_device(file)) \
301 fd = dsp_open_helper(file, oflag); \
302 else if (is_mixer_device(file)) \
303 fd = mixer_open_helper(file, oflag); \
304 else { \
305 fd = callback(file, oflag, mode); \
306 if (fd >= 0) \
307 assert(fds[fd] == NULL); \
308 } \
309 return fd; \
310 }
311
312 DECL_OPEN(open, _open)
313 DECL_OPEN(open64, _open64)
314
315 int close(int fd)
316 {
317 if (!initialized)
318 initialize();
319
320 if (! is_oss_device(fd)) {
321 return _close(fd);
322 } else {
323 fd_t *xfd = fds[fd];
324 int err;
325
326 fds[fd] = NULL;
327 poll_fds_add -= xfd->poll_fds;
328 if (poll_fds_add < 0) {
329 fprintf(stderr, "alsa-oss: poll_fds_add screwed up!\n");
330 poll_fds_add = 0;
331 }
332 err = ops[xfd->class].close(fd);
333 // assert(err >= 0);
334 return err;
335 }
336 }
337
338 ssize_t write(int fd, const void *buf, size_t n)
339 {
340 if (!initialized)
341 initialize();
342
343 if (! is_oss_device(fd))
344 return _write(fd, buf, n);
345 else
346 return ops[fds[fd]->class].write(fd, buf, n);
347 }
348
349 ssize_t read(int fd, void *buf, size_t n)
350 {
351 if (!initialized)
352 initialize();
353
354 if (! is_oss_device(fd))
355 return _read(fd, buf, n);
356 else
357 return ops[fds[fd]->class].read(fd, buf, n);
358 }
359
360 int ioctl(int fd, unsigned long request, ...)
361 {
362 va_list args;
363 void *arg;
364
365 if (!initialized)
366 initialize();
367
368 va_start(args, request);
369 arg = va_arg(args, void *);
370 va_end(args);
371 if (! is_oss_device(fd))
372 return _ioctl(fd, request, arg);
373 else
374 return ops[fds[fd]->class].ioctl(fd, request, arg);
375 }
376
377 int fcntl(int fd, int cmd, ...)
378 {
379 va_list args;
380 void *arg;
381
382 if (!initialized)
383 initialize();
384
385 va_start(args, cmd);
386 arg = va_arg(args, void *);
387 va_end(args);
388 if (! is_oss_device(fd))
389 return _fcntl(fd, cmd, arg);
390 else
391 return ops[fds[fd]->class].fcntl(fd, cmd, arg);
392 }
393
394 void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
395 {
396 void *result;
397
398 if (!initialized)
399 initialize();
400
401 if (! is_oss_device(fd))
402 return _mmap(addr, len, prot, flags, fd, offset);
403 result = ops[fds[fd]->class].mmap(addr, len, prot, flags, fd, offset);
404 if (result != NULL && result != MAP_FAILED)
405 fds[fd]->mmap_area = result;
406 return result;
407 }
408
409 int munmap(void *addr, size_t len)
410 {
411 int fd;
412
413 if (!initialized)
414 initialize();
415
416 for (fd = 0; fd < open_max; ++fd) {
417 if (fds[fd] && fds[fd]->mmap_area == addr)
418 break;
419 }
420 if (fd >= open_max)
421 return _munmap(addr, len);
422 fds[fd]->mmap_area = 0;
423 return ops[fds[fd]->class].munmap(addr, len);
424 }
425
426 #ifdef DEBUG_POLL
427 void dump_poll(struct pollfd *pfds, unsigned long nfds, int timeout)
428 {
429 unsigned int k;
430 fprintf(stderr, "POLL nfds: %ld, timeout: %d\n", nfds, timeout);
431 for (k = 0; k < nfds; ++k) {
432 fprintf(stderr, "fd=%d, events=%x, revents=%x\n",
433 pfds[k].fd, pfds[k].events, pfds[k].revents);
434 }
435 }
436 #endif
437
438 #ifdef DEBUG_SELECT
439 void dump_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
440 struct timeval *timeout)
441 {
442 int k;
443 fprintf(stderr, "SELECT nfds: %d, ", nfds);
444 if (timeout)
445 fprintf(stderr, "timeout: %ld.%06ld\n", (long)timeout->tv_sec, (long)timeout->tv_usec);
446 else
447 fprintf(stderr, "no timeout\n");
448 if (rfds) {
449 fprintf(stderr, "rfds: ");
450 for (k = 0; k < nfds; ++k) {
451 if (FD_ISSET(k, rfds))
452 putc('1', stderr);
453 else
454 putc('0', stderr);
455 }
456 putc('\n', stderr);
457 }
458 if (wfds) {
459 fprintf(stderr, "wfds: ");
460 for (k = 0; k < nfds; ++k) {
461 if (FD_ISSET(k, wfds))
462 putc('1', stderr);
463 else
464 putc('0', stderr);
465 }
466 putc('\n', stderr);
467 }
468 if (efds) {
469 fprintf(stderr, "efds: ");
470 for (k = 0; k < nfds; ++k) {
471 if (FD_ISSET(k, efds))
472 putc('1', stderr);
473 else
474 putc('0', stderr);
475 }
476 putc('\n', stderr);
477 }
478 }
479 #endif
480
481 static int poll_with_pcm(struct pollfd *pfds, unsigned long nfds, int timeout);
482
483 int poll(struct pollfd *pfds, unsigned long nfds, int timeout)
484 {
485 unsigned int k;
486
487 if (!initialized)
488 initialize();
489
490 for (k = 0; k < nfds; ++k) {
491 int fd = pfds[k].fd;
492 if (! is_oss_device(fd))
493 continue;
494 if (fds[fd]->class == FD_OSS_DSP)
495 return poll_with_pcm(pfds, nfds, timeout);
496 }
497 return _poll(pfds, nfds, timeout);
498 }
499
500
501 static int poll_with_pcm(struct pollfd *pfds, unsigned long nfds, int timeout)
502 {
503 unsigned int k;
504 unsigned int nfds1;
505 int count;
506 struct pollfd pfds1[nfds + poll_fds_add + 16];
507
508 nfds1 = 0;
509 for (k = 0; k < nfds; ++k) {
510 int fd = pfds[k].fd;
511 if (is_oss_device(fd) && fds[fd]->class == FD_OSS_DSP) {
512 unsigned short events = pfds[k].events;
513 int fmode = 0;
514 if ((events & (POLLIN|POLLOUT)) == (POLLIN|POLLOUT))
515 fmode = O_RDWR;
516 else if (events & POLLIN)
517 fmode = O_RDONLY;
518 else
519 fmode = O_WRONLY;
520 count = lib_oss_pcm_poll_prepare(fd, fmode, &pfds1[nfds1]);
521 if (count < 0)
522 return -1;
523 nfds1 += count;
524 } else {
525 pfds1[nfds1] = pfds[k];
526 nfds1++;
527 }
528 if (nfds1 > nfds + poll_fds_add) {
529 fprintf(stderr, "alsa-oss: Pollfd overflow!\n");
530 errno = EINVAL;
531 return -1;
532 }
533 }
534 #ifdef DEBUG_POLL
535 if (oss_wrapper_debug) {
536 fprintf(stderr, "Orig enter ");
537 dump_poll(pfds, nfds, timeout);
538 fprintf(stderr, "Changed enter ");
539 dump_poll(pfds1, nfds1, timeout);
540 }
541 #endif
542 count = _poll(pfds1, nfds1, timeout);
543 if (count <= 0)
544 return count;
545 nfds1 = 0;
546 count = 0;
547 for (k = 0; k < nfds; ++k) {
548 int fd = pfds[k].fd;
549 unsigned int revents;
550 if (is_oss_device(fd) && fds[fd]->class == FD_OSS_DSP) {
551 int result = lib_oss_pcm_poll_result(fd, &pfds1[nfds1]);
552 revents = 0;
553 if (result < 0) {
554 revents |= POLLNVAL;
555 } else {
556 revents |= ((result & OSS_WAIT_EVENT_ERROR) ? POLLERR : 0) |
557 ((result & OSS_WAIT_EVENT_READ) ? POLLIN : 0) |
558 ((result & OSS_WAIT_EVENT_WRITE) ? POLLOUT : 0);
559 }
560 nfds1 += lib_oss_pcm_poll_fds(fd);
561 } else {
562 revents = pfds1[nfds1].revents;
563 nfds1++;
564 }
565 pfds[k].revents = revents;
566 if (revents)
567 count++;
568 }
569 #ifdef DEBUG_POLL
570 if (oss_wrapper_debug) {
571 fprintf(stderr, "Changed exit ");
572 dump_poll(pfds1, nfds1, timeout);
573 fprintf(stderr, "Orig exit ");
574 dump_poll(pfds, nfds, timeout);
575 }
576 #endif
577 return count;
578 }
579
580 static int select_with_pcm(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
581 struct timeval *timeout);
582
583 int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
584 struct timeval *timeout)
585 {
586 int fd;
587
588 if (!initialized)
589 initialize();
590
591 for (fd = 0; fd < nfds; ++fd) {
592 int r = (rfds && FD_ISSET(fd, rfds));
593 int w = (wfds && FD_ISSET(fd, wfds));
594 int e = (efds && FD_ISSET(fd, efds));
595 if (!(r || w || e))
596 continue;
597 if (is_oss_device(fd) && fds[fd]->class == FD_OSS_DSP)
598 return select_with_pcm(nfds, rfds, wfds, efds, timeout);
599 }
600 return _select(nfds, rfds, wfds, efds, timeout);
601 }
602
603
604 static int select_with_pcm(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
605 struct timeval *timeout)
606 {
607 fd_set _rfds1, _wfds1, _efds1;
608 fd_set *rfds1, *wfds1, *efds1;
609 int fd;
610 int nfds1 = nfds;
611 int count;
612
613 if (rfds)
614 _rfds1 = *rfds;
615 else
616 FD_ZERO(&_rfds1);
617 rfds1 = &_rfds1;
618 if (wfds)
619 _wfds1 = *wfds;
620 else
621 FD_ZERO(&_wfds1);
622 wfds1 = &_wfds1;
623 if (efds) {
624 _efds1 = *efds;
625 efds1 = &_efds1;
626 } else {
627 efds1 = NULL;
628 }
629 for (fd = 0; fd < nfds; ++fd) {
630 int r = (rfds && FD_ISSET(fd, rfds));
631 int w = (wfds && FD_ISSET(fd, wfds));
632 int e = (efds && FD_ISSET(fd, efds));
633 if (!(r || w || e))
634 continue;
635 if (is_oss_device(fd) && fds[fd]->class == FD_OSS_DSP) {
636 int res, fmode = 0;
637
638 if (r & w)
639 fmode = O_RDWR;
640 else if (r)
641 fmode = O_RDONLY;
642 else
643 fmode = O_WRONLY;
644 res = lib_oss_pcm_select_prepare(fd, fmode, rfds1, wfds1,
645 e ? efds1 : NULL);
646 if (res < 0)
647 return -1;
648 if (nfds1 < res + 1)
649 nfds1 = res + 1;
650 if (r)
651 FD_CLR(fd, rfds1);
652 if (w)
653 FD_CLR(fd, wfds1);
654 if (e)
655 FD_CLR(fd, efds1);
656 }
657 }
658 #ifdef DEBUG_SELECT
659 if (oss_wrapper_debug) {
660 fprintf(stderr, "Orig enter ");
661 dump_select(nfds, rfds, wfds, efds, timeout);
662 fprintf(stderr, "Changed enter ");
663 dump_select(nfds1, rfds1, wfds1, efds1, timeout);
664 }
665 #endif
666 count = _select(nfds1, rfds1, wfds1, efds1, timeout);
667 if (count < 0)
668 return count;
669 if (count == 0) {
670 if (rfds)
671 FD_ZERO(rfds);
672 if (wfds)
673 FD_ZERO(wfds);
674 if (efds)
675 FD_ZERO(efds);
676 return 0;
677 }
678 count = 0;
679 for (fd = 0; fd < nfds; ++fd) {
680 int r = (rfds && FD_ISSET(fd, rfds));
681 int w = (wfds && FD_ISSET(fd, wfds));
682 int e = (efds && FD_ISSET(fd, efds));
683 int r1, w1, e1;
684 if (!(r || w || e))
685 continue;
686 if (is_oss_device(fd) && fds[fd]->class == FD_OSS_DSP) {
687 int result = lib_oss_pcm_select_result(fd, rfds1, wfds1, efds1);
688 r1 = w1 = e1 = 0;
689 if (result < 0 && e) {
690 if (efds)
691 FD_SET(fd, efds);
692 e1 = 1;
693 } else {
694 if (result & OSS_WAIT_EVENT_ERROR) {
695 if (efds)
696 FD_SET(fd, efds);
697 e1 = 1;
698 }
699 if (result & OSS_WAIT_EVENT_READ) {
700 if (rfds)
701 FD_SET(fd, rfds);
702 r1 = 1;
703 }
704 if (result & OSS_WAIT_EVENT_WRITE) {
705 if (wfds)
706 FD_SET(fd, wfds);
707 w1 = 1;
708 }
709 }
710 } else {
711 r1 = (r && FD_ISSET(fd, rfds1));
712 w1 = (w && FD_ISSET(fd, wfds1));
713 e1 = (e && FD_ISSET(fd, efds1));
714 }
715 if (r && !r1 && rfds)
716 FD_CLR(fd, rfds);
717 if (w && !w1 && wfds)
718 FD_CLR(fd, wfds);
719 if (e && !e1 && efds)
720 FD_CLR(fd, efds);
721 if (r1 || w1 || e1)
722 count++;
723 }
724 #ifdef DEBUG_SELECT
725 if (oss_wrapper_debug) {
726 fprintf(stderr, "Changed exit ");
727 dump_select(nfds1, rfds1, wfds1, efds1, timeout);
728 fprintf(stderr, "Orig exit ");
729 dump_select(nfds, rfds, wfds, efds, timeout);
730 }
731 #endif
732 return count;
733 }
734
735
736 #include "stdioemu.c"
737
738 FILE *fopen(const char* path, const char *mode)
739 {
740 if (!initialized)
741 initialize();
742
743 if (!is_dsp_device(path))
744 return _fopen(path, mode);
745
746 return fake_fopen(path, mode, 0);
747 }
748
749 FILE *fopen64(const char* path, const char *mode)
750 {
751 if (!initialized)
752 initialize();
753
754 if (!is_dsp_device(path))
755 return _fopen64(path, mode);
756
757 return fake_fopen(path, mode, O_LARGEFILE);
758 }
759
760 #if 0
761 int dup(int fd)
762 {
763 return fcntl(fd, F_DUPFD, 0);
764 }
765 #endif
766
767 #if 0
768 int dup2(int fd, int fd2)
769 {
770 int save;
771
772 if (fd2 < 0 || fd2 >= open_max) {
773 errno = EBADF;
774 return -1;
775 }
776
777 if (fcntl(fd, F_GETFL) < 0)
778 return -1;
779
780 if (fd == fd2)
781 return fd2;
782
783 save = errno;
784 close(fd2);
785 errno = save;
786
787 return fcntl(fd, F_DUPFD, fd2);
788 }
789 #endif
790
791 # define strong_alias(name, aliasname) \
792 extern __typeof (name) aliasname __attribute__ ((alias (#name)));
793
794 strong_alias(open, __open);
795 strong_alias(open64, __open64);
796 strong_alias(close, __close);
797 strong_alias(write, __write);
798 strong_alias(read, __read);
799 strong_alias(ioctl, __ioctl);
800 strong_alias(fcntl, __fcntl);
801 strong_alias(mmap, __mmap);
802 strong_alias(munmap, __munmap);
803 strong_alias(poll, __poll);
804 strong_alias(select, __select);
805 strong_alias(fopen, __fopen);
806 strong_alias(fopen64, __fopen64);
807
808 /* called by each override if needed */
809 static void initialize()
810 {
811 char *s = getenv("ALSA_OSS_DEBUG");
812 if (s)
813 oss_wrapper_debug = 1;
814 open_max = sysconf(_SC_OPEN_MAX);
815 if (open_max < 0)
816 exit(1);
817 fds = calloc(open_max, sizeof(*fds));
818 if (!fds)
819 exit(1);
820 _open = dlsym(RTLD_NEXT, "open");
821 _open64 = dlsym(RTLD_NEXT, "open64");
822 _close = dlsym(RTLD_NEXT, "close");
823 _write = dlsym(RTLD_NEXT, "write");
824 _read = dlsym(RTLD_NEXT, "read");
825 _ioctl = dlsym(RTLD_NEXT, "ioctl");
826 _fcntl = dlsym(RTLD_NEXT, "fcntl");
827 _mmap = dlsym(RTLD_NEXT, "mmap");
828 _munmap = dlsym(RTLD_NEXT, "munmap");
829 _select = dlsym(RTLD_NEXT, "select");
830 _poll = dlsym(RTLD_NEXT, "poll");
831 _fopen = dlsym(RTLD_NEXT, "fopen");
832 _fopen64 = dlsym(RTLD_NEXT, "fopen64");
833 initialized = 1;
834 }