1[+ AutoGen5 template c +] 2/* 3** Copyright (C) 2001-2017 Erik de Castro Lopo <erikd@mega-nerd.com> 4** 5** This program is free software; you can redistribute it and/or modify 6** it under the terms of the GNU General Public License as published by 7** the Free Software Foundation; either version 2 of the License, or 8** (at your option) any later version. 9** 10** This program is distributed in the hope that it will be useful, 11** but WITHOUT ANY WARRANTY; without even the implied warranty of 12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13** GNU General Public License for more details. 14** 15** You should have received a copy of the GNU General Public License 16** along with this program; if not, write to the Free Software 17** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18*/ 19 20/*========================================================================== 21** This is a test program which tests reading from and writing to pipes. 22*/ 23 24#include "sfconfig.h" 25 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29 30#if (OS_IS_WIN32 || defined __OS2__ || HAVE_PIPE == 0 || HAVE_WAITPID == 0) 31 32int 33main (void) 34{ 35 puts (" pipe_test : this test doesn't work on this OS.") ; 36 return 0 ; 37} /* main */ 38 39#else 40 41#if HAVE_UNISTD_H 42#include <unistd.h> 43#endif 44 45#include <errno.h> 46#include <sys/types.h> 47#include <sys/stat.h> 48#include <sys/wait.h> 49 50#include <sndfile.h> 51 52#include "utils.h" 53 54typedef struct 55{ int format ; 56 const char *ext ; 57} FILETYPE ; 58 59static void useek_pipe_rw_test (int filetype, const char *ext) ; 60static void pipe_read_test (int filetype, const char *ext) ; 61static void pipe_write_test (const char *ext) ; 62static void pipe_test_others (FILETYPE*, FILETYPE*) ; 63 64static 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" }, 71 /* Lite remove end */ 72 { 0 , NULL } 73} ; 74 75static 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" }, 89 /* Lite remove end */ 90 { 0 , NULL } 91} ; 92 93int 94main (void) 95{ int k ; 96 97 for (k = 0 ; read_only_types [k].format ; k++) 98 pipe_read_test (read_only_types [k].format, read_only_types [k].ext) ; 99 100 for (k = 0 ; read_write_types [k].format ; k++) 101 pipe_write_test (read_write_types [k].ext) ; 102 103 for (k = 0 ; read_write_types [k].format ; k++) 104 useek_pipe_rw_test (read_write_types [k].format, read_write_types [k].ext) ; 105 106 if (0) 107 pipe_test_others (read_write_types, read_only_types) ; 108 109 return 0 ; 110} /* main */ 111 112/*============================================================================== 113*/ 114 115static void 116pipe_read_test (int filetype, const char *ext) 117{ static short data [PIPE_TEST_LEN] ; 118 static char buffer [256] ; 119 static char filename [256] ; 120 121 SNDFILE *outfile ; 122 SF_INFO sfinfo ; 123 int k, retval ; 124 125 snprintf (filename, sizeof (filename), "pipe_in.%s", ext) ; 126 print_test_name ("pipe_read_test", filename) ; 127 128 memset (&sfinfo, 0, sizeof (sfinfo)) ; 129 sfinfo.format = filetype | SF_FORMAT_PCM_16 ; 130 sfinfo.channels = 1 ; 131 sfinfo.samplerate = 44100 ; 132 133 for (k = 0 ; k < PIPE_TEST_LEN ; k++) 134 data [k] = PIPE_INDEX (k) ; 135 136 outfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 137 test_writef_short_or_die (outfile, 0, data, PIPE_TEST_LEN, __LINE__) ; 138 sf_close (outfile) ; 139 140 snprintf (buffer, sizeof (buffer), "cat %s | ./tests/stdin_test %s ", filename, ext) ; 141 if ((retval = system (buffer)) != 0) 142 { retval = WEXITSTATUS (retval) ; 143 printf ("\n\n Line %d : pipe test returned error for file type \"%s\".\n\n", __LINE__, ext) ; 144 exit (retval) ; 145 } ; 146 147 unlink (filename) ; 148 puts ("ok") ; 149 150 return ; 151} /* pipe_read_test */ 152 153static void 154pipe_write_test (const char *ext) 155{ static char buffer [256] ; 156 157 int retval ; 158 159 print_test_name ("pipe_write_test", ext) ; 160 161 snprintf (buffer, sizeof (buffer), "./tests/stdout_test %s | ./tests/stdin_test %s ", ext, ext) ; 162 if ((retval = system (buffer))) 163 { retval = WEXITSTATUS (retval) ; 164 printf ("\n\n Line %d : pipe test returned error file type \"%s\".\n\n", __LINE__, ext) ; 165 exit (retval) ; 166 } ; 167 168 puts ("ok") ; 169 170 return ; 171} /* pipe_write_test */ 172 173/*============================================================================== 174*/ 175 176[+ FOR data_type +] 177static void 178useek_pipe_rw_[+ (get "type_name") +] (const char * ext, SF_INFO * psfinfo_write, SF_INFO * psfinfo_read) 179{ static [+ (get "type_name") +] buffer [PIPE_TEST_LEN] ; 180 static [+ (get "type_name") +] data [PIPE_TEST_LEN] ; 181 SNDFILE *outfile ; 182 SNDFILE *infile_piped ; 183 184 int k, status = 0 ; 185 int pipefd [2] ; 186 pid_t pida ; 187 188 for (k = 0 ; k < PIPE_TEST_LEN ; k++) 189 data [k] = PIPE_INDEX (k) ; 190 191 /* 192 ** Create the pipe. 193 */ 194 exit_if_true (pipe (pipefd) != 0, "\n\n%s %d : pipe failed : %s\n", __func__, __LINE__, strerror (errno)) ; 195 196 /* 197 ** Attach the write end of the pipe to be written to. 198 */ 199 if ((outfile = sf_open_fd (pipefd [1], SFM_WRITE, psfinfo_write, SF_TRUE)) == NULL) 200 { printf ("\n\n%s %d : unable to create unseekable pipe for write type \"%s\".\n", __func__, __LINE__, ext) ; 201 printf ("\t%s\n\n", sf_strerror (outfile)) ; 202 exit (1) ; 203 } ; 204 205 if (sf_error (outfile) != SF_ERR_NO_ERROR) 206 { printf ("\n\n%s %d : unable to open unseekable pipe for write type \"%s\".\n\n", __func__, __LINE__, ext) ; 207 exit (1) ; 208 } ; 209 210 /* 211 ** Attach the read end of the pipe to be read from. 212 */ 213 if ((infile_piped = sf_open_fd (pipefd [0], SFM_READ, psfinfo_read, SF_TRUE)) == NULL) 214 { printf ("\n\n%s %d : unable to create unseekable pipe for read type. \"%s\".\n\n", __func__, __LINE__, ext) ; 215 exit (1) ; 216 } ; 217 218 if (sf_error (infile_piped) != SF_ERR_NO_ERROR) 219 { printf ("\n\n%s %d : unable to open unseekable pipe for read type \"%s\".\n\n", __func__, __LINE__, ext) ; 220 exit (1) ; 221 } ; 222 223 /* Fork a child process that will write directly into the pipe. */ 224 if ((pida = fork ()) == 0) /* child process */ 225 { test_writef_[+ (get "type_name") +]_or_die (outfile, 0, data, PIPE_TEST_LEN, __LINE__) ; 226 exit (0) ; 227 } ; 228 229 /* In the parent process, read from the pipe and compare what is read 230 ** to what is written, if they match everything went as planned. 231 */ 232 test_readf_[+ (get "type_name") +]_or_die (infile_piped, 0, buffer, PIPE_TEST_LEN, __LINE__) ; 233 if (memcmp (buffer, data, sizeof (buffer)) != 0) 234 { printf ("\n\n%s %d : unseekable pipe test failed for file type \"%s\".\n\n", __func__, __LINE__, ext) ; 235 exit (1) ; 236 } ; 237 238 /* Wait for the child process to return. */ 239 waitpid (pida, &status, 0) ; 240 status = WEXITSTATUS (status) ; 241 sf_close (outfile) ; 242 sf_close (infile_piped) ; 243 244 if (status != 0) 245 { printf ("\n\n%s %d : status of child process is %d for file type %s.\n\n", __func__, __LINE__, status, ext) ; 246 exit (1) ; 247 } ; 248 249 return ; 250} /* useek_pipe_rw_[+ (get "type_name") +] */ 251 252[+ ENDFOR data_type +] 253 254 255static void 256useek_pipe_rw_test (int filetype, const char *ext) 257{ SF_INFO sfinfo_write ; 258 SF_INFO sfinfo_read ; 259 260 print_test_name ("useek_pipe_rw_test", ext) ; 261 262 /* 263 ** Setup the INFO structures for the filetype we will be 264 ** working with. 265 */ 266 sfinfo_write.format = filetype | SF_FORMAT_PCM_16 ; 267 sfinfo_write.channels = 1 ; 268 sfinfo_write.samplerate = 44100 ; 269 270 271 sfinfo_read.format = 0 ; 272 if (filetype == SF_FORMAT_RAW) 273 { sfinfo_read.format = filetype | SF_FORMAT_PCM_16 ; 274 sfinfo_read.channels = 1 ; 275 sfinfo_read.samplerate = 44100 ; 276 } ; 277 278 useek_pipe_rw_short (ext, &sfinfo_write, &sfinfo_read) ; 279 280 sfinfo_read.format = sfinfo_write.format = filetype | SF_FORMAT_FLOAT ; 281 if (sf_format_check (&sfinfo_read) != 0) 282 useek_pipe_rw_float (ext, &sfinfo_write, &sfinfo_read) ; 283 284 sfinfo_read.format = sfinfo_write.format = filetype | SF_FORMAT_DOUBLE ; 285 if (sf_format_check (&sfinfo_read) != 0) 286 useek_pipe_rw_double (ext, &sfinfo_write, &sfinfo_read) ; 287 288 puts ("ok") ; 289 return ; 290} /* useek_pipe_rw_test */ 291 292 293 294static void 295pipe_test_others (FILETYPE* list1, FILETYPE* list2) 296{ SF_FORMAT_INFO info ; 297 int k, m, major_count, in_list ; 298 299 print_test_name ("pipe_test_others", "") ; 300 301 sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof (int)) ; 302 303 for (k = 0 ; k < major_count ; k++) 304 { info.format = k ; 305 306 sf_command (NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof (info)) ; 307 308 in_list = SF_FALSE ; 309 for (m = 0 ; list1 [m].format ; m++) 310 if (info.format == list1 [m].format) 311 in_list = SF_TRUE ; 312 313 for (m = 0 ; list2 [m].format ; m++) 314 if (info.format == list2 [m].format) 315 in_list = SF_TRUE ; 316 317 if (in_list) 318 continue ; 319 320 printf ("%s %x\n", info.name, info.format) ; 321 322 if (1) 323 { static short data [PIPE_TEST_LEN] ; 324 static char buffer [256] ; 325 static const char *filename = "pipe_in.dat" ; 326 327 SNDFILE *outfile ; 328 SF_INFO sfinfo ; 329 int retval ; 330 331 memset (&sfinfo, 0, sizeof (sfinfo)) ; 332 sfinfo.format = info.format | SF_FORMAT_PCM_16 ; 333 sfinfo.channels = 1 ; 334 sfinfo.samplerate = 44100 ; 335 336 outfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 337 test_writef_short_or_die (outfile, 0, data, PIPE_TEST_LEN, __LINE__) ; 338 sf_close (outfile) ; 339 340 snprintf (buffer, sizeof (buffer), "cat %s | ./tests/stdin_test %s %d ", filename, info.extension, PIPE_TEST_LEN) ; 341 if ((retval = system (buffer)) == 0) 342 { retval = WEXITSTATUS (retval) ; 343 printf ("\n\n Line %d : pipe test should have returned error file type \"%s\" but didn't.\n\n", __LINE__, info.name) ; 344 exit (1) ; 345 } ; 346 347 unlink (filename) ; 348 } ; 349 } ; 350 351 352 puts ("ok") ; 353 354 return ; 355} /* pipe_test_others */ 356 357 358/*============================================================================== 359*/ 360 361#endif 362 363