]> code.delx.au - pulseaudio/blob - src/utils/pacmd.c
Merge commit 'coling/lgpl21'
[pulseaudio] / src / utils / pacmd.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5
6 PulseAudio 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.1 of the License,
9 or (at your option) any later version.
10
11 PulseAudio 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 PulseAudio; 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 #include <locale.h>
35
36 #include <pulse/error.h>
37 #include <pulse/util.h>
38 #include <pulse/xmalloc.h>
39 #include <pulse/i18n.h>
40
41 #include <pulsecore/core-util.h>
42 #include <pulsecore/log.h>
43 #include <pulsecore/pid.h>
44
45 int main(int argc, char*argv[]) {
46 pid_t pid ;
47 int fd = -1;
48 int ret = 1, i;
49 struct sockaddr_un sa;
50 char ibuf[PIPE_BUF], obuf[PIPE_BUF];
51 size_t ibuf_index, ibuf_length, obuf_index, obuf_length;
52 char *cli;
53 pa_bool_t ibuf_eof, obuf_eof, ibuf_closed, obuf_closed;
54
55 setlocale(LC_ALL, "");
56 bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
57
58 if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) {
59 pa_log("No PulseAudio daemon running, or not running as session daemon.");
60 goto fail;
61 }
62
63 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
64 pa_log(_("socket(PF_UNIX, SOCK_STREAM, 0): %s"), strerror(errno));
65 goto fail;
66 }
67
68 memset(&sa, 0, sizeof(sa));
69 sa.sun_family = AF_UNIX;
70
71 if (!(cli = pa_runtime_path("cli")))
72 goto fail;
73
74 pa_strlcpy(sa.sun_path, cli, sizeof(sa.sun_path));
75 pa_xfree(cli);
76
77 for (i = 0; i < 5; i++) {
78 int r;
79
80 if ((r = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 && (errno != ECONNREFUSED && errno != ENOENT)) {
81 pa_log(_("connect(): %s"), strerror(errno));
82 goto fail;
83 }
84
85 if (r >= 0)
86 break;
87
88 if (pa_pid_file_kill(SIGUSR2, NULL, "pulseaudio") < 0) {
89 pa_log(_("Failed to kill PulseAudio daemon."));
90 goto fail;
91 }
92
93 pa_msleep(300);
94 }
95
96 if (i >= 5) {
97 pa_log(_("Daemon not responding."));
98 goto fail;
99 }
100
101 ibuf_index = ibuf_length = obuf_index = obuf_length = 0;
102 ibuf_eof = obuf_eof = ibuf_closed = obuf_closed = FALSE;
103
104 if (argc > 1) {
105 for (i = 1; i < argc; i++) {
106 size_t k;
107
108 k = PA_MIN(sizeof(ibuf) - ibuf_length, strlen(argv[i]));
109 memcpy(ibuf + ibuf_length, argv[1], k);
110 ibuf_length += k;
111
112 if (ibuf_length < sizeof(ibuf)) {
113 ibuf[ibuf_length] = i < argc-1 ? ' ' : '\n';
114 ibuf_length++;
115 }
116 }
117
118 ibuf_eof = TRUE;
119 }
120
121 for (;;) {
122 fd_set ifds, ofds;
123
124 if (ibuf_eof &&
125 obuf_eof &&
126 ibuf_length <= 0 &&
127 obuf_length <= 0)
128 break;
129
130 FD_ZERO(&ifds);
131 FD_ZERO(&ofds);
132
133 if (obuf_length > 0)
134 FD_SET(1, &ofds);
135 else if (!obuf_eof)
136 FD_SET(fd, &ifds);
137
138 if (ibuf_length > 0)
139 FD_SET(fd, &ofds);
140 else if (!ibuf_eof)
141 FD_SET(0, &ifds);
142
143 if (select(FD_SETSIZE, &ifds, &ofds, NULL, NULL) < 0) {
144 pa_log(_("select(): %s"), strerror(errno));
145 goto fail;
146 }
147
148 if (FD_ISSET(0, &ifds)) {
149 ssize_t r;
150 assert(!ibuf_length);
151
152 if ((r = read(0, ibuf, sizeof(ibuf))) <= 0) {
153 if (r < 0) {
154 pa_log(_("read(): %s"), strerror(errno));
155 goto fail;
156 }
157
158 ibuf_eof = TRUE;
159 } else {
160 ibuf_length = (size_t) r;
161 ibuf_index = 0;
162 }
163 }
164
165 if (FD_ISSET(fd, &ifds)) {
166 ssize_t r;
167 assert(!obuf_length);
168
169 if ((r = read(fd, obuf, sizeof(obuf))) <= 0) {
170 if (r < 0) {
171 pa_log(_("read(): %s"), strerror(errno));
172 goto fail;
173 }
174
175 obuf_eof = TRUE;
176 } else {
177 obuf_length = (size_t) r;
178 obuf_index = 0;
179 }
180 }
181
182 if (FD_ISSET(1, &ofds)) {
183 ssize_t r;
184 assert(obuf_length);
185
186 if ((r = write(1, obuf + obuf_index, obuf_length)) < 0) {
187 pa_log(_("write(): %s"), strerror(errno));
188 goto fail;
189 }
190
191 obuf_length -= (size_t) r;
192 obuf_index += obuf_index;
193
194 }
195
196 if (FD_ISSET(fd, &ofds)) {
197 ssize_t r;
198 assert(ibuf_length);
199
200 if ((r = write(fd, ibuf + ibuf_index, ibuf_length)) < 0) {
201 pa_log(_("write(): %s"), strerror(errno));
202 goto fail;
203 }
204
205 ibuf_length -= (size_t) r;
206 ibuf_index += obuf_index;
207 }
208
209 if (ibuf_length <= 0 && ibuf_eof && !ibuf_closed) {
210 close(0);
211 shutdown(fd, SHUT_WR);
212 ibuf_closed = TRUE;
213 }
214
215 if (obuf_length <= 0 && obuf_eof && !obuf_closed) {
216 shutdown(fd, SHUT_RD);
217 close(1);
218 obuf_closed = TRUE;
219 }
220 }
221
222 ret = 0;
223
224 fail:
225 if (fd >= 0)
226 pa_close(fd);
227
228 return ret;
229 }