[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: dd hangs with SIGINT
From: |
Bruno Haible |
Subject: |
Re: dd hangs with SIGINT |
Date: |
Wed, 6 Apr 2005 21:24:11 +0200 |
User-agent: |
KMail/1.5 |
Guillaume Chazarain wrote:
> As it prints a message for the first time, it has to
> initialize gettext, and I'm not sure this qualifies for the "do as
> little as possible in a signal handler" rule.
I agree. The list of guaranteed async-safe function calls on POSIX systems
is listed at
http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03
fprintf() is not part of it. gettext() neither, nor are the calls made
by gettext(), namely malloc(), free(), tsearch(), mmap(). So it would seem
advisable to pre-fetch the translations before the SIGINT happens. Untested
patch is appended. Unfortunately it forces to remove ngettext() calls, which
is bad for plural handling. Also you need to check the quote() call whether
it avoids calling malloc...
Bruno
*** dd.c.bak 2005-04-06 20:39:58.000000000 +0200
--- dd.c 2005-04-06 21:08:58.000000000 +0200
***************
*** 476,481 ****
--- 476,511 ----
return (i & (i - 1)) != 0;
}
+ /* Pre-translated strings, to avoid gettext() calls during signal handler. */
+ static const char *msg_records_in;
+ static const char *msg_records_out;
+ static const char *msg_truncated;
+ static const char *msg_truncated_plural;
+ static const char *msg_copied;
+ static const char *msg_copied_plural;
+ static const char *msg_infinity;
+ static const char *msg_seconds;
+ static const char *msg_seconds_plural;
+ static const char *msg_closing_input;
+ static const char *msg_closing_output;
+
+ static void
+ preinit_before_signal (void)
+ {
+ msg_records_in = _("%s+%s records in\n");
+ msg_records_out = _("%s+%s records out\n");
+ msg_truncated = _("truncated record");
+ msg_truncated_plural = _("truncated records");
+ msg_copied = _("%s byte (%s) copied");
+ msg_copied_plural = _("%s bytes (%s) copied");
+ msg_infinity = _("Infinity");
+ msg_seconds = _(", %g second, %s/s\n");
+ msg_seconds_plural = _(", %g seconds, %s/s\n");
+ msg_closing_input = _("closing input file %s");
+ msg_closing_output = _("closing output file %s");
+ }
+
+ /* Called from signal handler. */
static void
print_stats (void)
{
***************
*** 488,504 ****
double delta_s;
char const *bytes_per_second;
! fprintf (stderr, _("%s+%s records in\n"),
umaxtostr (r_full, buf[0]), umaxtostr (r_partial, buf[1]));
! fprintf (stderr, _("%s+%s records out\n"),
umaxtostr (w_full, buf[0]), umaxtostr (w_partial, buf[1]));
if (r_truncate > 0)
{
fprintf (stderr, "%s %s\n",
umaxtostr (r_truncate, buf[0]),
(r_truncate == 1
! ? _("truncated record")
! : _("truncated records")));
}
if (status_flags & STATUS_NOXFER)
--- 518,534 ----
double delta_s;
char const *bytes_per_second;
! fprintf (stderr, msg_records_in,
umaxtostr (r_full, buf[0]), umaxtostr (r_partial, buf[1]));
! fprintf (stderr, msg_records_out,
umaxtostr (w_full, buf[0]), umaxtostr (w_partial, buf[1]));
if (r_truncate > 0)
{
fprintf (stderr, "%s %s\n",
umaxtostr (r_truncate, buf[0]),
(r_truncate == 1
! ? msg_truncated
! : msg_truncated_plural));
}
if (status_flags & STATUS_NOXFER)
***************
*** 508,515 ****
since that makes it easy to use SI abbreviations. */
fprintf (stderr,
! ngettext ("%s byte (%s) copied",
! "%s bytes (%s) copied", w_bytes == 1),
umaxtostr (w_bytes, buf[0]),
human_readable (w_bytes, buf[1], human_opts, 1, 1));
--- 538,544 ----
since that makes it easy to use SI abbreviations. */
fprintf (stderr,
! w_bytes == 1 ? msg_copied : msg_copied_plural,
umaxtostr (w_bytes, buf[0]),
human_readable (w_bytes, buf[1], human_opts, 1, 1));
***************
*** 524,548 ****
else
{
delta_s = 0;
! sprintf (buf[1], "%s B", _("Infinity"));
bytes_per_second = buf[1];
}
fprintf (stderr,
! ngettext (", %g second, %s/s\n",
! ", %g seconds, %s/s\n", delta_s == 1),
delta_s, bytes_per_second);
}
static void
cleanup (void)
{
if (close (STDIN_FILENO) < 0)
error (EXIT_FAILURE, errno,
! _("closing input file %s"), quote (input_file));
if (close (STDOUT_FILENO) < 0)
error (EXIT_FAILURE, errno,
! _("closing output file %s"), quote (output_file));
print_stats ();
}
--- 553,577 ----
else
{
delta_s = 0;
! sprintf (buf[1], "%s B", msg_infinity);
bytes_per_second = buf[1];
}
fprintf (stderr,
! delta_s == 1 ? msg_seconds : msg_seconds_plural,
delta_s, bytes_per_second);
}
+ /* Called from signal handler. */
static void
cleanup (void)
{
if (close (STDIN_FILENO) < 0)
error (EXIT_FAILURE, errno,
! msg_closing_input, quote (input_file));
if (close (STDOUT_FILENO) < 0)
error (EXIT_FAILURE, errno,
! msg_closing_output, quote (output_file));
print_stats ();
}
***************
*** 1525,1530 ****
--- 1554,1560 ----
#endif
}
+ preinit_before_signal ();
install_handler (SIGINT, interrupt_handler);
install_handler (SIGQUIT, interrupt_handler);
install_handler (SIGPIPE, interrupt_handler);
- dd hangs with SIGINT, Guillaume Chazarain, 2005/04/01
- Re: dd hangs with SIGINT, Paul Eggert, 2005/04/04
- Re: dd hangs with SIGINT, Guillaume Chazarain, 2005/04/04
- Re: dd hangs with SIGINT, Guillaume Chazarain, 2005/04/06
- Re: dd hangs with SIGINT,
Bruno Haible <=
- Re: dd hangs with SIGINT, Jim Meyering, 2005/04/07
- Re: dd hangs with SIGINT, Guillaume Chazarain, 2005/04/07
- Re: dd hangs with SIGINT, Jim Meyering, 2005/04/07
- Re: dd hangs with SIGINT, Guillaume Chazarain, 2005/04/07
- Re: dd hangs with SIGINT, Jim Meyering, 2005/04/07
- Re: dd hangs with SIGINT, Guillaume Chazarain, 2005/04/08
- Re: dd hangs with SIGINT, Paul Eggert, 2005/04/07
- Re: dd hangs with SIGINT, Andreas Schwab, 2005/04/07
- Re: dd hangs with SIGINT, Bruno Haible, 2005/04/08
- Re: dd hangs with SIGINT, Guillaume Chazarain, 2005/04/08