Re: exec/3 and waiting for processes...

From: Joachim Schimpf <j.schimpf_at_icparc.ic.ac.uk>
Date: Tue 19 Nov 2002 12:25:49 PM GMT
Message-ID: <3DDA2DCD.94DE0062@icparc.ic.ac.uk>
Sebastian Sardina wrote:
> 
> Hello, I have a problem with spaning unix processes from ECLIPSE and
> recovering its resources later:
> 
> As the doc says, it's recomendend to do a wait/2 for each exec/3 because
> otherwise the process is finished but still "there".
> wait/2 in fact does that, waits until the process is finished and frees
> its resources after that.
> 
> Now as the doc points out, if a signal arrives while "waiting" an error
> occurrs (from wait/2 doc):
> 
> Error:
>       [eclipse]: exec(bc, [], A), wait(P, S).
>       Signal 23            % sending a signal to this process
>       system interface error: Interrupted system call
>                                           in wait(_g50, _g42)
>       [eclipse]:
> 
> the problem is that my application may receive a io signal at any point
> that I handle with an interrupt handler and an even hanlder. If I'm very
> lucky and the interrupts arrives when I'm in the process of waiting for
> some process that I ran with exec/3, then my program aborts!!
> 
> Anybody knows how to handle this? either I need to avoid wait/2 to give
> me an error if an interrupt arrives or I need to issue a wait/2 only
> after I know the process is totally finished (since waiting 1 second can
> be too much and an interrupt may arrive!). I couldn't find anything to
> "learn" whether a unix process is finished.


In many cases you will have some communication between the Eclipse
process and the sub-process, and you know when the sub-process is
finished. In the above example with bc (which is a unix calculator
program) this could look like:

main :-
	% start the subprocess
	exec(bc, [In,Out], PID),

	% send one query and read the answer
        writeln(In, "21376123*23186238"), flush(In),
        read_string(Out, end_of_line, _, Answer1), writeln(Answer1),

	% send another query and read the answer
        writeln(In, "123233/3312"), flush(In),
        read_string(Out, end_of_line, _, Answer2), writeln(Answer2),

	% close the other process' stdin:
	% this will cause it to terminate
        close(In),

	% make sure it has terminated properly
        wait(PID, Status).

In this case, wait/2 will not really need to wait.


But I agree with your general point that wait/2 should not
abort when interrupted. You can achieve this by modifying
the corresponding error handler as follows:

:- set_error_handler(170, my_system_error_handler/2).

my_system_error_handler(E, Goal) :-
	(
	    errno_id("Interrupted system call"),
	    restartable_goal(Goal)
	->
	    call(Goal)
	;
	    error(default(E), Goal)
	).
	
restartable_goal(wait(_,_)).



-- 
 Joachim Schimpf              /             phone: +44 20 7594 8187
 IC-Parc, Imperial College   /            mailto:J.Schimpf@ic.ac.uk
 London SW7 2AZ, UK         /    http://www.icparc.ic.ac.uk/eclipse
Received on Tue Nov 19 12:28:15 2002

This archive was generated by hypermail 2.1.8 : Wed 16 Nov 2005 06:07:18 PM GMT GMT