]> code.delx.au - pulseaudio/blob - src/utils/pacmd.c
* split pa_cstrerror() into its own file polypcore/core-error.[ch]
[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 <polyp/error.h>
36 #include <polyp/util.h>
37
38 #include <polypcore/core-util.h>
39 #include <polypcore/log.h>
40 #include <polypcore/pid.h>
41
42 int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {
43 pid_t pid ;
44 int fd = -1;
45 int ret = 1, i;
46 struct sockaddr_un sa;
47 char ibuf[256], obuf[256];
48 size_t ibuf_index, ibuf_length, obuf_index, obuf_length;
49 fd_set ifds, ofds;
50
51 if (pa_pid_file_check_running(&pid) < 0) {
52 pa_log(__FILE__": no Polypaudio daemon running");
53 goto fail;
54 }
55
56 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
57 pa_log(__FILE__": socket(PF_UNIX, SOCK_STREAM, 0): %s", strerror(errno));
58 goto fail;
59 }
60
61 memset(&sa, 0, sizeof(sa));
62 sa.sun_family = AF_UNIX;
63 pa_runtime_path("cli", sa.sun_path, sizeof(sa.sun_path));
64
65 for (i = 0; i < 5; i++) {
66 int r;
67
68 if ((r = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 && (errno != ECONNREFUSED && errno != ENOENT)) {
69 pa_log(__FILE__": connect(): %s", strerror(errno));
70 goto fail;
71 }
72
73 if (r >= 0)
74 break;
75
76 if (pa_pid_file_kill(SIGUSR2, NULL) < 0) {
77 pa_log(__FILE__": failed to kill Polypaudio daemon.");
78 goto fail;
79 }
80
81 pa_msleep(50);
82 }
83
84 if (i >= 5) {
85 pa_log(__FILE__": daemon not responding.");
86 goto fail;
87 }
88
89 ibuf_index = ibuf_length = obuf_index = obuf_length = 0;
90
91
92 FD_ZERO(&ifds);
93 FD_SET(0, &ifds);
94 FD_SET(fd, &ifds);
95
96 FD_ZERO(&ofds);
97
98 for (;;) {
99 if (select(FD_SETSIZE, &ifds, &ofds, NULL, NULL) < 0) {
100 pa_log(__FILE__": select(): %s", strerror(errno));
101 goto fail;
102 }
103
104 if (FD_ISSET(0, &ifds)) {
105 ssize_t r;
106 assert(!ibuf_length);
107
108 if ((r = read(0, ibuf, sizeof(ibuf))) <= 0) {
109 if (r == 0)
110 break;
111
112 pa_log(__FILE__": read(): %s", strerror(errno));
113 goto fail;
114 }
115
116 ibuf_length = (size_t) r;
117 ibuf_index = 0;
118 }
119
120 if (FD_ISSET(fd, &ifds)) {
121 ssize_t r;
122 assert(!obuf_length);
123
124 if ((r = read(fd, obuf, sizeof(obuf))) <= 0) {
125 if (r == 0)
126 break;
127
128 pa_log(__FILE__": read(): %s", strerror(errno));
129 goto fail;
130 }
131
132 obuf_length = (size_t) r;
133 obuf_index = 0;
134 }
135
136 if (FD_ISSET(1, &ofds)) {
137 ssize_t r;
138 assert(obuf_length);
139
140 if ((r = write(1, obuf + obuf_index, obuf_length)) < 0) {
141 pa_log(__FILE__": write(): %s", strerror(errno));
142 goto fail;
143 }
144
145 obuf_length -= (size_t) r;
146 obuf_index += obuf_index;
147
148 }
149
150 if (FD_ISSET(fd, &ofds)) {
151 ssize_t r;
152 assert(ibuf_length);
153
154 if ((r = write(fd, ibuf + ibuf_index, ibuf_length)) < 0) {
155 pa_log(__FILE__": write(): %s", strerror(errno));
156 goto fail;
157 }
158
159 ibuf_length -= (size_t) r;
160 ibuf_index += obuf_index;
161
162 }
163
164 FD_ZERO(&ifds);
165 FD_ZERO(&ofds);
166
167 if (obuf_length <= 0)
168 FD_SET(fd, &ifds);
169 else
170 FD_SET(1, &ofds);
171
172 if (ibuf_length <= 0)
173 FD_SET(0, &ifds);
174 else
175 FD_SET(fd, &ofds);
176 }
177
178
179 ret = 0;
180
181 fail:
182 if (fd >= 0)
183 close(fd);
184
185 return ret;
186 }