bucky has asked for the wisdom of the Perl Monks concerning the following question:

**this is NOT an advertisement** I really my Slimp3 player. It's an MP3 player device that plays streams coming from my server. www.slimp3.com They say that it plays OGG formatted files and I located the code. It looks like:
my $fh = FileHandle-new(); $fh->open("ogg123... | lame... &"); ... #finally $fh->close()
So here's the problem. OGG123 starts 3 processes and lame starts one. When the close is initiated, only lame is terminated. The remaining OGG123 instances remain. Since I'm running this on a 500mhz machine I run out of jiuce too soon. I'm using perl v5.6.1 and slackware 8.1. The latest OGG and lame packages too. (the close is issued when the track finishes playing, the user presses stop; next or previous.) HELP!!!

Replies are listed 'Best First'.
Re: FileHandle->close() is not closing everything
by Abigail-II (Bishop) on Mar 28, 2003 at 00:06 UTC
    If this is really the code you are executing, then no additional process is started. You're just opening a file with a very strange name.

    However, I expect your real code does a pipe-open, and reads from it (or writes to it). A pipe-open is a complex process. A pipe is opened, the process forks, parent and child each close one end of the pipe (leaving a uni-directional pipe), and then the child does an exec. If you call close, Perl closes the pipe. It doesn't send a TERM signal, or something else to the child process. It's up to the child process how to deal with a closed pipe (most programs will exit, but some won't).

    So you'll have to fix the OGG123 program, or do the termination from your program after the close yourself.

    Abigail

      Here's the actual code for the OPEN:
      } elsif (SliMP3::Info::isOgg($fullpath) && SliMP3::Prefs::get("transc +ode-ogg")) { # Note we have to put the path in double quotes so that # spaces in file names are handled properly. my $ogg_cmd = "ogg123 -q -p 5 -d raw -f - \"$filepath\""; my $lame_cmd = "lame -x -r - - &"; $client->mp3filehandle( FileHandle->new() ); $client->mp3filehandle->open("$ogg_cmd | $lame_cmd |");
      Here's the actual code for the CLOSE:
      # close the previous handle to prevent leakage. if (defined $client->mp3filehandle()) { $client->mp3filehandle->close(); $client->mp3filehandle(undef); $client->mp3filehandleIsSocket(0); }
      The OPEN is called when PLAY, NEXT, PREVIOUS is called. OPEN, always calls CLOSE to make sure that there are no running processes. So the code really does work that way. But I see your point about TERM.
        Well, it's doing just as I said, a pipe-open. A close() closes the pipe. Whether the program on the other ends terminate is up to said program, Perl will not take any attempts to kill the program off.

        Abigail

Re: FileHandle->close() is not closing everything
by tachyon (Chancellor) on Mar 27, 2003 at 23:37 UTC

    The problem is that the file handle you are creating is just to a system process consisting of ogg123 piped to lame. I suspect that something like this may work:

    my $ogg_fh = new FileHandle "ogg123...."; my $lame_fh= new FileHandle "lame....."; my $pipe = new FileHandle "$ogg_fh | $lame_fh &"; .... # now close your pipe and then lame and ogg123 # you should be able to just undef the handles # as this should call close automatically $pipe->close(); $lame_fh->close(); $ogg_fh->close();

    Completetely untested but it makes vague sense to me.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      I suspect that something like this may work
      Ah, no, that won't work. I did come up with a method that might work though.
Re: FileHandle->close() is not closing everything
by runrig (Abbot) on Mar 27, 2003 at 23:47 UTC
    $fh->open("ogg123... | lame... &");
    Uhh, that's a very odd file name you have there. I don't think you're doing what you think you're doing. You should check the status of your open, and include the $! variable in any message if the open fails. See the open documentation for samples (or 'perldoc -f open'). (update: I realize its a FileHandle object, but the open method is just a front end to the open function).
      Amazingly enough, it works. What's not working is the close. The close() does not tear down ALL of the processes.
        Amazingly enough, it works
        Not really, according to your reply to Abigail-II below, you are doing a pipe open. The above code is not doing that. See my reply elsewhere for a link to something which might work for you.