1 /*
2 * audio-sock.cc --
3 *
4 * FIXME: This file needs a description here.
5 *
6 * Copyright (c) 1993-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 static const char rcsid[] =
36 "@(#) $Header: /usr/mash/src/repository/mash/mash-1/audio/audio-sock.cc,v 1.8 2002/02/03 03:10:46 lim Exp $";
37 #endif
38
39 #include <errno.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <sys/file.h>
45 #include <sys/socket.h>
46 #include <sys/un.h>
47 #include "audio.h"
48 #include "tclcl.h"
49
50 class SocketAudio : public Audio {
51 public:
52 SocketAudio(const char *filename);
53 virtual int FrameReady();
54 virtual u_char* Read();
55 virtual void Write(u_char *);
56 virtual void Obtain();
57 virtual void Release();
58 protected:
59 u_char* buf_;
60 u_char* bufcur_;
61 u_char* bufend_;
62 sockaddr_un sockaddr_;
63 int socklen_;
64 int lock_;
65 };
66
67 static class SocketAudioMatcher : public Matcher {
68 public:
69 SocketAudioMatcher() : Matcher("audio") {}
70 TclObject* match(const char* id) {
71 /* FIXME assume socket pathname starts with slash */
72 if (*id == '/')
73 return (new SocketAudio(id));
74 else
75 return (0);
76 }
77 } socket_audio_matcher;
78
79 SocketAudio::SocketAudio(const char *name)
80 {
81 sockaddr_.sun_family = AF_UNIX;
82 strcpy(sockaddr_.sun_path, name);
83 socklen_ = strlen(sockaddr_.sun_path) + 2;
84 bufcur_ = buf_ = new u_char[blksize];
85 bufend_ = buf_ + blksize;
86 openlock();
87 }
88
89 void SocketAudio::Release()
90 {
91 if (HaveAudio()) {
92 unlock();
93 Audio::Release();
94 }
95 }
96
97 void SocketAudio::Obtain()
98 {
99 if (HaveAudio())
100 abort();
101 if (lock() == 0) {
102 fd_ = socket(AF_UNIX, SOCK_STREAM, 0);
103 if (fd_ < 0) {
104 perror("vat: socket");
105 exit(1);
106 }
107 if (connect(fd_, (sockaddr*)&sockaddr_, socklen_) < 0) {
108 if (errno != ECONNREFUSED && errno != ENOENT)
109 perror("vat: audio connect");
110 close(fd_);
111 fd_ = -1;
112 unlock();
113 return;
114 }
115 bufcur_ = buf_;
116 Audio::Obtain();
117 }
118 }
119
120 void SocketAudio::Write(u_char *cp)
121 {
122 if (HaveAudio())
123 (void)write(fd_, (char *)cp, blksize);
124 }
125
126 int SocketAudio::FrameReady()
127 {
128 register int len = bufend_ - bufcur_;
129 while (len > 0) {
130 int cc = read(fd_, (char *)bufcur_, len);
131 if (cc == 0) {
132 Release();
133 return (0);
134 }
135 if (cc < 0) {
136 switch (errno) {
137 case EINVAL:
138 /* probably wrapped file pos. */
139 lseek(fd_, 0, SEEK_SET);
140 cc = 0;
141 break;
142
143 case EPERM:
144 /* probably lost audio */
145 goto out;
146
147 case EWOULDBLOCK:
148 /* should warn about audio_bsize here */
149 goto out;
150
151 default:
152 perror("vat: audio read");
153 return (0);
154 }
155 }
156 bufcur_ += cc;
157 len -= cc;
158 }
159 out:
160 return (bufcur_ >= bufend_);
161 }
162
163 u_char* SocketAudio::Read()
164 {
165 bufcur_ = buf_;
166 return (buf_);
167 }
168
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.