diff --git a/alsa-utils-git-fixes.diff b/alsa-utils-git-fixes.diff deleted file mode 100644 index 53ad2ba..0000000 --- a/alsa-utils-git-fixes.diff +++ /dev/null @@ -1,1430 +0,0 @@ -diff --git a/alsactl/alsactl.c b/alsactl/alsactl.c -index 02e082f..3b5dfda 100644 ---- a/alsactl/alsactl.c -+++ b/alsactl/alsactl.c -@@ -189,5 +189,5 @@ int main(int argc, char *argv[]) - } - - snd_config_update_free_global(); -- return res < 0 ? res : 0; -+ return res < 0 ? -res : 0; - } -diff --git a/alsactl/alsactl.h b/alsactl/alsactl.h -index 89ad295..be90efb 100644 ---- a/alsactl/alsactl.h -+++ b/alsactl/alsactl.h -@@ -34,16 +34,16 @@ extern char *statefile; - - #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) - #define cerror(cond, ...) do {\ -- if (cond) { \ -- fprintf(stderr, "%s: %s:%d: ", command, __FUNCTION__, __LINE__); \ -+ if (cond || debugflag) { \ -+ fprintf(stderr, "%s%s: %s:%d: ", debugflag ? "WARNING: " : "", command, __FUNCTION__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ - putc('\n', stderr); \ - } \ - } while (0) - #else - #define cerror(cond, args...) do {\ -- if (cond) { \ -- fprintf(stderr, "%s: %s:%d: ", command, __FUNCTION__, __LINE__); \ -+ if (cond || debugflag) { \ -+ fprintf(stderr, "%s%s: %s:%d: ", debugflag ? "WARNING: " : "", command, __FUNCTION__, __LINE__); \ - fprintf(stderr, ##args); \ - putc('\n', stderr); \ - } \ -@@ -78,7 +78,7 @@ int generate_names(const char *cfgfile); - int file_map(const char *filename, char **buf, size_t *bufsize); - void file_unmap(void *buf, size_t bufsize); - size_t line_width(const char *buf, size_t bufsize, size_t pos); --void initfailed(int cardnumber, const char *reason); -+void initfailed(int cardnumber, const char *reason, int exitcode); - - static inline int hextodigit(int c) - { -diff --git a/alsactl/state.c b/alsactl/state.c -index 635a999..e70c6f9 100644 ---- a/alsactl/state.c -+++ b/alsactl/state.c -@@ -1117,7 +1117,6 @@ static int restore_config_value2(snd_ctl_t *handle, snd_ctl_elem_info_t *info, - } - snd_ctl_elem_value_set_byte(ctl, idx, val); - return 1; -- break; - default: - break; - } -@@ -1404,6 +1403,7 @@ static int set_controls(int card, snd_config_t *top, int doit) - snd_ctl_card_info_alloca(&info); - - sprintf(name, "hw:%d", card); -+ dbg("device='%s', doit=%i", name, doit); - err = snd_ctl_open(&handle, name, 0); - if (err < 0) { - error("snd_ctl_open error: %s", snd_strerror(err)); -@@ -1415,6 +1415,7 @@ static int set_controls(int card, snd_config_t *top, int doit) - goto _close; - } - id = snd_ctl_card_info_get_id(info); -+ dbg("card-info-id: '%s'", id); - err = snd_config_searchv(top, &control, "state", id, "control", 0); - if (err < 0) { - if (force_restore) { -@@ -1440,24 +1441,25 @@ static int set_controls(int card, snd_config_t *top, int doit) - goto _close; - } - -+ dbg("maxnumid=%i", maxnumid); - /* check if we have additional controls in driver */ - /* in this case we should go through init procedure */ - if (!doit && maxnumid >= 0) { -- snd_ctl_elem_id_t *id; - snd_ctl_elem_info_t *info; -- snd_ctl_elem_id_alloca(&id); - snd_ctl_elem_info_alloca(&info); - snd_ctl_elem_info_set_numid(info, maxnumid+1); - if (snd_ctl_elem_info(handle, info) == 0) { - /* not very informative */ - /* but value is used for check only */ - err = -EAGAIN; -+ dbg("more controls than maxnumid?"); - goto _close; - } - } - - _close: - snd_ctl_close(handle); -+ dbg("result code: %i", err); - return err; - } - -@@ -1582,9 +1584,9 @@ int load_state(const char *file, const char *initfile, const char *cardname, - err = init(initfile, cardname1); - if (err < 0) { - finalerr = err; -- initfailed(card, "init"); -+ initfailed(card, "init", err); - } -- initfailed(card, "restore"); -+ initfailed(card, "restore", -ENOENT); - } - if (first) - finalerr = 0; /* no cards, no error code */ -@@ -1617,14 +1619,14 @@ int load_state(const char *file, const char *initfile, const char *cardname, - sprintf(cardname1, "%i", card); - err = init(initfile, cardname1); - if (err < 0) { -- initfailed(card, "init"); -+ initfailed(card, "init", err); - finalerr = err; - } - } - if ((err = set_controls(card, config, 1))) { - if (!force_restore) - finalerr = err; -- initfailed(card, "restore"); -+ initfailed(card, "restore", err); - } - } - } else { -@@ -1639,12 +1641,12 @@ int load_state(const char *file, const char *initfile, const char *cardname, - if (do_init && set_controls(cardno, config, 0)) { - err = init(initfile, cardname); - if (err < 0) { -- initfailed(cardno, "init"); -- return err; -+ initfailed(cardno, "init", err); -+ finalerr = err; - } - } - if ((err = set_controls(cardno, config, 1))) { -- initfailed(cardno, "restore"); -+ initfailed(cardno, "restore", err); - if (!force_restore) - return err; - } -diff --git a/alsactl/utils.c b/alsactl/utils.c -index ab4dbd4..a27eb6e 100644 ---- a/alsactl/utils.c -+++ b/alsactl/utils.c -@@ -79,19 +79,23 @@ size_t line_width(const char *buf, size_t bufsize, size_t pos) - return count - pos; - } - --void initfailed(int cardnumber, const char *reason) -+void initfailed(int cardnumber, const char *reason, int exitcode) - { - int fp; - char *str; -+ char sexitcode[16]; - - if (statefile == NULL) - return; - if (snd_card_get_name(cardnumber, &str) < 0) - return; -+ sprintf(sexitcode, "%i", exitcode); - fp = open(statefile, O_WRONLY|O_CREAT|O_APPEND, 0644); - write(fp, str, strlen(str)); - write(fp, ":", 1); - write(fp, reason, strlen(reason)); -+ write(fp, ":", 1); -+ write(fp, sexitcode, strlen(sexitcode)); - write(fp, "\n", 1); - close(fp); - free(str); -diff --git a/alsamixer/mixer_display.c b/alsamixer/mixer_display.c -index 9eadcc9..20d6d6a 100644 ---- a/alsamixer/mixer_display.c -+++ b/alsamixer/mixer_display.c -@@ -390,6 +390,15 @@ static void display_string_centered_in_control(int y, int col, const char *s, in - display_string_in_field(y, x, s, width, ALIGN_CENTER); - } - -+static long clamp(long value, long min, long max) -+{ -+ if (value < min) -+ return min; -+ if (value > max) -+ return max; -+ return value; -+} -+ - static void display_control(unsigned int control_index) - { - struct control *control; -@@ -462,6 +471,10 @@ static void display_control(unsigned int control_index) - err = snd_mixer_selem_get_capture_volume_range(control->elem, &min, &max); - if (err < 0) - return; -+ if (min >= max) -+ max = min + 1; -+ volumes[0] = clamp(volumes[0], min, max); -+ volumes[1] = clamp(volumes[1], min, max); - - if (control->flags & IS_ACTIVE) - wattrset(mixer_widget.window, 0); -diff --git a/amidi/amidi.c b/amidi/amidi.c -index 2e970ae..cedf18c 100644 ---- a/amidi/amidi.c -+++ b/amidi/amidi.c -@@ -95,122 +95,63 @@ static void *my_malloc(size_t size) - return p; - } - --static int is_input(snd_ctl_t *ctl, int card, int device, int sub) --{ -- snd_rawmidi_info_t *info; -- int err; -- -- snd_rawmidi_info_alloca(&info); -- snd_rawmidi_info_set_device(info, device); -- snd_rawmidi_info_set_subdevice(info, sub); -- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); -- -- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0 && err != -ENXIO) -- return err; -- else if (err == 0) -- return 1; -- -- return 0; --} -- --static int is_output(snd_ctl_t *ctl, int card, int device, int sub) --{ -- snd_rawmidi_info_t *info; -- int err; -- -- snd_rawmidi_info_alloca(&info); -- snd_rawmidi_info_set_device(info, device); -- snd_rawmidi_info_set_subdevice(info, sub); -- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); -- -- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0 && err != -ENXIO) -- return err; -- else if (err == 0) -- return 1; -- -- return 0; --} -- - static void list_device(snd_ctl_t *ctl, int card, int device) - { - snd_rawmidi_info_t *info; - const char *name; - const char *sub_name; - int subs, subs_in, subs_out; -- int sub, in, out; -+ int sub; - int err; - - snd_rawmidi_info_alloca(&info); - snd_rawmidi_info_set_device(info, device); - - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); -- snd_ctl_rawmidi_info(ctl, info); -- subs_in = snd_rawmidi_info_get_subdevices_count(info); -+ err = snd_ctl_rawmidi_info(ctl, info); -+ if (err >= 0) -+ subs_in = snd_rawmidi_info_get_subdevices_count(info); -+ else -+ subs_in = 0; -+ - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); -- snd_ctl_rawmidi_info(ctl, info); -- subs_out = snd_rawmidi_info_get_subdevices_count(info); -- subs = subs_in > subs_out ? subs_in : subs_out; -+ err = snd_ctl_rawmidi_info(ctl, info); -+ if (err >= 0) -+ subs_out = snd_rawmidi_info_get_subdevices_count(info); -+ else -+ subs_out = 0; - -- sub = 0; -- in = out = 0; -- if ((err = is_output(ctl, card, device, sub)) < 0) { -- error("cannot get rawmidi information %d:%d: %s", -- card, device, snd_strerror(err)); -+ subs = subs_in > subs_out ? subs_in : subs_out; -+ if (!subs) - return; -- } else if (err) -- out = 1; - -- if (err == 0) { -- if ((err = is_input(ctl, card, device, sub)) < 0) { -- error("cannot get rawmidi information %d:%d: %s", -- card, device, snd_strerror(err)); -+ for (sub = 0; sub < subs; ++sub) { -+ snd_rawmidi_info_set_stream(info, sub < subs_in ? -+ SND_RAWMIDI_STREAM_INPUT : -+ SND_RAWMIDI_STREAM_OUTPUT); -+ snd_rawmidi_info_set_subdevice(info, sub); -+ err = snd_ctl_rawmidi_info(ctl, info); -+ if (err < 0) { -+ error("cannot get rawmidi information %d:%d:%d: %s\n", -+ card, device, sub, snd_strerror(err)); - return; - } -- } else if (err) -- in = 1; -- -- if (err == 0) -- return; -- -- name = snd_rawmidi_info_get_name(info); -- sub_name = snd_rawmidi_info_get_subdevice_name(info); -- if (sub_name[0] == '\0') { -- if (subs == 1) { -- printf("%c%c hw:%d,%d %s\n", -- in ? 'I' : ' ', out ? 'O' : ' ', -+ name = snd_rawmidi_info_get_name(info); -+ sub_name = snd_rawmidi_info_get_subdevice_name(info); -+ if (sub == 0 && sub_name[0] == '\0') { -+ printf("%c%c hw:%d,%d %s", -+ sub < subs_in ? 'I' : ' ', -+ sub < subs_out ? 'O' : ' ', - card, device, name); -- } else -- printf("%c%c hw:%d,%d %s (%d subdevices)\n", -- in ? 'I' : ' ', out ? 'O' : ' ', -- card, device, name, subs); -- } else { -- sub = 0; -- for (;;) { -+ if (subs > 1) -+ printf(" (%d subdevices)", subs); -+ putchar('\n'); -+ break; -+ } else { - printf("%c%c hw:%d,%d,%d %s\n", -- in ? 'I' : ' ', out ? 'O' : ' ', -+ sub < subs_in ? 'I' : ' ', -+ sub < subs_out ? 'O' : ' ', - card, device, sub, sub_name); -- if (++sub >= subs) -- break; -- -- in = is_input(ctl, card, device, sub); -- out = is_output(ctl, card, device, sub); -- snd_rawmidi_info_set_subdevice(info, sub); -- if (out) { -- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); -- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0) { -- error("cannot get rawmidi information %d:%d:%d: %s", -- card, device, sub, snd_strerror(err)); -- break; -- } -- } else { -- snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); -- if ((err = snd_ctl_rawmidi_info(ctl, info)) < 0) { -- error("cannot get rawmidi information %d:%d:%d: %s", -- card, device, sub, snd_strerror(err)); -- break; -- } -- } -- sub_name = snd_rawmidi_info_get_subdevice_name(info); - } - } - } -diff --git a/amixer/amixer.c b/amixer/amixer.c -index 9620721..c9ea572 100644 ---- a/amixer/amixer.c -+++ b/amixer/amixer.c -@@ -534,6 +534,26 @@ static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_ - } - break; - #endif -+#ifdef SND_CTL_TLVT_DB_MINMAX -+ case SND_CTL_TLVT_DB_MINMAX: -+ case SND_CTL_TLVT_DB_MINMAX_MUTE: -+ if (type == SND_CTL_TLVT_DB_MINMAX_MUTE) -+ printf("dBminmaxmute-"); -+ else -+ printf("dBminmax-"); -+ if (size != 2 * sizeof(unsigned int)) { -+ while (size > 0) { -+ printf("0x%08x,", tlv[idx++]); -+ size -= sizeof(unsigned int); -+ } -+ } else { -+ printf("min="); -+ print_dB(tlv[2]); -+ printf(",max="); -+ print_dB(tlv[3]); -+ } -+ break; -+#endif - default: - printf("unk-%i-", type); - while (size > 0) { -@@ -602,6 +622,8 @@ static int show_control(const char *space, snd_hctl_elem_t *elem, - break; - } - if (level & LEVEL_BASIC) { -+ if (!snd_ctl_elem_info_is_readable(info)) -+ goto __skip_read; - if ((err = snd_hctl_elem_read(elem, control)) < 0) { - error("Control %s element read error: %s\n", card, snd_strerror(err)); - return err; -@@ -638,6 +660,7 @@ static int show_control(const char *space, snd_hctl_elem_t *elem, - } - } - printf("\n"); -+ __skip_read: - if (!snd_ctl_elem_info_is_tlv_readable(info)) - goto __skip_tlv; - tlv = malloc(4096); -diff --git a/aplay/aplay.1 b/aplay/aplay.1 -index 7759347..b6caf0b 100644 ---- a/aplay/aplay.1 -+++ b/aplay/aplay.1 -@@ -1,4 +1,4 @@ --.TH APLAY 1 "2 August 2001" -+.TH APLAY 1 "1 January 2010" - .SH NAME - arecord, aplay \- command-line sound recorder and player for ALSA - soundcard driver -@@ -46,6 +46,7 @@ If this parameter is omitted the WAVE format is used. - \fI\-c, \-\-channels=#\fP - The number of channels. - The default is one channel. -+Valid values are 1 through 32. - .TP - \fI\-f \-\-format=FORMAT\fP - Sample format -@@ -53,19 +54,23 @@ Sample format - Recognized sample formats are: S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE - S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE FLOAT_BE - FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE IEC958_SUBFRAME_BE MU_LAW --A_LAW IMA_ADPCM MPEG GSM -+A_LAW IMA_ADPCM MPEG GSM SPECIAL S24_3LE S24_3BE U24_3LE U24_3BE S20_3LE -+S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE U18_3LE - .br - Some of these may not be available on selected hardware - .br --There are also two format shortcuts available: -+The available format shortcuts are: - .nf --\-f cd (16 bit little endian, 44100, stereo [\-f S16_LE \-c2 \-r44100] -+\-f cd (16 bit little endian, 44100, stereo) [\-f S16_LE \-c2 \-r44100] -+\-f cdr (16 bit big endian, 44100, stereo) [\-f S16_BE \-c2 \-f44100] - \-f dat (16 bit little endian, 48000, stereo) [\-f S16_LE \-c2 \-r48000] - .fi - If no format is given U8 is used. - .TP - \fI\-r, \-\-rate=#\fP - Sampling rate in Hertz. The default rate is 8000 Hertz. -+If the value specified is less than 300, it is taken as the rate in kilohertz. -+Valid values are 2000 through 192000 Hertz. - .TP - \fI\-d, \-\-duration=#\fP - Interrupt after # seconds. -@@ -120,10 +125,69 @@ The stereo VU-meter is available only for 2-channel stereo samples - with interleaved format. - .TP - \fI\-I, \-\-separate\-channels\fP --One file for each channel -+One file for each channel. This option disables max\-file\-time -+and use\-strftime, and ignores SIGUSR1. The stereo VU meter is -+not available with separate channels. -+.TP -+\fI\-P\fP -+Playback. This is the default if the program is invoked -+by typing aplay. -+.TP -+\fI\-C\fP -+Record. This is the default if the program is invoked -+by typing arecord. -+.TP -+\fI\-\-disable\-resample\fP -+Disable automatic rate resample. -+.TP -+\fI\-\-disable\-channels\fP -+Disable automatic channel conversions. -+.TP -+\fI\-\-disable\-format\fP -+Disable automatic format conversions. -+.TP -+\fI\-\-disable\-softvol\fP -+Disable software volume control (softvol). -+.TP -+\fI\-\-test\-position\fP -+Test ring buffer position. -+.TP -+\fI\-\-test\-coef=\fP -+Test coefficient for ring buffer position; default is 8. -+Expression for validation is: coef * (buffer_size / 2). -+Minimum value is 1. -+.TP -+\fI\-\-test\-nowait\fP -+Do not wait for the ring buffer--eats the whole CPU. -+.TP -+\fI\-\-max\-file\-time\fP -+While recording, when the output file has been accumulating -+sound for this long, -+close it and open a new output file. Default is the maximum -+size supported by the file format: 2 GiB for WAV files. -+This option has no effect if \-\-separate\-channels is -+specified. -+.TP -+\fI\-\-process\-id\-file \fP -+aplay writes its process ID here, so other programs can -+send signals to it. -+.TP -+\fI\-\-use\-strftime\fP -+When recording, interpret %-codes in the file name parameter using -+the strftime facility whenever the output file is opened. The -+important strftime codes are: %Y is the year, %m month, %d day of -+the month, %H hour, %M minute and %S second. In addition, %v is -+the file number, starting at 1. When this option is specified, -+intermediate directories for the output file are created automatically. -+This option has no effect if \-\-separate\-channels is specified. - --.SS --Example: -+.SH SIGNALS -+When recording, SIGINT, SIGTERM and SIGABRT will close the output -+file and exit. SIGUSR1 will close the output file, open a new one, -+and continue recording. However, SIGUSR1 does not work with -+\-\-separate\-channels. -+ -+.SH EXAMPLES - - .TP - \fBaplay \-c 1 \-t raw \-r 22050 \-f mu_law foobar\fR -@@ -144,6 +208,19 @@ pcm.copy { - } - .fi - -+.TP -+\fBarecord \-t wav \-max-file_time 30 mon.wav\fP -+Record from the default audio source in monaural, 8,000 samples -+per second, 8 bits per sample. Start a new file every -+30 seconds. File names are mon-nn.wav, where nn increases -+from 01. The file after mon-99.wav is mon-100.wav. -+ -+.TP -+\fBarecord \-f cd \-t wav \-max-file-time 3600 --use-strftime %Y/%m/%d/listen-%H-%M-%v.wav\fP -+Record in stereo from the default audio source. Create a new file -+every hour. The files are placed in directories based on their start dates -+and have names which include their start times and file numbers. -+ - .SH SEE ALSO - \fB - alsamixer(1), -diff --git a/aplay/aplay.c b/aplay/aplay.c -index 22a5fe0..e1d8e6a 100644 ---- a/aplay/aplay.c -+++ b/aplay/aplay.c -@@ -111,11 +111,19 @@ static int test_position = 0; - static int test_coef = 8; - static int test_nowait = 0; - static snd_output_t *log; -+static long long max_file_size = 0; -+static int max_file_time = 0; -+static int use_strftime = 0; -+volatile static int recycle_capture_file = 0; - - static int fd = -1; - static off64_t pbrec_count = LLONG_MAX, fdcount; - static int vocmajor, vocminor; - -+static char *pidfile_name = NULL; -+FILE *pidf = NULL; -+static int pidfile_written = 0; -+ - /* needed prototypes */ - - static void playback(char *filename); -@@ -194,7 +202,11 @@ _("Usage: %s [OPTION]... [FILE]...\n" - " --test-position test ring buffer position\n" - " --test-coef=# test coeficient for ring buffer position (default 8)\n" - " expression for validation is: coef * (buffer_size / 2)\n" --" --test-nowait do not wait for ring buffer - eats whole CPU\n") -+" --test-nowait do not wait for ring buffer - eats whole CPU\n" -+" --max-file-time=# start another output file when the old file has recorded\n" -+" for this many seconds\n" -+" --process-id-file write the process ID here\n" -+" --use-strftime apply the strftime facility to the output file name\n") - , command); - printf(_("Recognized sample formats are:")); - for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) { -@@ -324,6 +336,18 @@ static void version(void) - printf("%s: version " SND_UTIL_VERSION_STR " by Jaroslav Kysela \n", command); - } - -+/* -+ * Subroutine to clean up before exit. -+ */ -+static void prg_exit(int code) -+{ -+ if (handle) -+ snd_pcm_close(handle); -+ if (pidfile_written) -+ remove (pidfile_name); -+ exit(code); -+} -+ - static void signal_handler(int sig) - { - if (verbose==2) -@@ -345,7 +369,14 @@ static void signal_handler(int sig) - snd_pcm_close(handle); - handle = NULL; - } -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); -+} -+ -+/* call on SIGUSR1 signal. */ -+static void signal_handler_recycle (int sig) -+{ -+ /* flag the capture loop to start a new output file */ -+ recycle_capture_file = 1; - } - - enum { -@@ -358,7 +389,10 @@ enum { - OPT_DISABLE_SOFTVOL, - OPT_TEST_POSITION, - OPT_TEST_COEF, -- OPT_TEST_NOWAIT -+ OPT_TEST_NOWAIT, -+ OPT_MAX_FILE_TIME, -+ OPT_PROCESS_ID_FILE, -+ OPT_USE_STRFTIME - }; - - int main(int argc, char *argv[]) -@@ -399,6 +433,9 @@ int main(int argc, char *argv[]) - {"test-position", 0, 0, OPT_TEST_POSITION}, - {"test-coef", 1, 0, OPT_TEST_COEF}, - {"test-nowait", 0, 0, OPT_TEST_NOWAIT}, -+ {"max-file-time", 1, 0, OPT_MAX_FILE_TIME}, -+ {"process-id-file", 1, 0, OPT_PROCESS_ID_FILE}, -+ {"use-strftime", 0, 0, OPT_USE_STRFTIME}, - {0, 0, 0, 0} - }; - char *pcm_name = "default"; -@@ -493,7 +530,7 @@ int main(int argc, char *argv[]) - rhwparams.format = snd_pcm_format_value(optarg); - if (rhwparams.format == SND_PCM_FORMAT_UNKNOWN) { - error(_("wrong extended format '%s'"), optarg); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - break; -@@ -588,6 +625,15 @@ int main(int argc, char *argv[]) - case OPT_TEST_NOWAIT: - test_nowait = 1; - break; -+ case OPT_MAX_FILE_TIME: -+ max_file_time = strtol(optarg, NULL, 0); -+ break; -+ case OPT_PROCESS_ID_FILE: -+ pidfile_name = optarg; -+ break; -+ case OPT_USE_STRFTIME: -+ use_strftime = 1; -+ break; - default: - fprintf(stderr, _("Try `%s --help' for more information.\n"), command); - return 1; -@@ -643,10 +689,24 @@ int main(int argc, char *argv[]) - readn_func = snd_pcm_readn; - } - -+ if (pidfile_name) { -+ errno = 0; -+ pidf = fopen (pidfile_name, "w"); -+ if (pidf) { -+ (void)fprintf (pidf, "%d\n", getpid()); -+ fclose(pidf); -+ pidfile_written = 1; -+ } else { -+ error(_("Cannot create process ID file %s: %s"), -+ pidfile_name, strerror (errno)); -+ return 1; -+ } -+ } - - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGABRT, signal_handler); -+ signal(SIGUSR1, signal_handler_recycle); - if (interleaved) { - if (optind > argc - 1) { - if (stream == SND_PCM_STREAM_PLAYBACK) -@@ -670,10 +730,13 @@ int main(int argc, char *argv[]) - if (verbose==2) - putchar('\n'); - snd_pcm_close(handle); -+ handle = NULL; - free(audiobuf); - __end: - snd_output_close(log); - snd_config_update_free_global(); -+ prg_exit(EXIT_SUCCESS); -+ /* avoid warning */ - return EXIT_SUCCESS; - } - -@@ -725,7 +788,7 @@ static size_t test_wavefile_read(int fd, u_char *buffer, size_t *size, size_t re - return *size; - if ((size_t)safe_read(fd, buffer + *size, reqsize - *size) != reqsize - *size) { - error(_("read error (called from line %i)"), line); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - return *size = reqsize; - } -@@ -735,7 +798,7 @@ static size_t test_wavefile_read(int fd, u_char *buffer, size_t *size, size_t re - blimit = len; \ - if ((buffer = realloc(buffer, blimit)) == NULL) { \ - error(_("not enough memory")); \ -- exit(EXIT_FAILURE); \ -+ prg_exit(EXIT_FAILURE); \ - } \ - } - -@@ -784,7 +847,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) - if (len < sizeof(WaveFmtBody)) { - error(_("unknown length of 'fmt ' chunk (read %u, should be %u at least)"), - len, (u_int)sizeof(WaveFmtBody)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - check_wavefile_space(buffer, len, blimit); - test_wavefile_read(fd, buffer, &size, len, __LINE__); -@@ -794,22 +857,22 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) - if (len < sizeof(WaveFmtExtensibleBody)) { - error(_("unknown length of extensible 'fmt ' chunk (read %u, should be %u at least)"), - len, (u_int)sizeof(WaveFmtExtensibleBody)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (memcmp(fe->guid_tag, WAV_GUID_TAG, 14) != 0) { - error(_("wrong format tag in extensible 'fmt ' chunk")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - f->format = fe->guid_format; - } - if (LE_SHORT(f->format) != WAV_FMT_PCM && - LE_SHORT(f->format) != WAV_FMT_IEEE_FLOAT) { - error(_("can't play WAVE-file format 0x%04x which is not PCM or FLOAT encoded"), LE_SHORT(f->format)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (LE_SHORT(f->channels) < 1) { - error(_("can't play WAVE-files with %d tracks"), LE_SHORT(f->channels)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - hwparams.channels = LE_SHORT(f->channels); - switch (LE_SHORT(f->bit_p_spl)) { -@@ -842,7 +905,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) - default: - error(_(" can't play WAVE-files with sample %d bits in %d bytes wide (%d channels)"), - LE_SHORT(f->bit_p_spl), LE_SHORT(f->byte_p_spl), hwparams.channels); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - break; - case 32: -@@ -854,7 +917,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) - default: - error(_(" can't play WAVE-files with sample %d bits wide"), - LE_SHORT(f->bit_p_spl)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - hwparams.rate = LE_INT(f->sample_fq); - -@@ -936,7 +999,7 @@ static int test_au(int fd, void *buffer) - return -1; - if ((size_t)safe_read(fd, buffer + sizeof(AuHeader), BE_INT(ap->hdr_size) - sizeof(AuHeader)) != BE_INT(ap->hdr_size) - sizeof(AuHeader)) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - return 0; - } -@@ -966,7 +1029,7 @@ static void set_params(void) - err = snd_pcm_hw_params_any(handle, params); - if (err < 0) { - error(_("Broken configuration for this PCM: no configurations available")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (mmap_flag) { - snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); -@@ -983,18 +1046,18 @@ static void set_params(void) - SND_PCM_ACCESS_RW_NONINTERLEAVED); - if (err < 0) { - error(_("Access type not available")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - err = snd_pcm_hw_params_set_format(handle, params, hwparams.format); - if (err < 0) { - error(_("Sample format non available")); - show_available_sample_formats(params); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - err = snd_pcm_hw_params_set_channels(handle, params, hwparams.channels); - if (err < 0) { - error(_("Channels count non available")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - #if 0 -@@ -1052,14 +1115,14 @@ static void set_params(void) - if (err < 0) { - error(_("Unable to install hw params:")); - snd_pcm_hw_params_dump(params, log); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - snd_pcm_hw_params_get_period_size(params, &chunk_size, 0); - snd_pcm_hw_params_get_buffer_size(params, &buffer_size); - if (chunk_size == buffer_size) { - error(_("Can't use period equal to buffer size (%lu == %lu)"), - chunk_size, buffer_size); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - snd_pcm_sw_params_current(handle, swparams); - if (avail_min < 0) -@@ -1090,7 +1153,7 @@ static void set_params(void) - if (snd_pcm_sw_params(handle, swparams) < 0) { - error(_("unable to install sw params:")); - snd_pcm_sw_params_dump(swparams, log); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - if (verbose) -@@ -1102,7 +1165,7 @@ static void set_params(void) - audiobuf = realloc(audiobuf, chunk_bytes); - if (audiobuf == NULL) { - error(_("not enough memory")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - // fprintf(stderr, "real chunk_size = %i, frags = %i, total = %i\n", chunk_size, setup.buf.block.frags, setup.buf.block.frags * chunk_size); - -@@ -1120,7 +1183,7 @@ static void set_params(void) - err = snd_pcm_mmap_begin(handle, &areas, &offset, &size); - if (err < 0) { - error("snd_pcm_mmap_begin problem: %s", snd_strerror(err)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - for (i = 0; i < hwparams.channels; i++) - fprintf(stderr, "mmap_area[%i] = %p,%u,%u (%u)\n", i, areas[i].addr, areas[i].first, areas[i].step, snd_pcm_format_physical_width(hwparams.format)); -@@ -1164,7 +1227,7 @@ static void xrun(void) - snd_pcm_status_alloca(&status); - if ((res = snd_pcm_status(handle, status))<0) { - error(_("status error: %s"), snd_strerror(res)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) { - if (monotonic) { -@@ -1194,7 +1257,7 @@ static void xrun(void) - } - if ((res = snd_pcm_prepare(handle))<0) { - error(_("xrun: prepare error: %s"), snd_strerror(res)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - return; /* ok, data should be accepted again */ - } if (snd_pcm_status_get_state(status) == SND_PCM_STATE_DRAINING) { -@@ -1206,7 +1269,7 @@ static void xrun(void) - fprintf(stderr, _("capture stream format change? attempting recover...\n")); - if ((res = snd_pcm_prepare(handle))<0) { - error(_("xrun(DRAINING): prepare error: %s"), snd_strerror(res)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - return; - } -@@ -1216,7 +1279,7 @@ static void xrun(void) - snd_pcm_status_dump(status, log); - } - error(_("read/write error, state = %s"), snd_pcm_state_name(snd_pcm_status_get_state(status))); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - /* I/O suspend handler */ -@@ -1233,7 +1296,7 @@ static void suspend(void) - fprintf(stderr, _("Failed. Restarting stream. ")); fflush(stderr); - if ((res = snd_pcm_prepare(handle)) < 0) { - error(_("suspend: prepare error: %s"), snd_strerror(res)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - if (!quiet_mode) -@@ -1538,7 +1601,7 @@ static ssize_t pcm_write(u_char *data, size_t count) - suspend(); - } else if (r < 0) { - error(_("write error: %s"), snd_strerror(r)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (r > 0) { - if (vumeter) -@@ -1584,7 +1647,7 @@ static ssize_t pcm_writev(u_char **data, unsigned int channels, size_t count) - suspend(); - } else if (r < 0) { - error(_("writev error: %s"), snd_strerror(r)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (r > 0) { - if (vumeter) { -@@ -1627,7 +1690,7 @@ static ssize_t pcm_read(u_char *data, size_t rcount) - suspend(); - } else if (r < 0) { - error(_("read error: %s"), snd_strerror(r)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (r > 0) { - if (vumeter) -@@ -1670,7 +1733,7 @@ static ssize_t pcm_readv(u_char **data, unsigned int channels, size_t rcount) - suspend(); - } else if (r < 0) { - error(_("readv error: %s"), snd_strerror(r)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (r > 0) { - if (vumeter) { -@@ -1727,7 +1790,7 @@ static void voc_write_silence(unsigned x) - l = chunk_size; - if (voc_pcm_write(buf, l) != (ssize_t)l) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - x -= l; - } -@@ -1769,7 +1832,7 @@ static void voc_play(int fd, int ofs, char *name) - buffer_pos = 0; - if (data == NULL) { - error(_("malloc error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (!quiet_mode) { - fprintf(stderr, _("Playing Creative Labs Channel file '%s'...\n"), name); -@@ -1778,14 +1841,14 @@ static void voc_play(int fd, int ofs, char *name) - while (ofs > (ssize_t)chunk_bytes) { - if ((size_t)safe_read(fd, buf, chunk_bytes) != chunk_bytes) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - ofs -= chunk_bytes; - } - if (ofs) { - if (safe_read(fd, buf, ofs) != ofs) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - hwparams.format = DEFAULT_FORMAT; -@@ -1809,7 +1872,7 @@ static void voc_play(int fd, int ofs, char *name) - nextblock = buf[0] = 0; - if (l == -1) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - } -@@ -1953,12 +2016,12 @@ static void voc_play(int fd, int ofs, char *name) - if (output && !quiet_mode) { - if (write(2, data, l) != l) { /* to stderr */ - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } else { - if (voc_pcm_write(data, l) != l) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - COUNT(l); -@@ -2005,7 +2068,7 @@ static void begin_voc(int fd, size_t cnt) - - if (write(fd, &vh, sizeof(VocHeader)) != sizeof(VocHeader)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (hwparams.channels > 1) { - /* write an extended block */ -@@ -2014,14 +2077,14 @@ static void begin_voc(int fd, size_t cnt) - bt.datalen_m = bt.datalen_h = 0; - if (write(fd, &bt, sizeof(VocBlockType)) != sizeof(VocBlockType)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - eb.tc = LE_SHORT(65536 - 256000000L / (hwparams.rate << 1)); - eb.pack = 0; - eb.mode = 1; - if (write(fd, &eb, sizeof(VocExtBlock)) != sizeof(VocExtBlock)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - bt.type = 1; -@@ -2031,13 +2094,13 @@ static void begin_voc(int fd, size_t cnt) - bt.datalen_h = (u_char) ((cnt & 0xFF0000) >> 16); - if (write(fd, &bt, sizeof(VocBlockType)) != sizeof(VocBlockType)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - vd.tc = (u_char) (256 - (1000000 / hwparams.rate)); - vd.pack = 0; - if (write(fd, &vd, sizeof(VocVoiceData)) != sizeof(VocVoiceData)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - -@@ -2073,7 +2136,7 @@ static void begin_wave(int fd, size_t cnt) - break; - default: - error(_("Wave doesn't support %s format..."), snd_pcm_format_name(hwparams.format)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - h.magic = WAV_RIFF; - tmp = cnt + sizeof(WaveHeader) + sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + sizeof(WaveChunkHeader) - 8; -@@ -2109,7 +2172,7 @@ static void begin_wave(int fd, size_t cnt) - write(fd, &f, sizeof(WaveFmtBody)) != sizeof(WaveFmtBody) || - write(fd, &cd, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - -@@ -2133,13 +2196,13 @@ static void begin_au(int fd, size_t cnt) - break; - default: - error(_("Sparc Audio doesn't support %s format..."), snd_pcm_format_name(hwparams.format)); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - ah.sample_rate = BE_INT(hwparams.rate); - ah.channels = BE_INT(hwparams.channels); - if (write(fd, &ah, sizeof(AuHeader)) != sizeof(AuHeader)) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - -@@ -2153,7 +2216,7 @@ static void end_voc(int fd) - - if (write(fd, &dummy, 1) != 1) { - error(_("write error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - length_seek = sizeof(VocHeader); - if (hwparams.channels > 1) -@@ -2261,7 +2324,7 @@ static void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *n - r = safe_read(fd, audiobuf + l, c); - if (r < 0) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - fdcount += r; - if (r == 0) -@@ -2300,14 +2363,14 @@ static void playback(char *name) - } else { - if ((fd = open64(name, O_RDONLY, 0)) == -1) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - /* read the file header */ - dta = sizeof(AuHeader); - if ((size_t)safe_read(fd, audiobuf, dta) != dta) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - if (test_au(fd, audiobuf) >= 0) { - rhwparams.format = hwparams.format; -@@ -2319,7 +2382,7 @@ static void playback(char *name) - if ((size_t)safe_read(fd, audiobuf + sizeof(AuHeader), - dta - sizeof(AuHeader)) != dta - sizeof(AuHeader)) { - error(_("read error")); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE);; - } - if ((ofs = test_vocfile(audiobuf)) >= 0) { - pbrec_count = calc_count(); -@@ -2341,13 +2404,98 @@ static void playback(char *name) - close(fd); - } - -+/** -+ * mystrftime -+ * -+ * Variant of strftime(3) that supports additional format -+ * specifiers in the format string. -+ * -+ * Parameters: -+ * -+ * s - destination string -+ * max - max number of bytes to write -+ * userformat - format string -+ * tm - time information -+ * filenumber - the number of the file, starting at 1 -+ * -+ * Returns: number of bytes written to the string s -+ */ -+size_t mystrftime(char *s, size_t max, const char *userformat, -+ const struct tm *tm, const int filenumber) -+{ -+ char formatstring[PATH_MAX] = ""; -+ char tempstring[PATH_MAX] = ""; -+ char *format, *tempstr; -+ const char *pos_userformat; -+ -+ format = formatstring; -+ -+ /* if mystrftime is called with userformat = NULL we return a zero length string */ -+ if (userformat == NULL) { -+ *s = '\0'; -+ return 0; -+ } -+ -+ for (pos_userformat = userformat; *pos_userformat; ++pos_userformat) { -+ if (*pos_userformat == '%') { -+ tempstr = tempstring; -+ tempstr[0] = '\0'; -+ switch (*++pos_userformat) { -+ -+ case '\0': // end of string -+ --pos_userformat; -+ break; -+ -+ case 'v': // file number -+ sprintf(tempstr, "%02d", filenumber); -+ break; -+ -+ default: // All other codes will be handled by strftime -+ *format++ = '%'; -+ *format++ = *pos_userformat; -+ continue; -+ } -+ -+ /* If a format specifier was found and used, copy the result. */ -+ if (tempstr[0]) { -+ while ((*format = *tempstr++) != '\0') -+ ++format; -+ continue; -+ } -+ } -+ -+ /* For any other character than % we simply copy the character */ -+ *format++ = *pos_userformat; -+ } -+ -+ *format = '\0'; -+ format = formatstring; -+ return strftime(s, max, format, tm); -+} -+ - static int new_capture_file(char *name, char *namebuf, size_t namelen, - int filecount) - { -- /* get a copy of the original filename */ - char *s; - char buf[PATH_MAX+1]; -+ time_t t; -+ struct tm *tmp; -+ -+ if (use_strftime) { -+ t = time(NULL); -+ tmp = localtime(&t); -+ if (tmp == NULL) { -+ perror("localtime"); -+ prg_exit(EXIT_FAILURE); -+ } -+ if (mystrftime(namebuf, namelen, name, tmp, filecount+1) == 0) { -+ fprintf(stderr, "mystrftime returned 0"); -+ prg_exit(EXIT_FAILURE); -+ } -+ return filecount; -+ } - -+ /* get a copy of the original filename */ - strncpy(buf, name, sizeof(buf)); - - /* separate extension from filename */ -@@ -2379,6 +2527,58 @@ static int new_capture_file(char *name, char *namebuf, size_t namelen, - return filecount; - } - -+/** -+ * create_path -+ * -+ * This function creates a file path, like mkdir -p. -+ * -+ * Parameters: -+ * -+ * path - the path to create -+ * -+ * Returns: 0 on success, -1 on failure -+ * On failure, a message has been printed to stderr. -+ */ -+int create_path(const char *path) -+{ -+ char *start; -+ mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; -+ -+ if (path[0] == '/') -+ start = strchr(path + 1, '/'); -+ else -+ start = strchr(path, '/'); -+ -+ while (start) { -+ char *buffer = strdup(path); -+ buffer[start-path] = 0x00; -+ -+ if (mkdir(buffer, mode) == -1 && errno != EEXIST) { -+ fprintf(stderr, "Problem creating directory %s", buffer); -+ perror(" "); -+ free(buffer); -+ return -1; -+ } -+ free(buffer); -+ start = strchr(start + 1, '/'); -+ } -+ return 0; -+} -+ -+static int safe_open(const char *name) -+{ -+ int fd; -+ -+ fd = open64(name, O_WRONLY | O_CREAT, 0644); -+ if (fd == -1) { -+ if (errno != ENOENT || !use_strftime) -+ return -1; -+ if (create_path(name) == 0) -+ fd = open64(name, O_WRONLY | O_CREAT, 0644); -+ } -+ return fd; -+} -+ - static void capture(char *orig_name) - { - int tostdout=0; /* boolean which describes output stream */ -@@ -2391,6 +2591,10 @@ static void capture(char *orig_name) - count = calc_count(); - if (count == 0) - count = LLONG_MAX; -+ /* compute the number of bytes per file */ -+ max_file_size = max_file_time * -+ snd_pcm_format_size(hwparams.format, -+ hwparams.rate * hwparams.channels); - /* WAVE-file should be even (I'm not sure), but wasting one byte - isn't a problem (this can only be in 8 bit mono) */ - if (count < LLONG_MAX) -@@ -2417,7 +2621,7 @@ static void capture(char *orig_name) - /* open a file to write */ - if(!tostdout) { - /* upon the second file we start the numbering scheme */ -- if (filecount) { -+ if (filecount || use_strftime) { - filecount = new_capture_file(orig_name, namebuf, - sizeof(namebuf), - filecount); -@@ -2426,9 +2630,10 @@ static void capture(char *orig_name) - - /* open a new file */ - remove(name); -- if ((fd = open64(name, O_WRONLY | O_CREAT, 0644)) == -1) { -+ fd = safe_open(name); -+ if (fd < 0) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - filecount++; - } -@@ -2436,6 +2641,8 @@ static void capture(char *orig_name) - rest = count; - if (rest > fmt_rec_table[file_type].max_filesize) - rest = fmt_rec_table[file_type].max_filesize; -+ if (max_file_size && (rest > max_file_size)) -+ rest = max_file_size; - - /* setup sample header */ - if (fmt_rec_table[file_type].start) -@@ -2443,7 +2650,7 @@ static void capture(char *orig_name) - - /* capture */ - fdcount = 0; -- while (rest > 0) { -+ while (rest > 0 && recycle_capture_file == 0) { - size_t c = (rest <= (off64_t)chunk_bytes) ? - (size_t)rest : chunk_bytes; - size_t f = c * 8 / bits_per_frame; -@@ -2451,13 +2658,19 @@ static void capture(char *orig_name) - break; - if (write(fd, audiobuf, c) != c) { - perror(name); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - count -= c; - rest -= c; - fdcount += c; - } - -+ /* re-enable SIGUSR1 signal */ -+ if (recycle_capture_file) { -+ recycle_capture_file = 0; -+ signal(SIGUSR1, signal_handler_recycle); -+ } -+ - /* finish sample container */ - if (fmt_rec_table[file_type].end && !tostdout) { - fmt_rec_table[file_type].end(fd); -@@ -2498,12 +2711,12 @@ static void playbackv_go(int* fds, unsigned int channels, size_t loaded, off64_t - r = safe_read(fds[0], bufs[0], expected); - if (r < 0) { - perror(names[channel]); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - for (channel = 1; channel < channels; ++channel) { - if (safe_read(fds[channel], bufs[channel], r) != r) { - perror(names[channel]); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - if (r == 0) -@@ -2550,7 +2763,7 @@ static void capturev_go(int* fds, unsigned int channels, off64_t count, int rtyp - for (channel = 0; channel < channels; ++channel) { - if ((size_t)write(fds[channel], bufs[channel], rv) != rv) { - perror(names[channel]); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - } - r = r * bits_per_frame / 8; -@@ -2583,7 +2796,7 @@ static void playbackv(char **names, unsigned int count) - alloced = 1; - } else if (count != channels) { - error(_("You need to specify %d files"), channels); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - for (channel = 0; channel < channels; ++channel) { -@@ -2609,7 +2822,7 @@ static void playbackv(char **names, unsigned int count) - if (alloced) - free(names); - if (ret) -- exit(ret); -+ prg_exit(ret); - } - - static void capturev(char **names, unsigned int count) -@@ -2636,7 +2849,7 @@ static void capturev(char **names, unsigned int count) - alloced = 1; - } else if (count != channels) { - error(_("You need to specify %d files"), channels); -- exit(EXIT_FAILURE); -+ prg_exit(EXIT_FAILURE); - } - - for (channel = 0; channel < channels; ++channel) { -@@ -2662,5 +2875,5 @@ static void capturev(char **names, unsigned int count) - if (alloced) - free(names); - if (ret) -- exit(ret); -+ prg_exit(ret); - } -diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c -index 053ed3b..d8d68e2 100644 ---- a/speaker-test/speaker-test.c -+++ b/speaker-test/speaker-test.c -@@ -689,6 +689,7 @@ static int write_loop(snd_pcm_t *handle, int channel, int periods, uint8_t *fram - double phase = 0; - int err, n; - -+ fflush(stdout); - if (test_type == TEST_WAV) { - int bufsize = snd_pcm_frames_to_bytes(handle, period_size); - n = 0; diff --git a/alsa-utils.changes b/alsa-utils.changes index 40c062c..127ef76 100644 --- a/alsa-utils.changes +++ b/alsa-utils.changes @@ -1,22 +1,3 @@ -------------------------------------------------------------------- -Mon Mar 8 14:35:52 CET 2010 - tiwai@suse.de - -- Backport upstream fixes: - * aplay: Dump PCM state on xrun when verbose mode is active - * aplay - add option --process-id-file - * aplay -- add features for audio surveilance - * aplay -- update the man file - * amidi: fix port listing - * speaker-test: add fflush(stdout) to write_loop - * amixer: fix display of unreadable control elements - * amixer: add support for TLV dB minmax types - * alsactl: Fix return code - * alsamixer: fix division by zero - * alsamixer: handle out-of-range volume values - * alsactl: improve -d to get warnings and store exitcode to runstate file - * alsactl: add more debug prints to state.c - * alsactl: update debug prints in state.c - ------------------------------------------------------------------- Fri Dec 18 17:37:24 CET 2009 - tiwai@suse.de diff --git a/alsa-utils.spec b/alsa-utils.spec index 9d2ccdd..9b9b307 100644 --- a/alsa-utils.spec +++ b/alsa-utils.spec @@ -30,7 +30,7 @@ Summary: Advanced Linux Sound Architecture Utilities Version: 1.0.21 Release: 3 Source: ftp://ftp.alsa-project.org/pub/util/alsa-utils-%{package_version}.tar.bz2 -Patch: alsa-utils-git-fixes.diff +# Patch: alsa-utils-git-fixes.diff Patch1: alsa-utils-gettext-version-removal.diff # Patch2: alsa-utils-po-pre-patch.diff Url: http://www.alsa-project.org/ @@ -54,7 +54,7 @@ sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am # fix po changes in tarball first # %patch2 -p1 # rm -f po/Makefile* po/*.gmo po/*.pot po/*.header po/stamp-* -%patch -p1 +# %patch -p1 %if %suse_version < 1020 %patch1 -p1 %endif