diff --git a/configure.ac b/configure.ac index 66ed8ca0..8e4207b2 100644 --- a/configure.ac +++ b/configure.ac @@ -102,6 +102,18 @@ gt_TYPE_SSIZE_T # gnulib modules gl_INIT + +if test $ac_cv_lib_error_at_line = no; then + # This means that the error() function is not present in libc, so + # the one from gnulib will be used instead. This function precedes + # error messages it prints with the program name as returned by getprogname() + # call, instead of using the name set by set_program_name. + # Install workaround. + AC_DEFINE([ENABLE_ERROR_PRINT_PROGNAME],[1], + [Enable the use of error_print_progname to print program name with error messages. + See comment to function tar_print_progname in src/tar.c]) +fi + # paxutils modules tar_PAXUTILS diff --git a/src/tar.c b/src/tar.c index 9c939f39..721d7779 100644 --- a/src/tar.c +++ b/src/tar.c @@ -2666,7 +2666,28 @@ decode_options (int argc, char **argv) report_textual_dates (&args); } + +#ifdef ENABLE_ERROR_PRINT_PROGNAME +/* The error() function from glibc correctly prefixes each message it + prints with program_name as set by set_program_name. However, its + replacement from gnulib, which is linked in on systems where this + function is not available, prints the name returned by getprogname() + instead. Due to this messages output by tar subprocess (which sets its + program name to 'tar (child)') become indiscernible from those printed + by the main process. In particular, this breaks the remfiles01.at and + remfiles02.at test cases. + To avoid this, on such systems the following helper function is used + to print proper program name. Its address is assigned to the + error_print_progname variable, which error() then uses instead of + printing getprogname() result. + */ +static void +tar_print_progname (void) +{ + fprintf (stderr, "%s: ", program_name); +} +#endif /* Tar proper. */ @@ -2676,7 +2697,9 @@ main (int argc, char **argv) { set_start_time (); set_program_name (argv[0]); - +#ifdef ENABLE_ERROR_PRINT_PROGNAME + error_print_progname = tar_print_progname; +#endif setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE);