* new tool pacmd
[profile/ivi/pulseaudio-panda.git] / polyp / 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 "util.h"
36 #include "log.h"
37 #include "pid.h"
38
39 int main() {
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(10);
79     }
80
81     if (i >= 5) {
82         pa_log(__FILE__": daemon to 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 }