{"id":125,"date":"2005-11-04T14:51:00","date_gmt":"2005-11-04T14:51:00","guid":{"rendered":"http:\/\/adam.rosi-kessel.org\/weblog\/free_software\/code\/randomplay_0.48_released.html"},"modified":"-0001-11-30T00:00:00","modified_gmt":"1970-01-01T05:00:00","slug":"randomplay_048_released","status":"publish","type":"post","link":"http:\/\/adam.rosi-kessel.org\/weblog\/2005\/11\/04\/randomplay_048_released","title":{"rendered":"randomplay 0.48 released"},"content":{"rendered":"<p> I&#8217;ve released <a href=\"http:\/\/adam.rosi-kessel.org\/weblog\/free_software\/code\/randomplay.html\">randomplay 0.48<\/a>. <a href=\"http:\/\/adam.rosi-kessel.org\/weblog\/free_software\/code\/randomplay.html\">randomplay<\/a> is my command-line &#8216;itch a scratch&#8217; music player. It is most useful for maintaining a random shuffle over many sessions&#8212;for example, I use it to make sure I don&#8217;t ever hear the same song in any three month period. <\/p>\n<p> 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 &#8216;play&#8217; which spawns &#8216;sox&#8217;). I use a bit of a hack to kill the child task and it&#8217;s children, but the standard way of doing this in perl&#8212;kill HUP => -$$ doesn&#8217;t seem to work when randomplay is called from a shell script and the child process&#8217; output is redirected to null. Here&#8217;s the code in question (with the fix to kill children and grandchildren recursively): <\/p>\n<p><pre> <font color=\"#444444\"># 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. <\/font><strong>sub<font color=\"ff0000\"> KillAll<\/font> {<\/strong> <strong>my<\/strong> <font color=\"#2040a0\">$pid<\/font> = <font color=\"a52a2a\"><strong>shift<\/strong><\/font>; <strong>local<\/strong> <font color=\"#2040a0\">$SIG<\/font><font color=\"4444FF\"><strong>{<\/strong><\/font>HUP<font color=\"4444FF\"><strong>}<\/strong><\/font> = <font color=\"#008000\">'IGNORE'<\/font>; <font color=\"#444444\"># don't want to kill ourselves here--shouldn't happen, but just in case. <\/font><strong>if<\/strong> <font color=\"4444FF\"><strong>(<\/strong><\/font><font color=\"a52a2a\"><strong>open<\/strong><\/font> PS, <font color=\"#008000\">\"ps -o pid,ppid |\"<\/font><font color=\"4444FF\"><strong>)<\/strong><\/font> <font color=\"4444FF\"><strong>{<\/strong><\/font> <font color=\"a52a2a\"><strong>eof<\/strong><\/font> PS; <font color=\"#444444\"># Force ps to run now. Otherwise it would run at the first read operation. <\/font><font color=\"a52a2a\"><strong>kill<\/strong><\/font> HUP => <font color=\"#2040a0\">$pid<\/font>; <strong>foreach<\/strong> <strong>my<\/strong> <font color=\"#2040a0\">$line<\/font> <font color=\"4444FF\"><strong>(<\/strong><\/font><ps><font color=\"4444FF\"><strong>)<\/strong><\/font> <font color=\"4444FF\"><strong>{<\/strong><\/font> KillAll<font color=\"4444FF\"><strong>(<\/strong><\/font><font color=\"#2040a0\">$1<\/font><font color=\"4444FF\"><strong>)<\/strong><\/font> <strong>if<\/strong> <font color=\"4444FF\"><strong>(<\/strong><\/font><font color=\"#2040a0\">$line<\/font> =~<font color=\"b000d0\"> \/^\\s*(\\d+)\\s*(\\d+)\\s*$\/<\/font> <strong>and<\/strong> <font color=\"4444FF\"><strong>(<\/strong><\/font><font color=\"#2040a0\">$2<\/font> <strong>eq<\/strong> <font color=\"#2040a0\">$pid<\/font><font color=\"4444FF\"><strong>)<\/strong><\/font><font color=\"4444FF\"><strong>)<\/strong><\/font>; <font color=\"4444FF\"><strong>}<\/strong><\/font> <font color=\"a52a2a\"><strong>close<\/strong><\/font> PS; <font color=\"4444FF\"><strong>}<\/strong><\/font> <strong>else<\/strong> <font color=\"4444FF\"><strong>{<\/strong><\/font> <font color=\"#444444\"># if we can't read the process table, just try killing the child process group <\/font><font color=\"a52a2a\"><strong>kill<\/strong><\/font> HUP => -<font color=\"#2040a0\">$$;<\/font> <font color=\"4444FF\"><strong>}<\/strong><\/font> <font color=\"4444FF\"><strong>}<\/strong><\/font> <\/pre>\n<\/p>\n<p> Thanks to Christopher Zimmermann for the patch to kill children recursively. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve released randomplay 0.48. randomplay is my command-line &#8216;itch a scratch&#8217; music player. It is most useful for maintaining a random shuffle over many sessions&#8212;for example, I use it to make sure I don&#8217;t ever hear the same song in any three month period. The new version fixes a bug that prevented randomplay from advancing [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[17],"tags":[],"_links":{"self":[{"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/posts\/125"}],"collection":[{"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/comments?post=125"}],"version-history":[{"count":0,"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/posts\/125\/revisions"}],"wp:attachment":[{"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/media?parent=125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/categories?post=125"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/adam.rosi-kessel.org\/weblog\/wp-json\/wp\/v2\/tags?post=125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}