randomplay 0.48 released

I’ve released randomplay 0.48. randomplay is my command-line ‘itch a scratch’ music player. It is most useful for maintaining a random shuffle over many sessions—for example, I use it to make sure I don’t ever hear the same song in any three month period.

The new version fixes a bug that prevented randomplay from advancing to the next track when the player subprocess itself spawned a child process (e.g., with ‘play’ which spawns ‘sox’). I use a bit of a hack to kill the child task and it’s children, but the standard way of doing this in perl—kill HUP => -$$ doesn’t seem to work when randomplay is called from a shell script and the child process’ output is redirected to null. Here’s the code in question (with the fix to kill children and grandchildren recursively):

 # KillAll recursively kills the request process ID and all of its children/grandchildren/etc. # This is a bit of a hack--there should be a better way to do this, but I haven't found one. # Normally, kill HUP => -$$ should do the job, except this doesn't work when randomplay itself # is called from a shell script and all output from child processes is redirected to null. # This subroutine assumes that shelling out to ps is going to work, which may not be totally # safe--at the very least, it reduces the portability of the script. # Any suggestions for a better way to do this are welcome. sub KillAll { my $pid = shift; local $SIG{HUP} = 'IGNORE'; # don't want to kill ourselves here--shouldn't happen, but just in case. if (open PS, "ps -o pid,ppid |") { eof PS; # Force ps to run now. Otherwise it would run at the first read operation. kill HUP => $pid; foreach my $line () { KillAll($1) if ($line =~ /^\s*(\d+)\s*(\d+)\s*$/ and ($2 eq $pid)); } close PS; } else { # if we can't read the process table, just try killing the child process group kill HUP => -$$; } } 

Thanks to Christopher Zimmermann for the patch to kill children recursively.


  1. Daniel Jacobowitz Jan 28

    It sounds like you don’t _have_ a child process group. Are you explicitly creating one before you exec the player? Perl function setpgrp.

  2. Adam Rosi-Kessel Jan 28

    Nope! That sounds like a good solution. I vaguely remember using setpgrp long ago, but I had forgotten that it could probably solve this problem. Thanks.

Leave a Reply

(Markdown Syntax Permitted)