Bug Summary

File:main/audsp.cc
Location:line 285, column 5
Description:The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage

Annotated Source Code

1/*************************************************************************/
2/* */
3/* Centre for Speech Technology Research */
4/* University of Edinburgh, UK */
5/* Copyright (c) 1996,1997 */
6/* All Rights Reserved. */
7/* */
8/* Permission is hereby granted, free of charge, to use and distribute */
9/* this software and its documentation without restriction, including */
10/* without limitation the rights to use, copy, modify, merge, publish, */
11/* distribute, sublicense, and/or sell copies of this work, and to */
12/* permit persons to whom this work is furnished to do so, subject to */
13/* the following conditions: */
14/* 1. The code must retain the above copyright notice, this list of */
15/* conditions and the following disclaimer. */
16/* 2. Any modifications must be clearly marked as such. */
17/* 3. Original authors' names are not deleted. */
18/* 4. The authors' names are not used to endorse or promote products */
19/* derived from this software without specific prior written */
20/* permission. */
21/* */
22/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30/* THIS SOFTWARE. */
31/* */
32/*************************************************************************/
33/* Author : Alan W Black */
34/* Date : September 1996 */
35/*-----------------------------------------------------------------------*/
36/* */
37/* An audio file spooler, like lpd. Reads in commands about files to */
38/* to play, and queues them until any previous requests are finished. */
39/* This allows the synthesizer to get on with synthesizing the next */
40/* utterance. */
41/* */
42/* Actually this doesn't use anything in Festival, only the speech_tools */
43/*=======================================================================*/
44#include <cstdlib>
45#include <cstdio>
46#include <cstring>
47#include <csignal>
48
49using namespace std;
50
51#include "EST.h"
52#include "EST_unix.h"
53
54#ifdef NO_SPOOLER
55
56int main(int argc, char **argv)
57{
58
59 printf("Audio spooler not supported\n");
60 return 0;
61}
62
63#else
64
65class Command {
66 private:
67 EST_String p_file;
68 int p_rate;
69 public:
70 Command(const EST_String &f, int rate) { p_file=f; p_rate=rate; }
71 int rate(void) const { return p_rate; }
72 const EST_String &file(void) const { return p_file; }
73};
74
75class CQueue_Item {
76 public:
77 Command *c;
78 CQueue_Item *next;
79 CQueue_Item(Command *com) { c=com; next=0; }
80 ~CQueue_Item() { delete c; if (next != 0) delete next; }
81};
82
83class CQueue {
84 private:
85 CQueue_Item *head;
86 CQueue_Item *tail;
87 public:
88 CQueue() { head = tail = 0; }
89 ~CQueue() { delete head; }
90 void push(Command *c);
91 Command *pop(void);
92 void display(void) const;
93 int length(void) const;
94 void clear(void);
95};
96
97static void auspl_main(int argc, char **argv);
98static void check_new_input(void);
99static char *read_a_line(void);
100static void process_command(char *line);
101static void check_new_output(void);
102static int execute_command(Command *c);
103static void load_play_file(Command *c);
104static int sp_terminate(void);
105static void tidy_up(void);
106
107void CQueue::push(Command *c)
108{
109 // Put this item on tail
110 CQueue_Item *n = new CQueue_Item(c);
111
112 if (head == 0)
113 { // first one
114 head = n;
115 tail = n;
116 }
117 else
118 {
119 tail->next = n;
120 tail = n;
121 }
122}
123
124Command *CQueue::pop(void)
125{
126 // Pop top from the queue
127
128 if (head == 0)
129 return 0;
130 else
131 {
132 Command *c = head->c;
133 CQueue_Item *h;
134 h = head;
135 h->c = 0;
136 head = head->next;
137 h->next = 0;
138 delete h;
139 return c;
140 }
141}
142
143void CQueue::display(void) const
144{
145 CQueue_Item *t;
146 int i;
147
148 cerr << "Command_queue: " << length() << endl;
149 for (i=0,t=head; t != 0; t=t->next,i++)
150 cerr << " " << i << ": " << t->c->file() << endl;
151}
152
153int CQueue::length(void) const
154{
155 // length of queue
156 CQueue_Item *t;
157 int i;
158
159 for (i=0,t=head; t != 0; t=t->next)
160 i++;
161
162 return i;
163}
164
165void CQueue::clear(void)
166{
167 // Remove all memebers in the queue
168 CQueue_Item *t;
169
170 // Somebody has to do it ...
171 for (t=head; t != 0; t=t->next)
172 unlink(t->c->file());
173
174 delete head;
175 head = 0;
176 tail = 0;
177}
178
179static int no_more_input = FALSE(1==0);
180static CQueue command_queue;
181static int child_pid = 0;
182static EST_String current_file;
183static EST_Option play_wave_options;
184static int maxqueue = 5;
185static int pending_close = FALSE(1==0);
186static int kids = 0;
187
188int main(int argc, char **argv)
189{
190
191 auspl_main(argc,argv);
192
193 return 0;
194}
195
196static void auspl_main(int argc, char **argv)
197{
198 EST_Option al;
199 EST_StrList files;
200
201 parse_command_line(argc, argv,
202 EST_String("Usage: audio spooler \n")+
203 "auspl <options> <file0> <file1> ...\n"+
204 "--method <string> audio play method\n"+
205 "--command <string> Unix command to play file, used when\n"+
206 " method is audio_command\n"+
207 "--maxqueue <int> {5} Maximum number of files in queue\n",
208 files, al);
209
210 if (al.present("--method"))
211 play_wave_options.add_item("-p",al.val("--method"));
212 if (al.present("--command"))
213 play_wave_options.add_item("-command",al.val("--command"));
214 play_wave_options.add_item("-quality","HIGH");
215
216 if (al.present("--maxqueue"))
217 maxqueue = al.ival("--maxqueue");
218
219 while (!sp_terminate())
220 {
221 check_new_input();
222 check_new_output();
223 }
224
225 tidy_up();
226}
227
228static int sp_terminate(void)
229{
230 // I'm never very sure of all the conditions necessary to terminate
231
232 if (no_more_input && (command_queue.length() == 0))
233 return TRUE(1==1);
234 else
235 return FALSE(1==0);
236}
237
238static void tidy_up(void)
239{
240 // should wait for any remaining children if I've been
241 // requested to.
242 int pid;
243 int statusp;
244
245 if (pending_close == TRUE(1==1))
246 {
247 while (kids > 0)
248 {
249 pid = waitpid(0,&statusp,0);
250 kids--;
251 }
252 fprintf(stdoutstdout,"OK\n"); // give an acknowledgement
253 fflush(stdoutstdout);
254 }
255
256 return;
257}
258
259static void check_new_input(void)
260{
261 // Do a select on stdin to find out if there is any new
262 // commands to process
263 fd_set inset;
264 fd_set outset;
265 fd_set exset;
266 struct timeval t;
267 int sv;
268
269 t.tv_sec = 0;
270 t.tv_usec = 1000; // 0.1 seconds
271
272 FD_ZERO(&inset)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&inset)->fds_bits)[0
]) : "memory"); } while (0)
;
273 FD_ZERO(&outset)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&outset)->fds_bits)[
0]) : "memory"); } while (0)
;
274 FD_ZERO(&exset)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&exset)->fds_bits)[0
]) : "memory"); } while (0)
;
275
276 if ((command_queue.length() >= maxqueue) ||
1
Taking false branch
277 no_more_input)
278 {
279 // wait a bit for the queue to go down a bit
280 // not we're selecting on no fds at all, just for the delay
281 sv = select(0,&inset,&outset,&exset,&t);
282 return;
283 }
284
285 FD_SET(0,&inset)((void) (((&inset)->fds_bits)[((0) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((0) % (8 * (int) sizeof
(__fd_mask))))))
;
2
Within the expansion of the macro 'FD_SET':
a
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage
286
287 sv = select(1,&inset,&outset,&exset,&t);
288
289 if (sv == 1)
290 process_command(read_a_line());
291 else if (sv == -1)
292 no_more_input = TRUE(1==1);
293}
294
295static int getc_unbuffered(int fd)
296{
297 // An attempted to get rid of the buffering
298 char c;
299 int n;
300
301 n = read(fd,&c,1);
302
303 if (n == 0)
304 return EOF(-1);
305 else
306 return c;
307}
308
309static char *read_a_line(void)
310{
311 // read upto \n on stdin -- wonder if I should read instead
312 int maxsize = 1024;
313 char *line = walloc(char,maxsize+2)((char *)safe_walloc(sizeof(char)*(maxsize+2)));
314 int i,c;
315
316 for (i=0;
317 (((c=getc_unbuffered(0)) != '\n') &&
318 (c != EOF(-1)));
319 i++)
320 {
321 if (i == maxsize)
322 {
323 char *nline = walloc(char,maxsize*2)((char *)safe_walloc(sizeof(char)*(maxsize*2)));
324 memcpy(nline,line,maxsize);
325 maxsize = maxsize*2;
326 wfree(line);
327 line = nline;
328 }
329 line[i] = c;
330 }
331
332 line[i] = '\n';
333 line[i+1] = '\0';
334 if (c == EOF(-1))
335 no_more_input = TRUE(1==1);
336
337 if (strncmp(line,"close",5) != 0)
338 {
339 fprintf(stdoutstdout,"OK\n"); // give an acknowledgement
340 fflush(stdoutstdout);
341 }
342
343 return line;
344}
345
346static void process_command(char *line)
347{
348 // Process command, some are immediate
349 EST_TokenStream ts;
350 ts.open_string(line);
351 EST_String comm = ts.get().string();
352
353 if ((comm == "quit") || (comm == ""))
354 {
355 no_more_input = TRUE(1==1);
356 }
357 else if (comm == "play")
358 {
359 EST_String file = ts.get().string();
360 int rate = atoi(ts.get().string());
361 Command *c = new Command(file,rate);
362 command_queue.push(c);
363 }
364 else if (comm == "method")
365 {
366 play_wave_options.add_item("-p",ts.get().string());
367 }
368 else if (comm == "command")
369 {
370 play_wave_options.add_item("-command",ts.get_upto_eoln().string());
371 }
372 else if (comm == "rate")
373 {
374 play_wave_options.add_item("-rate",ts.get().string());
375 }
376 else if (comm == "otype")
377 {
378 play_wave_options.add_item("-otype",ts.get().string());
379 }
380 else if (comm == "device")
381 {
382 play_wave_options.add_item("-audiodevice",ts.get().string());
383 }
384 else if (comm == "close")
385 {
386 pending_close = TRUE(1==1);
387 no_more_input = TRUE(1==1);
388 }
389 else if (comm == "shutup")
390 {
391 // clear queue and kill and child currently playing
392 command_queue.clear();
393 if (child_pid != 0)
394 {
395 kill(child_pid,SIGKILL9);
396 unlink(current_file);
397 }
398 }
399 else if (comm == "query")
400 command_queue.display();
401 else if (comm != "")
402 {
403 cerr << "audsp: unknown command \"" << comm << "\"\n";
404 }
405
406 ts.close();
407 wfree(line);
408}
409
410static void check_new_output(void)
411{
412 // If we are not waiting on any children lauch next command
413 int pid;
414 int statusp;
415
416 if (kids > 0)
417 {
418 pid = waitpid(0,&statusp,WNOHANG1);
419 if (pid != 0)
420 {
421 kids--;
422 child_pid = 0;
423 }
424 }
425 else if (command_queue.length() != 0)
426 {
427 Command *c = command_queue.pop();
428 if (execute_command(c) == 0)
429 kids++;
430 delete c;
431 }
432
433 // else do nothing
434}
435
436static int execute_command(Command *c)
437{
438 // Execute the command as a child process
439 int pid;
440
441 current_file = c->file();
442
443 if ((pid=fork()) == 0)
444 { // child process
445 load_play_file(c);
446 _exit(0); // don't close any files on exit
447 return 0; // can't get here
448 }
449 else if (pid > 0)
450 { // parent process
451 child_pid = pid;
452 return 0;
453 }
454 else
455 {
456 cerr << "auspd: fork failed, \"" << c->file() << "\"\n";
457 return -1;
458 }
459}
460
461static void load_play_file(Command *c)
462{
463 // Load in wave file and play it
464
465 EST_Wave w;
466
467 w.load(c->file());
468 play_wave(w,play_wave_options);
469 unlink(c->file()); // delete it afterwards
470}
471
472#endif