--- dd.c.orig Tue Apr 10 16:07:07 2007 +++ dd.c Tue Apr 10 16:11:02 2007 @@ -150,6 +150,12 @@ static unsigned char *ibuf; /* input buffer pointer */ static unsigned char *obuf; /* output buffer pointer */ +/* Constants used to store the strings returned by gettext() in main(). */ +char *instr; +char *outstr; +char *truncstr; + + /* This is an EBCDIC to ASCII conversion table */ /* from a proposed BTL standard April 16, 1979 */ @@ -482,6 +488,20 @@ trunc = 1; /* default: truncate output file */ trantype = SVR4XLATE; /* use SVR4 EBCDIC by default */ + /* signal handler structure for SIGINT */ + struct sigaction int_handler; + + /* signal handler structure for SIGUSR1 */ + struct sigaction usr_handler; + + /* + Since gettext() is not async-thread-safe, we need to call + it to localize strings prior to enabing the signal handlers. + */ + instr = gettext("%llu+%llu records in\n"); + outstr = gettext("%llu+%llu records out\n"); + truncstr = gettext("%llu truncated record(s)\n"); + /* Parse command options */ (void) setlocale(LC_ALL, ""); @@ -872,13 +892,20 @@ exit(2); } - /* Enable a statistics message on SIGINT */ - #ifndef STANDALONE - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - { - (void) signal(SIGINT, term); - } + + /* A SIGINT signal will cause dd to print statistics to stderr and exit. */ + int_handler.sa_handler = term; + int_handler.sa_flags = SA_RESTART; + (void) sigfillset(&int_handler.sa_mask); + (void) sigaction(SIGINT, &int_handler, NULL); + + /* A SIGUSR1 signal will cause dd to print statistics to stderr. */ + usr_handler.sa_handler = stats; + usr_handler.sa_flags = SA_RESTART; + (void) sigfillset(&usr_handler.sa_mask); + (void) sigaction(SIGUSR1, &usr_handler, NULL); + #endif /* Skip input blocks */ @@ -1796,11 +1823,18 @@ static void stats() { - (void) fprintf(stderr, gettext("%llu+%llu records in\n"), nifr, nipr); - (void) fprintf(stderr, gettext("%llu+%llu records out\n"), nofr, nopr); - if (ntrunc) { - (void) fprintf(stderr, - gettext("%llu truncated record(s)\n"), ntrunc); - } + char ibuf[30]; + char obuf[30]; + char tbuf[30]; + + snprintf(ibuf, sizeof(ibuf), instr, nifr, nipr); + write(STDERR_FILENO, ibuf, strlen(ibuf)); + + snprintf(obuf, sizeof(obuf), outstr, nofr, nopr); + write(STDERR_FILENO, obuf, strlen(obuf)); + + if (ntrunc) { + snprintf(tbuf, sizeof(tbuf), truncstr, ntrunc); + write(STDERR_FILENO, tbuf, strlen(tbuf)); + } } -