From: Andre Noll Date: Fri, 8 Apr 2011 09:12:46 +0000 (+0200) Subject: Merge branch 't/gvf' X-Git-Tag: v0.4.7~20 X-Git-Url: http://git.tuebingen.mpg.de/?a=commitdiff_plain;h=65a0002eb560b7248cbb0b4f143d00053b66bccc;hp=be9f7c9b442f7b723427a79f85774d5fa7718425;p=paraslash.git Merge branch 't/gvf' --- diff --git a/Makefile.in b/Makefile.in index 06c86eb6..8b33aaac 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,17 +9,21 @@ PACKAGE_VERSION := @PACKAGE_VERSION@ PACKAGE_STRING := @PACKAGE_STRING@ install_sh := @install_sh@ cmdline_dir := @cmdline_dir@ +executables := @executables@ build_date := $(shell date) uname_s := $(shell uname -s 2>/dev/null || echo "UNKNOWN_OS") uname_rs := $(shell uname -rs) cc_version := $(shell $(CC) --version | head -n 1) -codename := deterministic entropy +codename := infinite rollback GIT_VERSION := $(shell ./GIT-VERSION-GEN git-version.h) DEBUG_CPPFLAGS += -Wno-sign-compare -g -Wunused -Wundef -W DEBUG_CPPFLAGS += -Wredundant-decls +DEBUG_CPPFLAGS += -Wall +DEBUG_CPPFLAGS += -Wformat-security +DEBUG_CPPFLAGS += -Wmissing-format-attribute # produces false positives # DEBUG_CPPFLAGS += -Wunreachable-code # DEBUG_CPPFLAGS += -Wwrite-strings @@ -39,24 +43,20 @@ ifeq ($(uname_s),Linux) CPPFLAGS += -Wshadow endif CPPFLAGS += -Os -CPPFLAGS += -Wall CPPFLAGS += -Wuninitialized CPPFLAGS += -Wchar-subscripts -CPPFLAGS += -Wformat-security CPPFLAGS += -DBINDIR='"$(BINDIR)"' CPPFLAGS += -DBUILD_DATE='"$(build_date)"' CPPFLAGS += -DUNAME_RS='"$(uname_rs)"' CPPFLAGS += -DCODENAME='"$(codename)"' CPPFLAGS += -DCC_VERSION='"$(cc_version)"' CPPFLAGS += -Werror-implicit-function-declaration -CPPFLAGS += -Wmissing-format-attribute CPPFLAGS += -Wmissing-noreturn CPPFLAGS += -Wunused-macros CPPFLAGS += -Wbad-function-cast CPPFLAGS += -fno-strict-aliasing CPPFLAGS += -DMAIN_INPUT_FILE_IS_$(*F) CPPFLAGS += @SSL_CPPFLAGS@ -CPPFLAGS += @ncurses_cppflags@ CPPFLAGS += @arch_cppflags@ CPPFLAGS += -I/usr/local/include CPPFLAGS += -I$(cmdline_dir) @@ -68,6 +68,7 @@ man_pages_in := $(patsubst %, web/%.man.in.html, @executables@) ggo_dir := ggo object_dir := objects man_dir := man/man1 +test_dir := t m4_ggos := afh audioc audiod client filter gui recv server write all_ggos := $(m4_ggos) dccp_recv alsa_write oss_write fade http_recv \ @@ -94,10 +95,10 @@ endif ifndef BUILD_VERBOSE BUILD_VERBOSE = 0 endif -ifeq ($(BUILD_VERBOSE),1) - Q = -else +ifeq ($(BUILD_VERBOSE),0) Q = @ +else + Q = endif .PHONY: dep all clean distclean maintainer-clean install man tarball @@ -189,6 +190,10 @@ $(object_dir)/aac_afh.o: aac_afh.c | $(object_dir) @[ -z "$(Q)" ] || echo 'CC $<' $(Q) $(CC) -c -o $@ $(CPPFLAGS) $(DEBUG_CPPFLAGS) @faad_cppflags@ $< +$(object_dir)/gui%.o: gui%.c | $(object_dir) + @[ -z "$(Q)" ] || echo 'CC $<' + $(Q) $(CC) -c -o $@ $(CPPFLAGS) $(DEBUG_CPPFLAGS) @curses_cppflags@ $< + $(object_dir)/%.cmdline.o: $(cmdline_dir)/%.cmdline.c $(cmdline_dir)/%.cmdline.h | $(object_dir) @[ -z "$(Q)" ] || echo 'CC $<' $(Q) $(CC) -c $(CPPFLAGS) -Wno-unused-function -o $@ $< @@ -205,6 +210,7 @@ $(object_dir)/%.d: %.c | $(object_dir) @[ -z "$(Q)" ] || echo 'DEP $<' $(Q) ./depend.sh $(object_dir) $(cmdline_dir) $(CPPFLAGS) $< > $@ + recv_objs := $(addprefix $(object_dir)/, @recv_objs@) filter_objs := $(addprefix $(object_dir)/, @filter_objs@) client_objs := $(addprefix $(object_dir)/, @client_objs@) @@ -240,7 +246,7 @@ para_client: $(client_objs) para_gui: $(gui_objs) @[ -z "$(Q)" ] || echo 'LD $@' - $(Q) $(CC) $(LDFLAGS) -o $@ $(gui_objs) -lncurses + $(Q) $(CC) $(LDFLAGS) -o $@ $(gui_objs) -lcurses para_audiod: audiod_command_list.c audiod_command_list.h $(audiod_objs) @[ -z "$(Q)" ] || echo 'LD $@' @@ -275,7 +281,7 @@ clean2: clean $(Q) rm -rf man $(object_dir) $(Q) rm -f *_command_list.* -distclean: clean2 +distclean: clean2 test-clean @[ -z "$(Q)" ] || echo 'DISTCLEAN' $(Q) rm -f Makefile autoscan.log config.status config.log $(Q) rm -rf autom4te.cache aclocal.m4 @@ -311,3 +317,4 @@ $(tarball): $(cmdline_generated) %.pdf: %.ps ps2pdf - - < $< > $@ +include $(test_dir)/makefile.test diff --git a/NEWS b/NEWS index e6309e4a..e8f847b9 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,15 @@ ------------------------------------------------ -0.4.6 (to be announced) "deterministic entropy" ------------------------------------------------ +------------------------------------------- +0.4.7 (to be announced) "infinite rollback" +------------------------------------------- + + - configure: improved options for ogg/vorbis/speex. + +------------------------------------------ +0.4.6 (2011-03-31) "deterministic entropy" +------------------------------------------ -Lots of ogg/vorbis improvements, enhancements for para_gui and a fair -amount of other bug fixes. +Lots of ogg/vorbis improvements, the new test suite, enhancements +for para_gui and a fair amount of other bug fixes. - For DCCP/OGG streams the audio file header is only sent once at the beginning of the stream rather than periodically @@ -12,7 +18,11 @@ amount of other bug fixes. - The vorbis comment header is replaced by an empty dummy header before the header is sent over the network. This also results in less network traffic and smaller FEC groups. + - The new "test" make target allows to perform some sanity checks prior + to installing the package. - ogg timing fixes and performance improvements + - Scheduler improvements + - Proper exit codes for para_write - para_gui: New option --theme to select a startup theme. Several other improvements and fixes. - aacdec error message cleanups diff --git a/afs.c b/afs.c index c2fd6d52..0464eb77 100644 --- a/afs.c +++ b/afs.c @@ -468,7 +468,6 @@ again: } ret = open_and_update_audio_file(aft_row, score, &afd); if (ret < 0) { - PARA_ERROR_LOG("%s\n", para_strerror(-ret)); ret = score_delete(aft_row); if (ret < 0) { PARA_ERROR_LOG("%s\n", para_strerror(-ret)); diff --git a/aft.c b/aft.c index 266188b5..b3dde137 100644 --- a/aft.c +++ b/aft.c @@ -1136,6 +1136,8 @@ int open_and_update_audio_file(struct osl_row *aft_row, long score, err: free(afd->afhi.chunk_table); osl_close_disk_object(&chunk_table_obj); + if (ret < 0) + PARA_ERROR_LOG("%s: %s\n", path, para_strerror(-ret)); return ret; } diff --git a/alsa_write.c b/alsa_write.c index ae3bbfba..8cf5cfd2 100644 --- a/alsa_write.c +++ b/alsa_write.c @@ -214,7 +214,7 @@ again: bytes = btr_next_buffer(btrn, &data); if (ret < 0 || bytes < wn->min_iqs) { /* eof */ assert(btr_no_parent(btrn)); - ret = -E_ALSA_EOF; + ret = -E_WRITE_COMMON_EOF; if (!pad) goto err; /* wait until pending frames are played */ diff --git a/audiod.c b/audiod.c index 8dd69c60..5bc22c81 100644 --- a/audiod.c +++ b/audiod.c @@ -168,7 +168,7 @@ struct command_task { * \return The audio format number on success, -E_UNSUPPORTED_AUDIO_FORMAT if * \a name is not a supported audio format. */ -int get_audio_format_num(const char *name) +static int get_audio_format_num(const char *name) { int i; @@ -470,20 +470,6 @@ static int get_empty_slot(void) return -E_NO_MORE_SLOTS; } -/** - * get the number of filters - * - * \param audio_format_num the number identifying the audio format - * - * \return the number of filters for the given audio format - * - * \sa struct filter; - */ -int num_filters(int audio_format_num) -{ - return afi[audio_format_num].num_filters; -} - static void open_filters(struct slot_info *s) { struct audio_format_info *a = afi + s->format; @@ -1098,17 +1084,17 @@ static void try_to_close_slot(int slot_num) if (s->format < 0) return; - if (s->receiver_node && s->receiver_node->task.error != -E_TASK_UNREGISTERED) + if (s->receiver_node && s->receiver_node->task.error >= 0) return; for (i = 0; i < a->num_filters; i++) - if (s->fns && s->fns[i].task.error != -E_TASK_UNREGISTERED) + if (s->fns && s->fns[i].task.error >= 0) return; if (a->num_writers > 0) { for (i = 0; i < a->num_writers; i++) - if (s->wns && s->wns[i].task.error != -E_TASK_UNREGISTERED) + if (s->wns && s->wns[i].task.error >= 0) return; } else { - if (s->wns && s->wns[0].task.error != -E_TASK_UNREGISTERED) + if (s->wns && s->wns[0].task.error >= 0) return; } PARA_INFO_LOG("closing slot %d\n", slot_num); @@ -1189,7 +1175,7 @@ static void status_post_select(__a_unused struct sched *s, struct task *t) kill_btrn(st->ct->btrn, &st->ct->task, -E_AUDIOD_OFF); goto out; } - if (st->ct->task.error != -E_TASK_UNREGISTERED) + if (st->ct->task.error >= 0) goto out; close_stat_pipe(); st->clock_diff_count = conf.clock_diff_count_arg; @@ -1200,7 +1186,7 @@ static void status_post_select(__a_unused struct sched *s, struct task *t) size_t sz; int ret; if (st->ct->task.error < 0) { - if (st->ct->task.error != -E_TASK_UNREGISTERED) + if (st->ct->task.error >= 0) goto out; close_stat_pipe(); goto out; diff --git a/audiod.cmd b/audiod.cmd index 7ffe98e7..c5890744 100644 --- a/audiod.cmd +++ b/audiod.cmd @@ -14,7 +14,7 @@ H: on -> standby -> off -> on N: grab D: grab the audio stream L: -U: -- grab [-m[{s|p|a}]] [-p=] [-n=] [-o] +U: -- grab [-m[{s|p|a}]] [-p=PARENT] [-n=NAME] [-o] H: H: grab ('splice') the audio stream at any position in the buffer H: tree and send that data back to the client. @@ -35,7 +35,7 @@ H: ready for writing (i.e. would block). Sloppy mode ignores H: the write, pedantic mode aborts and aggressive mode tries H: to write anyway. H: -H: -p Grab output of node of the buffer tree. +H: -p Grab output of node PARENT of the buffer tree. H: H: -n Name of the new buffer tree node. Defaults to 'grab'. H: @@ -49,11 +49,6 @@ H: in any way. But now these days are gone, I'm not so self assured. Now I find H: I've changed my mind and opened up the doors. H: -- Beatles: Help --- -N: kill -D: kill an active audiod task -U: kill task_id [task_id ...] -H: Simulate an error condition for the given task(s) ---- N: off D: deactivate para_audiod U: off diff --git a/audiod.h b/audiod.h index 94399602..4c321222 100644 --- a/audiod.h +++ b/audiod.h @@ -7,9 +7,6 @@ /** \file audiod.h symbols exported from audiod.c */ -int num_filters(int audio_format_num); -int get_audio_format_num(const char *name); - /** enum of audio formats supported by para_audiod */ enum {AUDIOD_AUDIO_FORMATS_ENUM}; diff --git a/audiod_command.c b/audiod_command.c index eed9fc15..bfd7c4aa 100644 --- a/audiod_command.c +++ b/audiod_command.c @@ -301,21 +301,6 @@ int com_tasks(int fd, __a_unused int argc, __a_unused char **argv) return ret; } -int com_kill(int fd, int argc, char **argv) -{ - int i, ret = 1; - if (argc < 2) - return -E_AUDIOD_SYNTAX; - for (i = 1; i < argc; i++) { - ret = kill_task(argv[i]); - if (ret < 0) - break; - } - if (ret > 0) - close(fd); - return ret; -} - int com_stat(int fd, int argc, char **argv) { int i, ret, parser_friendly = 0; diff --git a/autogen.sh b/autogen.sh index 76eaef2f..a047f7c4 100755 --- a/autogen.sh +++ b/autogen.sh @@ -3,11 +3,11 @@ echo preparing... if test -f Makefile; then make maintainer-clean > /dev/null fi -aclocal -I . &> /dev/null +aclocal -I . > /dev/null 2>&1 autoconf autoheader echo configuring... ./configure $@ > /dev/null echo compiling... -make clean2 &> /dev/null +make clean2 > /dev/null 2>&1 make > /dev/null diff --git a/command.c b/command.c index 029e2890..24ddf789 100644 --- a/command.c +++ b/command.c @@ -256,7 +256,8 @@ int com_si(struct rc4_context *rc4c, int argc, __a_unused char * const * argv) free(info); } ut = uptime_str(); - ret = rc4_send_va_buffer(rc4c, "up: %s\nplayed: %u\n" + ret = rc4_send_va_buffer(rc4c, "version: " GIT_VERSION "\n" + "up: %s\nplayed: %u\n" "server_pid: %d\n" "afs_pid: %d\n" "connections (active/accepted/total): %u/%u/%u\n" diff --git a/configure.ac b/configure.ac index e8b2118c..e5a23438 100644 --- a/configure.ac +++ b/configure.ac @@ -353,31 +353,31 @@ if test ${have_ucred} = yes; then fi ########################################################################### curses -have_ncurses="yes" +have_curses="yes" OLD_CPPFLAGS="$CPPFLAGS" OLD_LD_FLAGS="$LDFLAGS" OLD_LIBS="$LIBS" -AC_ARG_WITH(ncurses_headers, [AC_HELP_STRING(--with-ncurses-headers=dir, - [look for ncurses.h also in dir])]) -if test -n "$with_ncurses_headers"; then - ncurses_cppflags="-I$with_ncurses_headers" - CPPFLAGS="$CPPFLAGS $ncurses_cppflags" +AC_ARG_WITH(curses_headers, [AC_HELP_STRING(--with-curses-headers=dir, + [look for curses.h also in dir])]) +if test -n "$with_curses_headers"; then + curses_cppflags="-I$with_curses_headers" + CPPFLAGS="$CPPFLAGS $curses_cppflags" fi -AC_ARG_WITH(ncurses_libs, [AC_HELP_STRING(--with-ncurses-libs=dir, - [look for libncurses also in dir])]) -if test -n "$with_ncurses_libs"; then - ncurses_libs="-L$with_ncurses_libs" - LDFLAGS="$LDFLAGS $ncurses_libs" +AC_ARG_WITH(curses_libs, [AC_HELP_STRING(--with-curses-libs=dir, + [look for libcurses also in dir])]) +if test -n "$with_curses_libs"; then + curses_libs="-L$with_curses_libs" + LDFLAGS="$LDFLAGS $curses_libs" fi AC_CHECK_HEADER(curses.h, [], [ - have_ncurses="no" + have_curses="no" ]) -AC_CHECK_LIB([ncurses], [initscr], [], [ - have_ncurses="no" +AC_CHECK_LIB([curses], [initscr], [], [ + have_curses="no" ]) -if test "$have_ncurses" = "yes"; then - AC_SUBST(ncurses_cppflags) - AC_DEFINE(HAVE_NCURSES, 1, [define to 1 to turn on ncurses support]) +if test "$have_curses" = "yes"; then + AC_SUBST(curses_cppflags) + AC_DEFINE(HAVE_NCURSES, 1, [define to 1 to turn on curses support]) extras="$extras gui" executables="$executables gui" else @@ -430,86 +430,120 @@ if test ${have_core_audio} = yes; then fi ########################################################### ogg/vorbis/speex have_ogg="yes" -have_vorbis="yes" -have_speex="yes" OLD_CPPFLAGS="$CPPFLAGS" OLD_LD_FLAGS="$LDFLAGS" OLD_LIBS="$LIBS" -AC_ARG_WITH(oggvorbis_headers, [AC_HELP_STRING(--with-oggvorbis-headers=dir, - [look for ogg/vorbis/speex headers also in dir])]) -if test -n "$with_oggvorbis_headers"; then - ogg_cppflags="-I$with_oggvorbis_headers" +AC_ARG_WITH(ogg_headers, [AC_HELP_STRING(--with-ogg-headers=dir, + [look for ogg headers also in dir])]) +AC_ARG_WITH(ogg_libs, [AC_HELP_STRING(--with-ogg-libs=dir, + [look for ogg libs also in dir])]) +AC_ARG_WITH(vorbis_headers, [AC_HELP_STRING(--with-vorbis-headers=dir, + [look for vorbis headers also in dir])]) +AC_ARG_WITH(vorbis_libs, [AC_HELP_STRING(--with-vorbis-libs=dir, + [look for vorbis libs also in dir])]) +AC_ARG_WITH(speex_headers, [AC_HELP_STRING(--with-speex-headers=dir, + [look for speex headers also in dir])]) +AC_ARG_WITH(speex_libs, [AC_HELP_STRING(--with-speex-libs=dir, + [look for speex libs also in dir])]) + +if test -n "$with_ogg_headers"; then + ogg_cppflags="-I$with_ogg_headers" CPPFLAGS="$CPPFLAGS $ogg_cppflags" fi -AC_ARG_WITH(oggvorbis_libs, [AC_HELP_STRING(--with-oggvorbis-libs=dir, - [look for ogg/vorbis/speex libs also in dir])]) -if test -n "$with_oggvorbis_libs"; then - ogg_libs="-L$with_oggvorbis_libs" +if test -n "$with_ogg_libs"; then + ogg_libs="-L$with_ogg_libs" LDFLAGS="$LDFLAGS $ogg_libs" fi - -AC_CHECK_LIB([ogg], [ogg_stream_init], [], [ have_ogg="no" ]) -AC_CHECK_LIB([vorbis], [vorbis_info_init], [], [ have_vorbis="no" ]) -AC_CHECK_LIB([speex], [speex_decoder_init], [], [ have_speex="no" ]) AC_CHECK_HEADERS([ogg/ogg.h], [], [ have_ogg="no"; ]) -AC_CHECK_HEADERS([vorbis/codec.h], [], [ have_vorbis="no" ]) -AC_CHECK_HEADERS([speex/speex.h], [], [ have_speex="no" ]) +AC_CHECK_LIB([ogg], [ogg_stream_init], [], [ have_ogg="no" ]) + +have_vorbis="yes" +have_speex="yes" +if test "$have_ogg" = "yes"; then + # vorbis + if test -n "$with_vorbis_headers"; then + vorbis_cppflags="-I$with_vorbis_headers" + CPPFLAGS="$CPPFLAGS $vorbis_cppflags" + fi + if test -n "$with_vorbis_libs"; then + vorbis_libs="-L$with_vorbis_libs" + LDFLAGS="$LDFLAGS $vorbis_libs" + fi + AC_CHECK_HEADERS([vorbis/codec.h], [], [ have_vorbis="no" ]) + AC_CHECK_LIB([vorbis], [vorbis_info_init], [], [ have_vorbis="no" ]) + + # speex + if test -n "$with_speex_headers"; then + speex_cppflags="-I$with_speex_headers" + CPPFLAGS="$CPPFLAGS $speex_cppflags" + fi + if test -n "$with_speex_libs"; then + speex_libs="-L$with_speex_libs" + LDFLAGS="$LDFLAGS $speex_libs" + fi + AC_CHECK_LIB([speex], [speex_decoder_init], [], [ have_speex="no" ]) + AC_CHECK_HEADERS([speex/speex.h], [], [ have_speex="no" ]) +else + have_vorbis="no" + have_speex="no" +fi + msg="support in para_server/para_filter/para_afh" -if test "$have_ogg" = "yes" && { test "$have_vorbis" = "yes" || test "$have_speex" = "yes"; }; then +if test "$have_vorbis" = "yes" || test "$have_speex" = "yes"; then AC_SUBST(ogg_cppflags) ogg_libs="$ogg_libs -logg" if test "$OSTYPE" = "Darwin"; then - ogg_libs="-Wl,-bind_at_load $ogg_libs $ogg_libs" + ogg_libs="-Wl,-bind_at_load $ogg_libs" fi server_ldflags="$server_ldflags $ogg_libs" filter_ldflags="$filter_ldflags $ogg_libs" audiod_ldflags="$audiod_ldflags $ogg_libs" - all_errlist_objs="$all_errlist_objs ogg_afh_common" afh_ldflags="$afh_ldflags $ogg_libs" + all_errlist_objs="$all_errlist_objs ogg_afh_common" afh_errlist_objs="$afh_errlist_objs ogg_afh_common" server_errlist_objs="$server_errlist_objs ogg_afh_common" - if test "$have_vorbis" = "yes"; then - all_errlist_objs="$all_errlist_objs oggdec_filter ogg_afh" - AC_DEFINE(HAVE_OGGVORBIS, 1, define to 1 to turn on ogg/vorbis support) - filters="$filters oggdec" - vorbis_libs="-lvorbis -lvorbisfile" - server_ldflags="$server_ldflags $vorbis_libs" - filter_ldflags="$filter_ldflags $vorbis_libs" - audiod_ldflags="$audiod_ldflags $vorbis_libs" - afh_ldflags="$afh_ldflags $vorbis_libs" - - server_errlist_objs="$server_errlist_objs ogg_afh" - filter_errlist_objs="$filter_errlist_objs oggdec_filter" - audiod_errlist_objs="$audiod_errlist_objs oggdec_filter" - afh_errlist_objs="$afh_errlist_objs ogg_afh" - - audiod_audio_formats="$audiod_audio_formats ogg" - server_audio_formats="$server_audio_formats ogg" - else - AC_MSG_WARN([no ogg/vorbis $msg]) - fi - if test "$have_speex" = "yes"; then - all_errlist_objs="$all_errlist_objs spxdec_filter spx_afh spx_common" - AC_DEFINE(HAVE_SPEEX, 1, define to 1 to turn on ogg/speex support) - filters="$filters spxdec" - speex_libs="-lspeex" - server_ldflags="$server_ldflags $speex_libs" - filter_ldflags="$filter_ldflags $speex_libs" - audiod_ldflags="$audiod_ldflags $speex_libs" - afh_ldflags="$afh_ldflags $speex_libs" - - server_errlist_objs="$server_errlist_objs spx_afh spx_common" - filter_errlist_objs="$filter_errlist_objs spxdec_filter spx_common" - audiod_errlist_objs="$audiod_errlist_objs spxdec_filter spx_common" - afh_errlist_objs="$afh_errlist_objs spx_afh spx_common" - - audiod_audio_formats="$audiod_audio_formats spx" - server_audio_formats="$server_audio_formats spx" - else - AC_MSG_WARN([no ogg/speex $msg]) - fi else - AC_MSG_WARN([no ogg/vorbis ogg/speex $msg]) + AC_MSG_WARN([vorbis/speex require ogg]) +fi +if test "$have_vorbis" = "yes"; then + all_errlist_objs="$all_errlist_objs oggdec_filter ogg_afh" + AC_DEFINE(HAVE_OGGVORBIS, 1, define to 1 to turn on ogg/vorbis support) + filters="$filters oggdec" + vorbis_libs="-lvorbis -lvorbisfile" + server_ldflags="$server_ldflags $vorbis_libs" + filter_ldflags="$filter_ldflags $vorbis_libs" + audiod_ldflags="$audiod_ldflags $vorbis_libs" + afh_ldflags="$afh_ldflags $vorbis_libs" + + server_errlist_objs="$server_errlist_objs ogg_afh" + filter_errlist_objs="$filter_errlist_objs oggdec_filter" + audiod_errlist_objs="$audiod_errlist_objs oggdec_filter" + afh_errlist_objs="$afh_errlist_objs ogg_afh" + + audiod_audio_formats="$audiod_audio_formats ogg" + server_audio_formats="$server_audio_formats ogg" +else + AC_MSG_WARN([no ogg/vorbis $msg]) +fi +if test "$have_speex" = "yes"; then + all_errlist_objs="$all_errlist_objs spxdec_filter spx_afh spx_common" + AC_DEFINE(HAVE_SPEEX, 1, define to 1 to turn on ogg/speex support) + filters="$filters spxdec" + speex_libs="-lspeex" + server_ldflags="$server_ldflags $speex_libs" + filter_ldflags="$filter_ldflags $speex_libs" + audiod_ldflags="$audiod_ldflags $speex_libs" + afh_ldflags="$afh_ldflags $speex_libs" + + server_errlist_objs="$server_errlist_objs spx_afh spx_common" + filter_errlist_objs="$filter_errlist_objs spxdec_filter spx_common" + audiod_errlist_objs="$audiod_errlist_objs spxdec_filter spx_common" + afh_errlist_objs="$afh_errlist_objs spx_afh spx_common" + + audiod_audio_formats="$audiod_audio_formats spx" + server_audio_formats="$server_audio_formats spx" +else + AC_MSG_WARN([no ogg/speex $msg]) fi CPPFLAGS="$OLD_CPPFLAGS" LDFLAGS="$OLD_LDFLAGS" diff --git a/error.h b/error.h index 5a2e39b4..fdd2d3b7 100644 --- a/error.h +++ b/error.h @@ -103,7 +103,6 @@ extern const char **para_errlist[]; PARA_ERROR(BAD_SAMPLE_FORMAT, "sample format not supported"), \ PARA_ERROR(BAD_CHANNEL_COUNT, "channel count not supported"), \ PARA_ERROR(BAD_SAMPLERATE, "sample rate not supported"), \ - PARA_ERROR(OSS_EOF, "oss: end of file"), \ #define COMPRESS_FILTER_ERRORS \ @@ -230,10 +229,8 @@ extern const char **para_errlist[]; #define SCHED_ERRORS \ - PARA_ERROR(TASK_KILLED, "task killed"), \ - PARA_ERROR(TASK_UNREGISTERED, "task has been unscheduled"), \ - PARA_ERROR(NO_SUCH_TASK, "task not found"), \ PARA_ERROR(NOT_INITIALIZED, "scheduler not yet initialized"), \ + PARA_ERROR(SCHED_SHUTDOWN, "scheduler was shut down"), \ #define NET_ERRORS \ @@ -276,7 +273,6 @@ extern const char **para_errlist[]; #define AUDIOD_COMMAND_ERRORS \ PARA_ERROR(CLIENT_WRITE, "client write error"), \ - PARA_ERROR(AUDIOD_SYNTAX, "syntax error"), \ PARA_ERROR(UCRED_PERM, "permission denied"), \ PARA_ERROR(INVALID_AUDIOD_CMD, "invalid command"), \ PARA_ERROR(TOO_MANY_CLIENTS, "maximal number of stat clients exceeded"), \ @@ -396,7 +392,6 @@ extern const char **para_errlist[]; #define WRITE_ERRORS \ PARA_ERROR(WRITE_SYNTAX, "para_write syntax error"), \ - PARA_ERROR(NO_WAV_HEADER, "wave header not found"), \ #define ALSA_WRITE_ERRORS \ @@ -414,12 +409,11 @@ extern const char **para_errlist[]; PARA_ERROR(SET_RATE, "snd_pcm_hw_params_set_rate_near failed"), \ PARA_ERROR(START_THRESHOLD, "snd_pcm_sw_params_set_start_threshold() failed"), \ PARA_ERROR(STOP_THRESHOLD, "snd_pcm_sw_params_set_stop_threshold() failed"), \ - PARA_ERROR(ALSA_EOF, "alsa: end of file"), \ - #define WRITE_COMMON_ERRORS \ PARA_ERROR(WRITE_COMMON_SYNTAX, "syntax error in write option"), \ + PARA_ERROR(WRITE_COMMON_EOF, "end of file"), \ #define AACDEC_FILTER_ERRORS \ diff --git a/fade.c b/fade.c index 8affd69d..41b4a6d7 100644 --- a/fade.c +++ b/fade.c @@ -126,6 +126,7 @@ static void fixup_mixer_channel_arg(void) case mixer_channel_arg_reclev: val = SOUND_MIXER_RECLEV; break; case mixer_channel_arg_igain: val = SOUND_MIXER_IGAIN; break; case mixer_channel_arg_ogain: val = SOUND_MIXER_OGAIN; break; + default: break; } conf.mixer_channel_arg = val; } @@ -345,15 +346,15 @@ int main(int argc, char *argv[]) } fixup_mixer_channel_arg(); switch (conf.mode_arg) { - case mode_arg_sleep: - ret = sweet_dreams(); - break; case mode_arg_fade: ret = fade(conf.fade_vol_arg, conf.fade_time_arg); break; case mode_arg_snooze: ret = snooze(); break; + default: /* sleep mode */ + ret = sweet_dreams(); + break; } if (ret < 0) PARA_EMERG_LOG("%s\n", para_strerror(-ret)); diff --git a/fec.c b/fec.c index dc6e7520..233a8780 100644 --- a/fec.c +++ b/fec.c @@ -179,14 +179,14 @@ static void generate_gf(void) * This is used often, so better optimize it! Currently the loop is unrolled 16 * times. The case c=0 is also optimized, whereas c=1 is not. */ -static void addmul(unsigned char *dst1, const unsigned char const *src1, +static void addmul(unsigned char *dst1, const unsigned char *src1, unsigned char c, int sz) { if (c == 0) return; unsigned char *dst = dst1, *lim = &dst[sz - UNROLL + 1], *col = gf_mul_table[c]; - const unsigned char const *src = src1; + const unsigned char *src = src1; for (; dst < lim; dst += UNROLL, src += UNROLL) { dst[0] ^= col[src[0]]; diff --git a/grab_client.c b/grab_client.c index 8e671503..de6df6df 100644 --- a/grab_client.c +++ b/grab_client.c @@ -131,13 +131,12 @@ static void gc_activate(struct grab_client *gc) list_move(&gc->node, &active_grab_client_list); gc->btrn = btr_new_node(&(struct btr_node_description) EMBRACE(.name = name, .parent = parent)); - if (!gc->task.pre_select) { - gc->task.pre_select = gc_pre_select; - gc->task.post_select = gc_post_select; - snprintf(gc->task.status, sizeof(gc->task.status) - 1, "%s", name); - gc->task.status[sizeof(gc->task.status) - 1] = '\0'; - register_task(&gc->task); - } + gc->task.pre_select = gc_pre_select; + gc->task.post_select = gc_post_select; + snprintf(gc->task.status, sizeof(gc->task.status) - 1, "%s", name); + gc->task.status[sizeof(gc->task.status) - 1] = '\0'; + gc->task.error = 0; + register_task(&gc->task); } /** @@ -156,7 +155,7 @@ void activate_grab_clients(void) struct grab_client *gc, *tmp; list_for_each_entry_safe(gc, tmp, &inactive_grab_client_list, node) { - if (gc->task.error == -E_TASK_UNREGISTERED) { + if (gc->fd < 0) { list_del(&gc->node); free(gc); continue; @@ -179,11 +178,11 @@ static int gc_close(struct grab_client *gc, int err) * post_select(). */ close(gc->fd); + gc->fd = -1; free(gc->parent); free(gc->name); return 1; } - gc_activate(gc); return 0; } @@ -210,7 +209,8 @@ static void gc_post_select(__a_unused struct sched *s, struct task *t) btr_consume(btrn, ret); return; err: - t->error = gc_close(gc, ret)? ret : 0; + gc_close(gc, ret); + t->error = ret; } static int gc_check_args(int argc, char **argv, struct grab_client *gc) diff --git a/gui.c b/gui.c index 4be81f74..578eeed0 100644 --- a/gui.c +++ b/gui.c @@ -34,10 +34,10 @@ static int signal_pipe; static struct win_data { WINDOW *win; - NCURSES_SIZE_T begx; - NCURSES_SIZE_T begy; - NCURSES_SIZE_T cols; - NCURSES_SIZE_T lines; + size_t begx; + size_t begy; + size_t cols; + size_t lines; } top, bot, sb, in, sep; #define RINGBUFFER_SIZE 512 diff --git a/mm.c b/mm.c index a9f4b9bd..af99a36f 100644 --- a/mm.c +++ b/mm.c @@ -32,7 +32,7 @@ enum mood_comparator_id {MOOD_COMPARATORS NUM_MOOD_COMPARATORS}; #undef MC #define MC(a, b) # b, -static const char const *mood_comparators[] = {MOOD_COMPARATORS}; +static const char *mood_comparators[] = {MOOD_COMPARATORS}; #undef MC static int parse_mood_comparator(const char *word) diff --git a/oss_write.c b/oss_write.c index 70a58203..e79ea6ce 100644 --- a/oss_write.c +++ b/oss_write.c @@ -185,7 +185,7 @@ static void oss_post_select(__a_unused struct sched *s, bytes = btr_next_buffer(btrn, &data); frames = bytes / powd->bytes_per_frame; if (!frames) { /* eof and less than a single frame available */ - ret = -E_OSS_EOF; + ret = -E_WRITE_COMMON_EOF; goto out; } ret = 0; diff --git a/para.h b/para.h index 3121850f..7217486d 100644 --- a/para.h +++ b/para.h @@ -205,6 +205,9 @@ _static_inline_ long int para_random(unsigned max) /** Used to avoid a shortcoming in vim's syntax highlighting. */ #define EMBRACE(...) { __VA_ARGS__} +/** A nice cup of STFU for Mr gcc. */ +#define do_nothing do {/* nothing */} while (0) + /** * The sample formats supported by paraslash. * diff --git a/sched.c b/sched.c index b0e9ce12..9be3a2e8 100644 --- a/sched.c +++ b/sched.c @@ -38,21 +38,20 @@ static void unregister_task(struct task *t) { if (!initialized) return; + assert(t->error < 0); PARA_INFO_LOG("unregistering %s (%s)\n", t->status, - t->error <0? para_strerror(-t->error) : "shutdown"); + para_strerror(-t->error)); if (t->pre_select) list_del(&t->pre_select_node); if (t->post_select) list_del(&t->post_select_node); - t->error = -E_TASK_UNREGISTERED; } - static void sched_preselect(struct sched *s) { struct task *t, *tmp; list_for_each_entry_safe(t, tmp, &pre_select_list, pre_select_node) { - if (t->error >= 0 && t->pre_select) + if (t->pre_select) t->pre_select(s, t); // PARA_INFO_LOG("%s \n", t->status); if (t->error >= 0) @@ -207,10 +206,14 @@ void sched_shutdown(void) if (!initialized) return; - list_for_each_entry_safe(t, tmp, &pre_select_list, pre_select_node) + list_for_each_entry_safe(t, tmp, &pre_select_list, pre_select_node) { + t->error = -E_SCHED_SHUTDOWN; unregister_task(t); - list_for_each_entry_safe(t, tmp, &post_select_list, post_select_node) + } + list_for_each_entry_safe(t, tmp, &post_select_list, post_select_node) { + t->error = -E_SCHED_SHUTDOWN; unregister_task(t); + } initialized = 0; } @@ -219,8 +222,7 @@ void sched_shutdown(void) * * \return The task list. * - * Each entry of the list contains an identifier which is simply a hex number - * that may be used in \a kill_task() to terminate the task. + * Each entry of the list contains an identifier which is simply a hex number. * The result is dynamically allocated and must be freed by the caller. */ char *get_task_list(void) @@ -248,41 +250,6 @@ char *get_task_list(void) return msg; } -/** - * Simulate an error for the given task. - * - * \param id The task identifier. - * - * Find the task identified by \a id, set the tasks' error value to - * \p -E_TASK_KILLED and unregister the task. - * - * \return Positive on success, negative on errors (e.g. if \a id does not - * correspond to a registered task). - */ -int kill_task(char *id) -{ - struct task *t, *tmp; - char buf[20]; - - if (!initialized) - return -E_NOT_INITIALIZED; - list_for_each_entry_safe(t, tmp, &pre_select_list, pre_select_node) { - sprintf(buf, "%p", t); - if (strcmp(id, buf)) - continue; - t->error = -E_TASK_KILLED; - return 1; - } - list_for_each_entry_safe(t, tmp, &post_select_list, post_select_node) { - sprintf(buf, "%p", t); - if (strcmp(id, buf)) - continue; - t->error = -E_TASK_KILLED; - return 1; - } - return -E_NO_SUCH_TASK; -} - /** * Set the select timeout to the minimal possible value. * diff --git a/sched.h b/sched.h index 7158a873..e018c2fe 100644 --- a/sched.h +++ b/sched.h @@ -77,7 +77,6 @@ extern struct timeval *now; void register_task(struct task *t); int schedule(struct sched *s); char *get_task_list(void); -int kill_task(char *id); void sched_shutdown(void); void sched_min_delay(struct sched *s); void sched_request_timeout(struct timeval *to, struct sched *s); diff --git a/stdin.h b/stdin.h index 2d279a6e..32a4c281 100644 --- a/stdin.h +++ b/stdin.h @@ -12,7 +12,7 @@ struct stdin_task { struct task task; /** Stdin is always the root of a buffer tree. */ struct btr_node *btrn; - /* Use a buffer pool to minimize memcpy due to alignment problems. */ + /** Use a buffer pool to minimize memcpy due to alignment problems. */ struct btr_pool *btrp; }; diff --git a/t/.gitignore b/t/.gitignore new file mode 100644 index 00000000..e61ae9c6 --- /dev/null +++ b/t/.gitignore @@ -0,0 +1,2 @@ +/trashes +/test-results diff --git a/t/audio_files/short-44100-2.ogg b/t/audio_files/short-44100-2.ogg new file mode 100644 index 00000000..91981cd0 Binary files /dev/null and b/t/audio_files/short-44100-2.ogg differ diff --git a/t/makefile.test b/t/makefile.test new file mode 100644 index 00000000..d4aedf80 --- /dev/null +++ b/t/makefile.test @@ -0,0 +1,32 @@ +RM ?= rm -f + +results_dir := $(test_dir)/test-results +trash_dir := $(test_dir)/trashes + +test_options := --executables-dir $(shell pwd) +test_options += --results-dir $(results_dir) +test_options += --trash-dir $(trash_dir) +test_options += --executables "$(executables)" +test_options += --objects "$(basename $(notdir $(all_objs)))" + +ifdef V + ifeq ("$(origin V)", "command line") + test_options += --verbose=$(V) + endif +endif + +tests := $(wildcard $(test_dir)/t[0-9][0-9][0-9][0-9]-*.sh) + +test: $(tests) + +$(tests): all + $(Q) $@ $(test_options) + +test-help: + $(Q) for t in $(tests); do $$t $(test_options) -h; done + +test-clean: + $(RM) -r $(results_dir) + $(RM) -r $(trash_dir) + +.PHONY: $(tests) test-help diff --git a/t/t0000-help-output.sh b/t/t0000-help-output.sh new file mode 100755 index 00000000..fcc2c783 --- /dev/null +++ b/t/t0000-help-output.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +test_description='Parse help output of all executables. + +Each paraslash executable supports the -h switch which instructs +the program to print out all available options and to exit. This test +checks whether this help output looks as expected.' + +. ${0%/*}/test-lib.sh + +grep_output() +{ + local regex='^ -h, --help' + $1 -h | grep "$regex" +} + +for exe in $o_executables; do + test_expect_success "$exe" "grep_output $o_executables_dir/$exe" +done +test_done diff --git a/t/t0001-oggdec-correctness.sh b/t/t0001-oggdec-correctness.sh new file mode 100755 index 00000000..01260e5c --- /dev/null +++ b/t/t0001-oggdec-correctness.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +test_description='Check correctness of oggdec output. + +Executes para_filter -f oggdec on the test files provided by the test +suite and compares the output against the output of the reference +implementation.' + +. ${0%/*}/test-lib.sh + +test_require_objects "oggdec_filter" +missing_objects="$result" + +test_require_executables "oggdec" +missing_executables="$result" + +get_audio_file_paths ogg +oggs="$result" + +for ogg in $oggs; do + if [[ -n "$missing_objects" ]]; then + test_skip "${ogg##*/}" "missing object(s): $missing_objects" + continue + fi + if [[ -n "$missing_executables" ]]; then + test_skip "${ogg##*/}" \ + "missing executables(s): $missing_executables" + continue + fi + test_expect_success "${ogg##*/}" " + $PARA_FILTER -f oggdec < $ogg | sha1sum > filter.sha1 && + oggdec --quiet --raw --output - - < $ogg | sha1sum > oggdec.sha1 && + diff -u filter.sha1 oggdec.sha1 + " +done +test_done diff --git a/t/t0002-oggdec-performance.sh b/t/t0002-oggdec-performance.sh new file mode 100755 index 00000000..d496a3ec --- /dev/null +++ b/t/t0002-oggdec-performance.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +test_description='Measure time to decode ogg/vorbis files. + +Executes para_filter -f oggdec on the test files provided by the +test suite and fails if it takes much longer than the reference +implementation.' + +. ${0%/*}/test-lib.sh + +test_require_objects "oggdec_filter" +missing_objects="$result" + +get_audio_file_paths ogg +oggs="$result" + +test_require_executables "oggdec" +missing_executables="$result" + +for ogg in $oggs; do + if [[ -n "$missing_objects" ]]; then + test_skip "${ogg##*/}" "missing object(s): $missing_objects" + continue + fi + if [[ -n "$missing_executables" ]]; then + test_skip "${ogg##*/}" \ + "missing executables(s): $missing_executables" + continue + fi + test_expect_success "${ogg##*/}" ' + test_duration oggdec --quiet --raw --output - - < $ogg && + t1=$result && + test_duration $PARA_FILTER -f oggdec < $ogg && + t2=$result && + echo "oggdec: $t1, para_filter: $t2" + (($t2 <= $t1 * 3 / 2 + 100)) + ' +done +test_done diff --git a/t/t0003-writer-init-error-path.sh b/t/t0003-writer-init-error-path.sh new file mode 100755 index 00000000..15f1dd8e --- /dev/null +++ b/t/t0003-writer-init-error-path.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +test_description='Check if alsa_init() failures are handled gracefully. + +Older parasslash versions contained a bug which caused para_write and para_audiod +to abort if the alsa/oss device could not be opened. This test makes sure we +will not introduce the same bug again.' + +. ${0%/*}/test-lib.sh + +for i in alsa oss; do + test_require_objects "${i}_write" + missing_objects="$result" + if [[ -n "$missing_objects" ]]; then + test_skip "$i" "missing object(s): $missing_objects" + continue + fi + test_expect_failure "$i" " + head -c 100 /dev/zero | $PARA_WRITE -w '$i -d /dev/non_existent' + " +done +test_done diff --git a/t/test-lib.sh b/t/test-lib.sh new file mode 100644 index 00000000..b7d675ea --- /dev/null +++ b/t/test-lib.sh @@ -0,0 +1,323 @@ +#!/bin/bash + +# paraslash test suite helper functions +# Licensed under the GPL v2. For licencing details see COPYING. +# uses ideas and code from git's test-lib.sh, Copyright (c) 2005 Junio C Hamano + + +get_audio_file_paths() +{ + local suffix="$1" + + if (($# == 0)); then + result=$(find "$test_audio_file_dir" -type f) + else + result=$(find "$test_audio_file_dir" -type f -name "*.$suffix") + fi +} + +say_color() +{ + if [[ "$o_nocolor" != "true" && -n "$1" ]]; then + export TERM=$ORIGINAL_TERM + case "$1" in + error) tput bold; tput setaf 1;; + skip) tput setaf 5;; + ok) + (($o_verbose == 0)) && return + tput setaf 2;; + pass) tput bold; tput setaf 2;; + info) tput setaf 3;; + run) + (($o_verbose == 0)) && return + tput setaf 6;; + esac + fi + shift + printf "%s\n" "$*" + if [[ "$o_nocolor" != "true" && -n "$1" ]]; then + tput sgr0 + export TERM=dumb + fi +} + +die() +{ + local code=$? + [[ "$exit_ok" == "true" ]] && exit $code + say_color error "FATAL: Unexpected exit with code $code" + exit 1 +} + +error() +{ + say_color error "error: $*" + exit_ok="true" + exit 1 +} + +say() +{ + say_color info "$*" +} + +retval_ok() +{ + local rv="$1" expectation="$2" + + if [[ "$expectation" == "success" ]]; then + (($rv == 0)) && return 0 || return 1 + fi + if (($rv > 129 && $rv <= 192)); then + echo >&2 "died by signal" + return 1 + fi + if (($rv == 127)); then + echo >&2 "command not found" + return 1 + fi + if (($rv == 0)); then + echo >&2 "command was supposed to fail but succeeded" + return 1 + fi + return 0 +} + +_test_run() +{ + local f expectation="$3" ret + + let test_count++ + eval >&3 2>&4 "$2" + ret=$? + if retval_ok "$ret" "$expectation"; then + let test_success++ + say_color ok "ok $test_count - $1" + return + fi + let test_failure++ + say_color error "not ok - $test_count $1" + f="$o_results_dir/${0##*/}-$$.out" + if [[ -s "$f" ]]; then + sed -e 's/^/# /' < "$f" + else + sed -e 's/^/# /' <<< "$2" + fi + [[ "$o_immediate" != "true" ]] && return + exit_ok="true" + exit 1 +} + +test_skip() +{ + (($# != 2)) && error "bug: not 2 parameters to test_skip()" + let test_count++ + let test_skipped++ + say_color skip >&3 "skipping test $this_test.$test_count ($1): $2" + say_color skip "ok $test_count - $1 # skipped ($2)" +} + +test_require_objects() +{ + local o1 o2 found + + result= + # if no objects were given, we assume this test is run manually + # rather than via "make test". We won't check anything in this case + [[ -z "$o_objects" ]] && return + + for o1 in $1; do + found= + for o2 in $o_objects; do + [[ "$o1" != "$o2" ]] && continue + found="true" + break + done + [[ "$found" == "true" ]] && continue + [[ -n "$result" ]] && result+=" " + result+="$o1" + done + [[ -z "$result" ]] +} + +test_require_executables() +{ + local i + + result= + for i in "$@"; do + [[ -n "$(builtin type -t "$i")" ]] && continue + [[ -n "$result" ]] && result+=" " + result+="$i" + done + [[ -z "$result" ]] +} + +test_duration() +{ + local t=$(exec 2>&1 1>/dev/null; time -p "$@") + result=$(awk '{print $2 * 1000}' <<< $t) +} + +test_expect_success() +{ + (($# != 2)) && error "bug: not 2 parameters to test_expect_success()" + say >&3 "expecting success: $2" + _test_run "$1" "$2" "success" + echo >&3 "" +} + +test_expect_failure() +{ + (($# != 2)) && error "bug: not 2 parameters to test_expect_failure()" + say >&3 "expecting failure: $2" + _test_run "$1" "$2" "failure" + echo >&3 "" +} + +test_done() +{ + test_results_path="$o_results_dir/${0##*/}-$$.counts" + { + echo "total $test_count" + echo "success $test_success" + echo "failed $test_failure" + echo "skipped $test_skipped" + echo + } > $test_results_path + + exit_ok="true" + msg="$test_count test(s) ($test_skipped test(s) skipped)" + if (($test_failure == 0)); then + say_color pass "# ${0##*/}: passed all $msg" + exit 0 + else + say_color error "# ${0##*/}: failed $test_failure among $msg" + exit 1 + fi +} + +sanitize_environment() +{ + export LANG=C + export LC_ALL=C + export PAGER=cat + export TZ=UTC + export TERM=dumb + export EDITOR=: + export HOME=$(pwd) + + unset VISUAL + unset EMAIL + unset CDPATH + unset GREP_OPTIONS +} + +can_use_colors() +{ + result="false" + [[ "$TERM" == "dumb" ]] && return + [[ -t 1 ]] || return + tput bold >/dev/null 2>&1 || return + tput setaf 1 >/dev/null 2>&1 || return + tput sgr0 >/dev/null 2>&1 || return + result="true" +} + +parse_options() +{ + while (($# > 0)); do + case "$1" in + -i|--immediate) o_immediate="true"; shift;; + -l|--long) export o_long="true"; shift;; + -h|--help) o_help="true"; shift;; + -v=0|--verbose=0) o_verbose="0"; shift;; + -v=1|--verbose=1) o_verbose="1"; shift;; + -v|--verbose|-v=2|--verbose=2) o_verbose="2"; shift;; + --no-color) o_nocolor="true"; shift;; + --results-dir) o_results_dir="$2"; shift; shift;; + --trash-dir) o_trash_dir="$2"; shift; shift;; + --executables-dir) export o_executables_dir="$2"; shift; shift;; + --executables) export o_executables="$2"; shift; shift;; + --objects) export o_objects="$2"; shift; shift;; + *) echo "error: unknown test option '$1'" >&2; exit 1;; + esac + done + [[ -z "$o_verbose" ]] && o_verbose=1 +} + +create_trash_dir_and_cd() +{ + local trash="$o_trash_dir/trash-dir.${0##*/}" + + rm -rf "$trash" || error "could not remove trash dir" + mkdir -p "$trash" || error "could not make trash dir" + cd "$trash" || error "could not change to trash dir" +} + +fixup_dirs() +{ + local wd=$(pwd) + + test_dir="$wd/${0%/*}" + test_audio_file_dir="$test_dir/audio_files" + + [[ -z "$o_results_dir" ]] && o_results_dir="$test_dir/test-results" + [[ -z "$o_executables_dir" ]] && o_executables_dir="$test_dir/.." + [[ -z "$o_trash_dir" ]] && o_trash_dir="$test_dir/trashes" + + # we want alsolute paths because relative paths become invalid + # after changing to the trash dir + [[ -n "${o_results_dir##/*}" ]] && o_results_dir="$wd/$o_results_dir" + [[ -n "${o_executables_dir##/*}" ]] && o_executables_dir="$wd/$o_results_dir" + [[ -n "${o_trash_dir##/*}" ]] && o_trash_dir="$wd/$o_trash_dir" + + mkdir -p "$o_results_dir" +} + +parse_options "$@" +if [[ "$o_nocolor" != "true" ]]; then + can_use_colors + [[ "$result" != "true" ]] && o_nocolor="true" +fi + +# Each test must set test_description +[[ -z "${test_description}" ]] && error "${0##*/} did not set test_description" +if [[ "$o_help" == "true" ]]; then + printf "${0##*/}: " + sed -e '1!d' <<< "$test_description" + if (($o_verbose >= 2)); then + echo + sed -e '1,2d' -e 's/^/ /g' <<<"$test_description" + echo + fi + exit 0 +fi +fixup_dirs + +[[ -z "$o_executables" ]] && o_executables="para_afh para_audioc para_audiod + para_client para_fade para_filter para_gui para_recv para_server + para_write" +for exe in $o_executables; do + export $(tr 'a-z' 'A-Z' <<< $exe)="$o_executables_dir/$exe" +done + +test_failure=0 +test_count=0 +test_success=0 +test_skipped=0 + +ORIGINAL_TERM=$TERM +sanitize_environment +create_trash_dir_and_cd + +if (($o_verbose >= 2)); then + exec 4>&2 3>&1 +else + exec 4>$o_results_dir/${0##*/}-$$.out 3>&4 +fi + +exit_ok= +trap 'die' EXIT + +say_color run "# running ${0##*/}" diff --git a/udp_send.c b/udp_send.c index 4fb10b44..b4494eb7 100644 --- a/udp_send.c +++ b/udp_send.c @@ -57,8 +57,13 @@ static void udp_close_target(struct sender_client *sc) const char *buf; size_t len = vss_get_fec_eof_packet(&buf); - /* ignore return value, closing the target anyway. */ - (void)write(sc->fd, buf, len); + /* + * Ignore the return value of wirte() since we are closing the target + * anyway. The sole purpose of the "do_nothing" statement is to silence + * gcc. + */ + if (write(sc->fd, buf, len)) + do_nothing; } static void udp_delete_target(struct sender_client *sc, const char *msg) diff --git a/versions/paraslash-0.4.6.tar.bz2 b/versions/paraslash-0.4.6.tar.bz2 new file mode 100644 index 00000000..de90cf13 Binary files /dev/null and b/versions/paraslash-0.4.6.tar.bz2 differ diff --git a/versions/paraslash-0.4.6.tar.bz2.asc b/versions/paraslash-0.4.6.tar.bz2.asc new file mode 100644 index 00000000..a5307b25 --- /dev/null +++ b/versions/paraslash-0.4.6.tar.bz2.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.10 (GNU/Linux) + +iEYEABECAAYFAk2UZVsACgkQWto1QDEAkw/XxQCfZ3f3JFstN47qkV1lHLpNC0ij +woYAmwQrwy6WwMx7fttfxdou6reIrsir +=bZsC +-----END PGP SIGNATURE----- diff --git a/web/index.in.html b/web/index.in.html index 48f5bb51..f9009e4f 100644 --- a/web/index.in.html +++ b/web/index.in.html @@ -1,6 +1,10 @@

