Subject: Re: OpenSSH and WinCVS in Windows 9x
From: Laurent Pinchart <[email-masked]>
To: egor duda <[email-masked]>
Cc: [email-masked]
Date: Thu, 8 Aug 2002 19:32:25 +0200

> Cygwin uses the following code to periodically probe pipe status:
>
> (file select.cc)
> static int
> peek_pipe (select_record *s, bool from_select)
> ....
> else if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
>    {
>      select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
>      n = -1;
>    }
> ....
>
> Peeking into pipe for zero bytes is quite unusual, so win98 may return
> something wrong here. You can probably attach with a debugger or strace
> to running ssh instance and look what's going on. Maybe we'd have to
> probe for at least 1 byte here. Or maybe use some totally different
> approach to detect if peer's end of pipe is closed.

I recompiled openssh with debugging information (will probably have to 
recompile the cygwin librairies too). I have been able to attach gdb to the 
running ssh process, but I then experience segfaults when I enter the 
password at the ssh prompt.

Never mind, I added debug statements to the ssh code. From what I understand, 
here's what happens.

WinCVS:

CreatePipe is called to create an input (ssh -> WinCVS) and an output (WinCVS 
-> ssh) pipe. Both pipe are not inheritable. The input pipe write end is then 
duplicated into an inheritable handle (DuplicateHandle), and the original 
handle is closed. The same operation is performed on the output pipe read 
end.

CreateProcess is then called to create the ssh process, with stdin and stdout 
redirected to the ouput pipe read handle (inheritable) and the input pipe 
read handle (inheritable) respectively.

The input pipe write end and the output pipe read end, which are unneeded by 
WinCVS, are then closed.

The remaining handles are then converted to file descriptors 
(_open_osfhandle), which are in turn converted to stream pointers (fdopen). 
Those pointers are used for all the communication with the cvs server through 
ssh.

When WinCVS has finished the communication with the server, it closes the 
handles and waits for the child (ssh) to finish.

SSH:

stdin and stdout are duplicated, and the duplications are set to non blocking 
mode.

ssh performs various operations, opens a session, receives and sends requests, 
and then waits using select on both the connection socket (file handle 3) and 
the duplicate stdin (file handle 4) for read events. That's when WinCVS calls 
fclose on the stream descriptor which is mapped to the output pipe write 
handle.

select doesn't return. On win2k, it does return with a value equal to 1, and 
the bit corresponding to the duplicate stdin is set in the readfds.

It seems that the problem isn't in WinCVS nor in ssh but in the cygwin select 
implementation.

Once again, help will be appreciated :-)

Laurent Pinchart

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/