Matty wrote:
> Howdy,
> 
> Most Linux and BSD distributions ship with a version of dd that
> displays the status of a copy operation when a SIGUSR1 signal is
> received. For some reason /usr/bin/dd on Solaris hosts doesn't contain
> this capability (it has a signal handler for SIGINT which causes stats
> to be displayed, but the handler calls exit() after printing the
> statistics), and I would like to add it. After reading through the
> source code for dd.c, it looks like adding this support would be as
> simple as installing a signal handler for SIGUSR1, and having it call
> the function stats. I am attaching code (which I derived from the dd
> source code that comes with Fedora Core Linux) [1] to add this support
> to /usr/bin/dd, and have tested it on my build 54 machine. Would it be
> possible to integrate this or something similar to opensolaris
> (assuming this doesn't break some rule defined by the SUS or POSIX)?
> 
> Thanks,
> - Ryan
> -- 
> UNIX Administrator
> http://prefetch.net
> 
> [1]
> 
> /* Create a signal handler for SIGUSR1 so dd can display stats for
> active copies.*/
> struct sigaction sa;
> memset(&sa, 0, sizeof(sa));
> sa.sa_handler = stats;
> sa.sa_flags = SA_RESTART;
> sigemptyset(&sa.sa_mask);
> sigaction(SIGUSR1, &sa, 0);
> _______________________________________________
> request-sponsor mailing list
> request-sponsor at opensolaris.org

The code changes are obvious enough.  However, there exists a small
possibility of deadlock if the process receives a signal as
it is encountering errors or exiting, as neither fprintf and
gettext are async signal safe. If either routine holds a
lock when it is interrupted and then gets called again in
the signal handler, things can go badly awry.  We don't actually
deadlock (although perhaps we should), but output, etc, can get
rather garbled.

In general, a cleaner way to handle this is to block sigusr1 in the main
thread, and create a thread to handle the sigusr1 and sigint
synchronously using sigwait(2).  If sigint is caught, the
thread calls stats() and exits.  If sigusr1 is caught, the
thread calls stats() and then calls sigwait(2) again.

This is prob. overkill in this situation... since the main loop
will only do stdio just before exiting, it could set
signal handlers to SIG_IGN before doing any IO which should
prevent any problems from arising.


- Bart




-- 
Bart Smaalders                  Solaris Kernel Performance
barts at cyber.eng.sun.com              http://blogs.sun.com/barts

Reply via email to