Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-03

TProcess on windows: incompatibility between poUsePipes and InheritHandles:=false

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Luca Olivetti

In order to use poUsePipes, InheritHandles must be true (see
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx) This is a limitation of the windows api, but I wonder if is there a workaround to avoid inheriting other handles.

Long story:
I need to spawn a program (relatively short lived) and capture its standard output/standard error.
The main program has various files open as well as some connected sockets (using synapse as the socket library).

In a thread I have a

while not terminated do
begin
   ....
   LocBarcode:=FChannel.RecvTerminated(-1,cr);
   ....
end;

(where FChannel is a TTcpBlockSocket, a synapse socket) and in the thread destructor I have

  Terminate;
  FChannel.AbortSocket;
  inherited Destroy;

so that the above RecvTerminated will exit with an error and the thread terminates cleanly.

The problem is that if the child process is still running, that doesn't work anymore, until the process terminates. That's surely because the process has inherited the socket, so I tried InheritHandles:=false, but I discovered that it precludes the use of poUsePipes.

My current workaround is to terminate the process before trying to destroy the thread, and that works, but I wonder if having unneeded handles in a child process could have other unintended consequences, so I'd like to know if is there a better workaround that allows to capture stdout/stderr while at the same time avoiding inheriting other handles. Possibly in a "generic" way, so that I don't need to have knowledge of which handles are currently opened.

Bye

Luca

Reply by email

Sven Barth
to Luca Olivetti
Luca Olivetti wrote 5 lines
In order to use poUsePipes, InheritHandles must be true (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx) This is a limitation of the windows api, but I wonder if is there a workaround to avoid inheriting other handles.

[snip]

Show quoted text 7 lines
My current workaround is to terminate the process before trying to destroy the thread, and that works, but I wonder if having unneeded handles in a child process could have other unintended consequences, so I'd like to know if is there a better workaround that allows to capture stdout/stderr while at the same time avoiding inheriting other handles. Possibly in a "generic" way, so that I don't need to have knowledge of which handles are currently opened.

I have no explicit solution for you, but a few links that I hope can help you further:

http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms724466%28v=vs.85%29.aspx http://support.microsoft.com/kb/315939/en-us

Regards,
Sven

Reply by email

Luca Olivetti
to Sven Barth

El 11/03/14 19:17, Sven Barth ha escrit:

Show quoted text 20 lines
On 11.03.2014 17:18, Luca Olivetti wrote: > In order to use poUsePipes, InheritHandles must be true > (see > http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx) > > This is a limitation of the windows api, but I wonder if is there a > workaround to avoid inheriting other handles. [snip] > My current workaround is to terminate the process before trying to > destroy the thread, and that works, but I wonder if having unneeded > handles in a child process could have other unintended consequences, so > I'd like to know if is there a better workaround that allows to capture > stdout/stderr while at the same time avoiding inheriting other handles. > Possibly in a "generic" way, so that I don't need to have knowledge of > which handles are currently opened. I have no explicit solution for you, but a few links that I hope can help you further: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx

What surprises me is that it says that handles by default are non-inheritable, that you have to explicitly set bInheritHandle to true in a SECURITY_ATTRIBUTES parameter when creating the handle. Yet, it seems that the socket is inherited even if there is no security_attributes/bInheritHandle anywhere in synapse code. Either that or the cause of what I observe is something else.

Note that previously I had a similar problem, see
http://bugs.freepascal.org/view.php?id=22271#c65861 but in that case I didn't need to capture stdout/stderr of the spawned process, so setting InheritHandles to false solved it.

Bye

Luca

Reply by email

Luca Olivetti
to Luca Olivetti

El 11/03/14 19:43, Luca Olivetti ha escrit:

Show quoted text 7 lines
> I have no explicit solution for you, but a few links that I hope can > help you further: > > http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx What surprises me is that it says that handles by default are non-inheritable

It turns out that sockets by default *are* inheritable, but that doesn't really work reliably, and at the same time you *cannot* stop them from being inheritable

http://stackoverflow.com/questions/12058911/can-tcp-socket-handles-be-set-not-inheritable

Now I know that windows has been designed by Vicky Pollard.

Bye

Luca

Reply by email

Luca Olivetti
to Luca Olivetti

El 13/03/14 00:21, Luca Olivetti ha escrit:

Show quoted text 17 lines
El 11/03/14 19:43, Luca Olivetti ha escrit: >> I have no explicit solution for you, but a few links that I hope can >> help you further: >> >> http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx > > What surprises me is that it says that handles by default are > non-inheritable It turns out that sockets by default *are* inheritable, but that doesn't really work reliably, and at the same time you *cannot* stop them from being inheritable http://stackoverflow.com/questions/12058911/can-tcp-socket-handles-be-set-not-inheritable Now I know that windows has been designed by Vicky Pollard.

Since, in this case, I have control over the spawned program, I just modified it to send its results to an UDP socket instead of standard output, passing the port to use as a command line argument, so I can avoid poUsePipes and set InheritHandles to false.
The workarounds in the link above can be used when you cannot modify the program.

Bye

Luca

Reply by email