7

I am trying to execute a process using proc_open. The I/O for the process is handled by the pipes !!

$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("pipe", "w")
);

Now, as it happens, sometimes the "c program" that I have opened does get stuck, and I have added a max_time_limit check which would forcibly shut down the process. I have added callback function -- namely onExit -- (using "call_user_function") to process the information whenever the "process exits" in a valid manner or by force.

In the "exit" function, I am closing the i/o pipes

 foreach ($pipes as $pipe) {
    fclose($pipe);
 }

The above works perfectly fine if the process has had a valid exit. However, in the case when I forcibly killed my process, I called proc_terminate to do so. I understand that the termination of process would also go ahead and close any I/O pipes, but the problem is that due to callback, my "onExit" function process always gets called (and this is the way I want it to be...as I need to do some more processing). Now, in this case, as I try to close the pipes, I get the following error:

fclose(): 18 is not a valid stream resource 

I tried using "ftell" to check whether the pipe is valid or not, but that too errored out. How do I check whether the pipes have already been closed or not??

Kapil Kaushik
  • 1,536
  • 4
  • 21
  • 28
  • Why are you closing those pipes? They would be closed automatically by the garbage collector at the termination of your script. – lanzz Jun 28 '12 at 15:07
  • @lanzz: I just wanted to make sure that this doesn't cause any chaos. – Kapil Kaushik Jun 29 '12 at 04:22
  • @Bart: Agree with you...wasn't paying attention to this earlier....have started doing that now....will also go and update all other questions...thanks ! – Kapil Kaushik Jun 29 '12 at 04:22
  • @lanzz That does not mean it's not good practice to clean up after yourself. – Bart Jun 29 '12 at 07:16
  • @Bart: It is not a good practice when it's introducing unnecessary complexity which is already duplicated in the gargage collector. Avoiding additional complexity (and the possibility of screwing up its logic) is one of the major reasons to use a garbage-collected language in the first place. – lanzz Jun 29 '12 at 07:54
  • 1
    @lanzz Surely the GC removes the necessity to do our own memory management and such. That does not prevent us from being able to boost performance and decrease memory waste by adding a few nicely positioned cleanup statements here and there. I've seen and used it (e.g. in a database conversion script where it was required to keep the memory at an acceptable level). In this case it probably won't matter though, I have to agree on that. – Bart Jun 29 '12 at 08:35

2 Answers2

15

What about checking if the resource is still a resource before trying to close it:

foreach ($pipes as $pipe) {
  // Finds whether a variable is a resource
  if(is_resource($pipe)) {
    fclose($pipe);
  }
}
Noah
  • 859
  • 7
  • 17
Bart
  • 2,062
  • 15
  • 19
-1

Or if your code is working properly and that's just a "warning" then close a warning with @. That's all.

@fclose($pipe);
Miro
  • 8,402
  • 3
  • 34
  • 72
Uzgraph
  • 27
  • 6