Events


    +
  • 2011-03-31: paraslash-0.4.6 + (sig) + "deterministic entropy" +
  • 2010-12-17: paraslash-0.4.5 (sig) "symmetric randomization" diff --git a/web/manual.m4 b/web/manual.m4 index 946b9d09..5926b555 100644 --- a/web/manual.m4 +++ b/web/manual.m4 @@ -280,7 +280,11 @@ might need to tell the configure script where to find them. Try ./configure --help to see a list of options. If the paraslash package was compiled -successfully, execute as root, +successfully, execute (optionally) + + make test + +to run the paraslash test suite. If all tests pass, execute as root make install diff --git a/write.c b/write.c index cf48922a..571dc4ed 100644 --- a/write.c +++ b/write.c @@ -210,6 +210,20 @@ static int main_btr(struct sched *s) s->default_timeout.tv_sec = 10; s->default_timeout.tv_usec = 50000; ret = schedule(s); + if (ret >= 0) { + int j; + for (j = 0; j < i; j++) { + struct task *t = &wns[j].task; + assert(t->error < 0); + if (t->error != -E_WRITE_COMMON_EOF + && t->error != -E_BTR_EOF) { + PARA_ERROR_LOG("%s: %s\n", t->status, + para_strerror(-t->error)); + if (ret >= 0) + ret = t->error; + } + } + } out: for (i--; i >= 0; i--) { struct writer_node *wn = wns + i;