perl hangs on exit (after closing a filehandle)

ipc, linux, perl, pipe, process

Solution

`undef $file` removes a reference count from the filehandle and makes it eligible for garbage collection. If `$file` is a handle to a regular file and there are no other references to the filehandle anywhere else, it should work as documented in `IO::File`. In this case `$file` is a handle to a shell command, and there may be some other internal references to the filehandle that keep it from getting destroyed. Using `$file->close` is safer and makes your intent much clearer.

To kill off the command when closing the filehandle doesn't work, you need the process ID. If you invoked the command like

my ($file,$pid);
$pid = open($file, "| some_command >> /dev/null 2>&1");

then you could

kill 'TERM',$pid;

at the end of your program. I don't know how to extract the process ID from the return value of `IO::File::new` though.

Problem

I've got a function that does (in short): ``` my $file = IO::File->new("| some_command >> /dev/null 2>&1") or die "cannot open some_command for writing: $!\n"; ... undef $file; ``` Right now I'm not even writing anything to `$file`. Currently there are no other operations on `$file` at all. When I run the program, it doesn't exit properly. I see that handle is closed, but my program is still waiting for the process to close. Captured with `strace`: ``` close(6) = 0 rt_sigaction(SIGHUP, {SIG_IGN}, {SIG_DFL}, 8) = 0 rt_sigaction(SIGINT, {SIG_IGN}, {SIG_DFL}, 8) = 0 rt_sigaction(SIGQUIT, {SIG_IGN}, {SIG_DFL}, 8) = 0 wait4(16861, ^C <unfinished ...> ``` I don't see this problem if I open the same process for reading. What do I have to do to make the program to exit? Edit: Suggestions so far were to use the Expect library or to finish the input stream via ctrl+d. But I do not want to interact with the program in any way at this point. I want it to finish exactly now without any more IO going on. Is that possible?

Original source