"Fossies" - the Fresh Open Source Software Archive 
Member "alsa-oss-1.1.8/oss-redir/oss-redir.c" (7 Jan 2019, 7138 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 "oss-redir.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 Redirector
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22 #define _GNU_SOURCE
23
24 #include "oss-redir.h"
25 #include <sys/poll.h>
26 #include <sys/ioctl.h>
27 #include <sys/mman.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <dlfcn.h>
34 #include <errno.h>
35 #include <linux/soundcard.h>
36
37 static int initialized = 0;
38 static int native_oss = 1;
39 static int open_count = 0;
40 static char hal[64];
41 static void *dl_handle = NULL;
42
43 static void initialize(void);
44
45 static int (*x_oss_pcm_open)(const char *pathname, int flags);
46 static int (*x_oss_pcm_close)(int fd);
47 int (*oss_pcm_nonblock)(int fd, int nonblock);
48 ssize_t (*oss_pcm_read)(int fd, void *buf, size_t count);
49 ssize_t (*oss_pcm_write)(int fd, const void *buf, size_t count);
50 void * (*oss_pcm_mmap)(void *start, size_t length, int prot, int flags, int fd, off_t offset);
51 int (*oss_pcm_munmap)(void *start, size_t length);
52 int (*oss_pcm_ioctl)(int fd, unsigned long int request, ...);
53 int (*oss_pcm_select_prepare)(int fd, int fmode, fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
54 int (*oss_pcm_select_result)(int fd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
55 int (*oss_pcm_poll_fds)(int fd);
56 int (*oss_pcm_poll_prepare)(int fd, int fmode, struct pollfd *ufds);
57 int (*oss_pcm_poll_result)(int fd, struct pollfd *ufds);
58
59 static int (*x_oss_mixer_open)(const char *pathname, int flags);
60 static int (*x_oss_mixer_close)(int fd);
61 int (*oss_mixer_ioctl)(int fd, unsigned long int request, ...);
62
63 static int native_pcm_nonblock(int fd, int nonblock)
64 {
65 long flags;
66
67 if ((flags = fcntl(fd, F_GETFL)) < 0)
68 return -1;
69 if (nonblock)
70 flags |= O_NONBLOCK;
71 else
72 flags &= ~O_NONBLOCK;
73 if (fcntl(fd, F_SETFL, flags) < 0)
74 return -1;
75 return 0;
76 }
77
78 static int native_pcm_select_prepare(int fd, int fmode, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
79 {
80 if (fd < 0)
81 return -EINVAL;
82 if ((fmode & O_ACCMODE) != O_WRONLY && readfds) {
83 FD_SET(fd, readfds);
84 if (exceptfds)
85 FD_SET(fd, exceptfds);
86 }
87 if ((fmode & O_ACCMODE) != O_RDONLY && writefds) {
88 FD_SET(fd, writefds);
89 if (exceptfds)
90 FD_SET(fd, exceptfds);
91 }
92 return fd;
93 }
94
95 static int native_pcm_select_result(int fd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
96 {
97 int result = 0;
98
99 if (fd < 0)
100 return -EINVAL;
101 if (readfds && FD_ISSET(fd, readfds))
102 result |= OSS_WAIT_EVENT_READ;
103 if (writefds && FD_ISSET(fd, writefds))
104 result |= OSS_WAIT_EVENT_WRITE;
105 if (exceptfds && FD_ISSET(fd, exceptfds))
106 result |= OSS_WAIT_EVENT_ERROR;
107 return result;
108 }
109
110 static int native_pcm_poll_fds(int fd)
111 {
112 if (fd < 0)
113 return -EINVAL;
114 return 1;
115 }
116
117 static int native_pcm_poll_prepare(int fd, int fmode, struct pollfd *ufds)
118 {
119 if (fd < 0)
120 return -EINVAL;
121 ufds->fd = fd;
122 ufds->events = ((fmode & O_ACCMODE) == O_WRONLY ? 0 : POLLIN) |
123 ((fmode & O_ACCMODE) == O_RDONLY ? 0 : POLLOUT) | POLLERR;
124 return 1;
125 }
126
127 static int native_pcm_poll_result(int fd, struct pollfd *ufds)
128 {
129 int result = 0;
130
131 if (fd < 0)
132 return -EINVAL;
133 if (ufds->events & POLLIN)
134 result |= OSS_WAIT_EVENT_READ;
135 if (ufds->events & POLLOUT)
136 result |= OSS_WAIT_EVENT_WRITE;
137 if (ufds->events & POLLERR)
138 result |= OSS_WAIT_EVENT_ERROR;
139 return result;
140 }
141
142 static inline void check_initialized(void)
143 {
144 if (!initialized)
145 initialize();
146 }
147
148 int oss_pcm_open(const char *pathname, int flags, ...)
149 {
150 int result;
151
152 check_initialized();
153 if (native_oss)
154 return open(pathname, flags);
155 result = x_oss_pcm_open(pathname, flags);
156 if (result >= 0) {
157 open_count++;
158 } else {
159 if (open_count == 0) {
160 dlclose(dl_handle);
161 dl_handle = NULL;
162 }
163 }
164 return result;
165 }
166
167 int oss_pcm_close(int fd)
168 {
169 int result;
170
171 if (native_oss)
172 return close(fd);
173 result = x_oss_pcm_close(fd);
174 if (--open_count) {
175 dlclose(dl_handle);
176 dl_handle = NULL;
177 }
178 return result;
179 }
180
181 int oss_mixer_open(const char *pathname, int flags, ...)
182 {
183 int result;
184
185 check_initialized();
186 if (native_oss)
187 return open(pathname, flags);
188 result = x_oss_mixer_open(pathname, flags);
189 if (result >= 0) {
190 open_count++;
191 } else {
192 if (open_count == 0) {
193 dlclose(dl_handle);
194 dl_handle = NULL;
195 }
196 }
197 return result;
198 }
199
200 int oss_mixer_close(int fd)
201 {
202 int result;
203
204 if (fd < 0)
205 return -EINVAL;
206 if (native_oss)
207 return close(fd);
208 result = x_oss_mixer_close(fd);
209 if (--open_count) {
210 dlclose(dl_handle);
211 dl_handle = NULL;
212 }
213 return result;
214 }
215
216 static void initialize(void)
217 {
218 char *s = getenv("OSS_REDIRECTOR");
219 if (s) {
220 strncpy(hal, s, sizeof(hal));
221 hal[sizeof(hal)-1] = '\0';
222 if (!strcasecmp(hal, "oss"))
223 native_oss = 1;
224 else
225 native_oss = 0;
226 } else {
227 native_oss = 1;
228 }
229 if (native_oss) {
230 __native:
231 oss_pcm_nonblock = native_pcm_nonblock;
232 oss_pcm_read = read;
233 oss_pcm_write = write;
234 oss_pcm_mmap = mmap;
235 oss_pcm_munmap = munmap;
236 oss_pcm_ioctl = ioctl;
237 oss_pcm_select_prepare = native_pcm_select_prepare;
238 oss_pcm_select_result = native_pcm_select_result;
239 oss_pcm_poll_fds = native_pcm_poll_fds;
240 oss_pcm_poll_prepare = native_pcm_poll_prepare;
241 oss_pcm_poll_result = native_pcm_poll_result;
242 oss_mixer_ioctl = ioctl;
243 } else {
244 dl_handle = dlopen(hal, RTLD_NOW);
245 if (dl_handle == NULL) {
246 fprintf(stderr, "ERROR: dlopen failed for sound (OSS) redirector: %s\n", dlerror());
247 fprintf(stderr, " reverting to native OSS mode\n");
248 native_oss = 1;
249 goto __native;
250 }
251 x_oss_pcm_open = dlsym(dl_handle, "lib_oss_pcm_open");
252 x_oss_pcm_close = dlsym(dl_handle, "lib_oss_pcm_close");
253 oss_pcm_nonblock = dlsym(dl_handle, "lib_oss_pcm_nonblock");
254 oss_pcm_read = dlsym(dl_handle, "lib_oss_pcm_read");
255 oss_pcm_write = dlsym(dl_handle, "lib_oss_pcm_write");
256 oss_pcm_mmap = dlsym(dl_handle, "lib_oss_pcm_mmap");
257 oss_pcm_munmap = dlsym(dl_handle, "lib_oss_pcm_munmap");
258 oss_pcm_ioctl = dlsym(dl_handle, "lib_oss_pcm_ioctl");
259 oss_pcm_select_prepare = dlsym(dl_handle, "lib_oss_select_prepare");
260 oss_pcm_select_result = dlsym(dl_handle, "lib_oss_select_result");
261 oss_pcm_poll_fds = dlsym(dl_handle, "lib_oss_poll_fds");
262 oss_pcm_poll_prepare = dlsym(dl_handle, "lib_oss_poll_prepare");
263 oss_pcm_poll_result = dlsym(dl_handle, "lib_oss_poll_result");
264 x_oss_mixer_open = dlsym(dl_handle, "lib_oss_mixer_open");
265 x_oss_mixer_close = dlsym(dl_handle, "lib_oss_mixer_close");
266 oss_mixer_ioctl = dlsym(dl_handle, "lib_oss_mixer_ioctl");
267 }
268 }