]> code.delx.au - pulseaudio/blob - src/utils/pacmd.c
Reorganised the source tree. We now have src/ with a couple of subdirs:
[pulseaudio] / src / utils / pacmd.c
1 /* $Id$ */
2
3 /***
4 This file is part of polypaudio.
5
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <assert.h>
27 #include <signal.h>
28 #include <sys/select.h>
29 #include <sys/socket.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <sys/un.h>
34
35 #include <polypcore/util.h>
36 #include <polypcore/log.h>
37 #include <polypcore/pid.h>
38
39 int main(PA_GCC_UNUSED int main, PA_GCC_UNUSED char*argv[]) {
40 pid_t pid ;
41 int fd = -1;
42 int ret = 1, i;
43 struct sockaddr_un sa;
44 char ibuf[256], obuf[256];
45 size_t ibuf_index, ibuf_length, obuf_index, obuf_length;
46 fd_set ifds, ofds;
47
48 if (pa_pid_file_check_running(&pid) < 0) {
49 pa_log(__FILE__": no Polypaudio daemon running\n");
50 goto fail;
51 }
52
53 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
54 pa_log(__FILE__": socket(PF_UNIX, SOCK_STREAM, 0): %s\n", strerror(errno));
55 goto fail;
56 }
57
58 memset(&sa, 0, sizeof(sa));
59 sa.sun_family = AF_UNIX;
60 pa_runtime_path("cli", sa.sun_path, sizeof(sa.sun_path));
61
62 for (i = 0; i < 5; i++) {
63 int r;
64
65 if ((r = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 && (errno != ECONNREFUSED && errno != ENOENT)) {
66 pa_log(__FILE__": connect() failed: %s\n", strerror(errno));
67 goto fail;
68 }
69
70 if (r >= 0)
71 break;
72
73 if (pa_pid_file_kill(SIGUSR2, NULL) < 0) {
74 pa_log(__FILE__": failed to kill Polypaudio daemon.\n");
75 goto fail;
76 }
77
78 pa_msleep(50);
79 }
80
81 if (i >= 5) {
82 pa_log(__FILE__": daemon not responding.\n");
83 goto fail;
84 }
85
86 ibuf_index = ibuf_length = obuf_index = obuf_length = 0;
87
88
89 FD_ZERO(&ifds);
90 FD_SET(0, &ifds);
91 FD_SET(fd, &ifds);
92
93 FD_ZERO(&ofds);
94
95 for (;;) {
96 if (select(FD_SETSIZE, &ifds, &ofds, NULL, NULL) < 0) {
97 pa_log(__FILE__": select() failed: %s\n", strerror(errno));
98 goto fail;
99 }
100
101 if (FD_ISSET(0, &ifds)) {
102 ssize_t r;
103 assert(!ibuf_length);
104
105 if ((r = read(0, ibuf, sizeof(ibuf))) <= 0) {
106 if (r == 0)
107 break;
108
109 pa_log(__FILE__": read() failed: %s\n", strerror(errno));
110 goto fail;
111 }
112
113 ibuf_length = (size_t) r;
114 ibuf_index = 0;
115 }
116
117 if (FD_ISSET(fd, &ifds)) {
118 ssize_t r;
119 assert(!obuf_length);
120
121 if ((r = read(fd, obuf, sizeof(obuf))) <= 0) {
122 if (r == 0)
123 break;
124
125 pa_log(__FILE__": read() failed: %s\n", strerror(errno));
126 goto fail;
127 }
128
129 obuf_length = (size_t) r;
130 obuf_index = 0;
131 }
132
133 if (FD_ISSET(1, &ofds)) {
134 ssize_t r;
135 assert(obuf_length);
136
137 if ((r = write(1, obuf + obuf_index, obuf_length)) < 0) {
138 pa_log(__FILE__": write() failed: %s\n", strerror(errno));
139 goto fail;
140 }
141
142 obuf_length -= (size_t) r;
143 obuf_index += obuf_index;
144
145 }
146
147 if (FD_ISSET(fd, &ofds)) {
148 ssize_t r;
149 assert(ibuf_length);
150
151 if ((r = write(fd, ibuf + ibuf_index, ibuf_length)) < 0) {
152 pa_log(__FILE__": write() failed: %s\n", strerror(errno));
153 goto fail;
154 }
155
156 ibuf_length -= (size_t) r;
157 ibuf_index += obuf_index;
158
159 }
160
161 FD_ZERO(&ifds);
162 FD_ZERO(&ofds);
163
164 if (obuf_length <= 0)
165 FD_SET(fd, &ifds);
166 else
167 FD_SET(1, &ofds);
168
169 if (ibuf_length <= 0)
170 FD_SET(0, &ifds);
171 else
172 FD_SET(fd, &ofds);
173 }
174
175
176 ret = 0;
177
178 fail:
179 if (fd >= 0)
180 close(fd);
181
182 return ret;
183 }