2 ** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU General Public License for more details.
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 /*==========================================================================
20 ** This is a test program which tests reading from and writing to pipes.
29 #if (OS_IS_WIN32 || HAVE_PIPE == 0 || HAVE_WAITPID == 0)
34 puts (" pipe_test : this test doesn't work on this OS.") ;
45 #include <sys/types.h>
58 static int file_exists (const char *filename
) ;
59 static void useek_pipe_rw_test (int filetype
, const char *ext
) ;
60 static void pipe_read_test (int filetype
, const char *ext
) ;
61 static void pipe_write_test (const char *ext
) ;
62 static void pipe_test_others (FILETYPE
*, FILETYPE
*) ;
64 static FILETYPE read_write_types
[] =
65 { { SF_FORMAT_RAW
, "raw" },
66 { SF_FORMAT_AU
, "au" },
67 /* Lite remove start */
68 { SF_FORMAT_PAF
, "paf" },
69 { SF_FORMAT_IRCAM
, "ircam" },
70 { SF_FORMAT_PVF
, "pvf" },
75 static FILETYPE read_only_types
[] =
76 { { SF_FORMAT_RAW
, "raw" },
77 { SF_FORMAT_AU
, "au" },
78 { SF_FORMAT_AIFF
, "aiff" },
79 { SF_FORMAT_WAV
, "wav" },
80 { SF_FORMAT_W64
, "w64" },
81 /* Lite remove start */
82 { SF_FORMAT_PAF
, "paf" },
83 { SF_FORMAT_NIST
, "nist" },
84 { SF_FORMAT_IRCAM
, "ircam" },
85 { SF_FORMAT_MAT4
, "mat4" },
86 { SF_FORMAT_MAT5
, "mat5" },
87 { SF_FORMAT_SVX
, "svx" },
88 { SF_FORMAT_PVF
, "pvf" },
97 if (file_exists ("libsndfile.spec.in"))
98 exit_if_true (chdir ("tests") != 0, "\n Error : chdir ('tests') failed.\n") ;
100 for (k
= 0 ; read_only_types
[k
].format
; k
++)
101 pipe_read_test (read_only_types
[k
].format
, read_only_types
[k
].ext
) ;
103 for (k
= 0 ; read_write_types
[k
].format
; k
++)
104 pipe_write_test (read_write_types
[k
].ext
) ;
106 for (k
= 0 ; read_write_types
[k
].format
; k
++)
107 useek_pipe_rw_test (read_write_types
[k
].format
, read_write_types
[k
].ext
) ;
110 pipe_test_others (read_write_types
, read_only_types
) ;
115 /*==============================================================================
119 pipe_read_test (int filetype
, const char *ext
)
120 { static short data
[PIPE_TEST_LEN
] ;
121 static char buffer
[256] ;
122 static char filename
[256] ;
128 snprintf (filename
, sizeof (filename
), "pipe_in.%s", ext
) ;
129 print_test_name ("pipe_read_test", filename
) ;
131 sfinfo
.format
= filetype
| SF_FORMAT_PCM_16
;
132 sfinfo
.channels
= 1 ;
133 sfinfo
.samplerate
= 44100 ;
135 for (k
= 0 ; k
< PIPE_TEST_LEN
; k
++)
136 data
[k
] = PIPE_INDEX (k
) ;
138 outfile
= test_open_file_or_die (filename
, SFM_WRITE
, &sfinfo
, SF_TRUE
, __LINE__
) ;
139 test_writef_short_or_die (outfile
, 0, data
, PIPE_TEST_LEN
, __LINE__
) ;
142 snprintf (buffer
, sizeof (buffer
), "cat %s | ./stdin_test %s ", filename
, ext
) ;
143 if ((retval
= system (buffer
)) != 0)
144 { retval
= WEXITSTATUS (retval
) ;
145 printf ("\n\n Line %d : pipe test returned error for file type \"%s\".\n\n", __LINE__
, ext
) ;
153 } /* pipe_read_test */
156 pipe_write_test (const char *ext
)
157 { static char buffer
[256] ;
161 print_test_name ("pipe_write_test", ext
) ;
163 snprintf (buffer
, sizeof (buffer
), "./stdout_test %s | ./stdin_test %s ", ext
, ext
) ;
164 if ((retval
= system (buffer
)))
165 { retval
= WEXITSTATUS (retval
) ;
166 printf ("\n\n Line %d : pipe test returned error file type \"%s\".\n\n", __LINE__
, ext
) ;
173 } /* pipe_write_test */
175 /*==============================================================================
180 useek_pipe_rw_short (const char * ext
, SF_INFO
* psfinfo_write
, SF_INFO
* psfinfo_read
)
181 { static short buffer
[PIPE_TEST_LEN
] ;
182 static short data
[PIPE_TEST_LEN
] ;
184 SNDFILE
*infile_piped
;
190 for (k
= 0 ; k
< PIPE_TEST_LEN
; k
++)
191 data
[k
] = PIPE_INDEX (k
) ;
196 exit_if_true (pipe (pipefd
) != 0, "\n\n%s %d : pipe failed : %s\n", __func__
, __LINE__
, strerror (errno
)) ;
199 ** Attach the write end of the pipe to be written to.
201 if ((outfile
= sf_open_fd (pipefd
[1], SFM_WRITE
, psfinfo_write
, SF_TRUE
)) == NULL
)
202 { printf ("\n\n%s %d : unable to create unseekable pipe for write type \"%s\".\n", __func__
, __LINE__
, ext
) ;
203 printf ("\t%s\n\n", sf_strerror (outfile
)) ;
207 if (sf_error (outfile
) != SF_ERR_NO_ERROR
)
208 { printf ("\n\n%s %d : unable to open unseekable pipe for write type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
213 ** Attach the read end of the pipe to be read from.
215 if ((infile_piped
= sf_open_fd (pipefd
[0], SFM_READ
, psfinfo_read
, SF_TRUE
)) == NULL
)
216 { printf ("\n\n%s %d : unable to create unseekable pipe for read type. \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
220 if (sf_error (infile_piped
) != SF_ERR_NO_ERROR
)
221 { printf ("\n\n%s %d : unable to open unseekable pipe for read type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
225 /* Fork a child process that will write directly into the pipe. */
226 if ((pida
= fork ()) == 0) /* child process */
227 { test_writef_short_or_die (outfile
, 0, data
, PIPE_TEST_LEN
, __LINE__
) ;
231 /* In the parent process, read from the pipe and compare what is read
232 ** to what is written, if they match everything went as planned.
234 test_readf_short_or_die (infile_piped
, 0, buffer
, PIPE_TEST_LEN
, __LINE__
) ;
235 if (memcmp (buffer
, data
, sizeof (buffer
)) != 0)
236 { printf ("\n\n%s %d : unseekable pipe test failed for file type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
240 /* Wait for the child process to return. */
241 waitpid (pida
, &status
, 0) ;
242 status
= WEXITSTATUS (status
) ;
244 sf_close (infile_piped
) ;
247 { printf ("\n\n%s %d : status of child process is %d for file type %s.\n\n", __func__
, __LINE__
, status
, ext
) ;
252 } /* useek_pipe_rw_short */
256 useek_pipe_rw_float (const char * ext
, SF_INFO
* psfinfo_write
, SF_INFO
* psfinfo_read
)
257 { static float buffer
[PIPE_TEST_LEN
] ;
258 static float data
[PIPE_TEST_LEN
] ;
260 SNDFILE
*infile_piped
;
266 for (k
= 0 ; k
< PIPE_TEST_LEN
; k
++)
267 data
[k
] = PIPE_INDEX (k
) ;
272 exit_if_true (pipe (pipefd
) != 0, "\n\n%s %d : pipe failed : %s\n", __func__
, __LINE__
, strerror (errno
)) ;
275 ** Attach the write end of the pipe to be written to.
277 if ((outfile
= sf_open_fd (pipefd
[1], SFM_WRITE
, psfinfo_write
, SF_TRUE
)) == NULL
)
278 { printf ("\n\n%s %d : unable to create unseekable pipe for write type \"%s\".\n", __func__
, __LINE__
, ext
) ;
279 printf ("\t%s\n\n", sf_strerror (outfile
)) ;
283 if (sf_error (outfile
) != SF_ERR_NO_ERROR
)
284 { printf ("\n\n%s %d : unable to open unseekable pipe for write type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
289 ** Attach the read end of the pipe to be read from.
291 if ((infile_piped
= sf_open_fd (pipefd
[0], SFM_READ
, psfinfo_read
, SF_TRUE
)) == NULL
)
292 { printf ("\n\n%s %d : unable to create unseekable pipe for read type. \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
296 if (sf_error (infile_piped
) != SF_ERR_NO_ERROR
)
297 { printf ("\n\n%s %d : unable to open unseekable pipe for read type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
301 /* Fork a child process that will write directly into the pipe. */
302 if ((pida
= fork ()) == 0) /* child process */
303 { test_writef_float_or_die (outfile
, 0, data
, PIPE_TEST_LEN
, __LINE__
) ;
307 /* In the parent process, read from the pipe and compare what is read
308 ** to what is written, if they match everything went as planned.
310 test_readf_float_or_die (infile_piped
, 0, buffer
, PIPE_TEST_LEN
, __LINE__
) ;
311 if (memcmp (buffer
, data
, sizeof (buffer
)) != 0)
312 { printf ("\n\n%s %d : unseekable pipe test failed for file type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
316 /* Wait for the child process to return. */
317 waitpid (pida
, &status
, 0) ;
318 status
= WEXITSTATUS (status
) ;
320 sf_close (infile_piped
) ;
323 { printf ("\n\n%s %d : status of child process is %d for file type %s.\n\n", __func__
, __LINE__
, status
, ext
) ;
328 } /* useek_pipe_rw_float */
332 useek_pipe_rw_double (const char * ext
, SF_INFO
* psfinfo_write
, SF_INFO
* psfinfo_read
)
333 { static double buffer
[PIPE_TEST_LEN
] ;
334 static double data
[PIPE_TEST_LEN
] ;
336 SNDFILE
*infile_piped
;
342 for (k
= 0 ; k
< PIPE_TEST_LEN
; k
++)
343 data
[k
] = PIPE_INDEX (k
) ;
348 exit_if_true (pipe (pipefd
) != 0, "\n\n%s %d : pipe failed : %s\n", __func__
, __LINE__
, strerror (errno
)) ;
351 ** Attach the write end of the pipe to be written to.
353 if ((outfile
= sf_open_fd (pipefd
[1], SFM_WRITE
, psfinfo_write
, SF_TRUE
)) == NULL
)
354 { printf ("\n\n%s %d : unable to create unseekable pipe for write type \"%s\".\n", __func__
, __LINE__
, ext
) ;
355 printf ("\t%s\n\n", sf_strerror (outfile
)) ;
359 if (sf_error (outfile
) != SF_ERR_NO_ERROR
)
360 { printf ("\n\n%s %d : unable to open unseekable pipe for write type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
365 ** Attach the read end of the pipe to be read from.
367 if ((infile_piped
= sf_open_fd (pipefd
[0], SFM_READ
, psfinfo_read
, SF_TRUE
)) == NULL
)
368 { printf ("\n\n%s %d : unable to create unseekable pipe for read type. \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
372 if (sf_error (infile_piped
) != SF_ERR_NO_ERROR
)
373 { printf ("\n\n%s %d : unable to open unseekable pipe for read type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
377 /* Fork a child process that will write directly into the pipe. */
378 if ((pida
= fork ()) == 0) /* child process */
379 { test_writef_double_or_die (outfile
, 0, data
, PIPE_TEST_LEN
, __LINE__
) ;
383 /* In the parent process, read from the pipe and compare what is read
384 ** to what is written, if they match everything went as planned.
386 test_readf_double_or_die (infile_piped
, 0, buffer
, PIPE_TEST_LEN
, __LINE__
) ;
387 if (memcmp (buffer
, data
, sizeof (buffer
)) != 0)
388 { printf ("\n\n%s %d : unseekable pipe test failed for file type \"%s\".\n\n", __func__
, __LINE__
, ext
) ;
392 /* Wait for the child process to return. */
393 waitpid (pida
, &status
, 0) ;
394 status
= WEXITSTATUS (status
) ;
396 sf_close (infile_piped
) ;
399 { printf ("\n\n%s %d : status of child process is %d for file type %s.\n\n", __func__
, __LINE__
, status
, ext
) ;
404 } /* useek_pipe_rw_double */
410 useek_pipe_rw_test (int filetype
, const char *ext
)
411 { SF_INFO sfinfo_write
;
412 SF_INFO sfinfo_read
;
414 print_test_name ("useek_pipe_rw_test", ext
) ;
417 ** Setup the INFO structures for the filetype we will be
420 sfinfo_write
.format
= filetype
| SF_FORMAT_PCM_16
;
421 sfinfo_write
.channels
= 1 ;
422 sfinfo_write
.samplerate
= 44100 ;
425 sfinfo_read
.format
= 0 ;
426 if (filetype
== SF_FORMAT_RAW
)
427 { sfinfo_read
.format
= filetype
| SF_FORMAT_PCM_16
;
428 sfinfo_read
.channels
= 1 ;
429 sfinfo_read
.samplerate
= 44100 ;
432 useek_pipe_rw_short (ext
, &sfinfo_write
, &sfinfo_read
) ;
434 sfinfo_read
.format
= sfinfo_write
.format
= filetype
| SF_FORMAT_FLOAT
;
435 if (sf_format_check (&sfinfo_read
) != 0)
436 useek_pipe_rw_float (ext
, &sfinfo_write
, &sfinfo_read
) ;
438 sfinfo_read
.format
= sfinfo_write
.format
= filetype
| SF_FORMAT_DOUBLE
;
439 if (sf_format_check (&sfinfo_read
) != 0)
440 useek_pipe_rw_double (ext
, &sfinfo_write
, &sfinfo_read
) ;
444 } /* useek_pipe_rw_test */
449 pipe_test_others (FILETYPE
* list1
, FILETYPE
* list2
)
450 { SF_FORMAT_INFO info
;
451 int k
, m
, major_count
, in_list
;
453 print_test_name ("pipe_test_others", "") ;
455 sf_command (NULL
, SFC_GET_FORMAT_MAJOR_COUNT
, &major_count
, sizeof (int)) ;
457 for (k
= 0 ; k
< major_count
; k
++)
460 sf_command (NULL
, SFC_GET_FORMAT_MAJOR
, &info
, sizeof (info
)) ;
463 for (m
= 0 ; list1
[m
].format
; m
++)
464 if (info
.format
== list1
[m
].format
)
467 for (m
= 0 ; list2
[m
].format
; m
++)
468 if (info
.format
== list2
[m
].format
)
474 printf ("%s %x\n", info
.name
, info
.format
) ;
477 { static short data
[PIPE_TEST_LEN
] ;
478 static char buffer
[256] ;
479 static const char *filename
= "pipe_in.dat" ;
485 sfinfo
.format
= info
.format
| SF_FORMAT_PCM_16
;
486 sfinfo
.channels
= 1 ;
487 sfinfo
.samplerate
= 44100 ;
489 outfile
= test_open_file_or_die (filename
, SFM_WRITE
, &sfinfo
, SF_TRUE
, __LINE__
) ;
490 test_writef_short_or_die (outfile
, 0, data
, PIPE_TEST_LEN
, __LINE__
) ;
493 snprintf (buffer
, sizeof (buffer
), "cat %s | ./stdin_test %s %d ", filename
, info
.extension
, PIPE_TEST_LEN
) ;
494 if ((retval
= system (buffer
)) == 0)
495 { retval
= WEXITSTATUS (retval
) ;
496 printf ("\n\n Line %d : pipe test should have returned error file type \"%s\" but didn't.\n\n", __LINE__
, info
.name
) ;
508 } /* pipe_test_others */
511 /*==============================================================================
515 file_exists (const char *filename
)
518 if (stat (filename
, &buf
))