Terminal: A question (not an issue) about ConPTY feature.

Created on 30 Aug 2018  路  5Comments  路  Source: microsoft/terminal

Hello and sorry for hijaking the "issues" thread for just asking a question about the new ConPTY feature.

On *nix, the openpty() function returns file descriptors to the PTY device, one descriptor for the PTY master (used by the terminal emulator), and one descriptor for the PTY slave (that is dup'ed for the console app that will be connected to the terminal). One can understand the descriptors as "handles" to the PTY channels.

However in the new Windows' ConPTY api, the CreatePseudoConsole() function takes as INPUT handles to (pre-created) in- and out- pipes that will basically play together the role of PTY master side, for input and output.
What I don't completely understand, is why it has been done like this, instead of having a function that retrieves handles for us (so, it would return HANDLEs by pointer), i.e. really "open" a PTY (note that we would then need to provide an optional LPSECURITY_ATTRIBUTES in that scenario).
Also, why wouldn't this (these?) handles be instead handles to the pseudo-files maintained by the condrv driver? (e.g. handle to some \Device\ConDrv\ScreenBuffer or Display? or to something else): This would allow the condrv driver to really act as the (kernel-mode side of) PTY driver (the user-mode side is conhost and is connected to the console app being run).

Issue-Question Product-Conpty

Most helpful comment

(Don't worry too much about using issues to start discussions - this is the best place to actually get our attention 馃槃 )

We debated a while about the pros and cons of having the API create the HANDLEs or having the caller create the HANDLEs. You're right that the *nix model would more accurately create the handles on behalf of the caller, but we found that we had a lot of partners who already had a pair of handles that they wanted to lug directly into conpty.

Say you had some network socket - by accepting HANDLEs as _In_ parameters, ConPTY can just read directly from the network socket and write directly too it, without the caller needing to spawn a thread to shuttle bytes from one handle to the next. If we created the handles for you, then there would NEED to be another thread connecting the two sets of pipes.

This also lets the caller make the handles however they want - I believe they could be handles to a file (though I haven't ever tried that), they can be named pipes, whatever you want.

Hopefully we'll have a sample out soon (cough @bitcrazed) that includes a dummy wrapper around CreatePseudoConsole that combines creating a pair of anonymous pipes and creating the pseudoconsole, and I expect that function to be basically what you're looking for in terms of openpty returning the handles to read/write.

These handles passed to CreatePseudoConsole are totally unrelated to ConDrv - condrv's handles are used to facilitate the Console API, which is supposed to be a commandline client API. These handles are on the other side of conhost, between conhost and the terminal app, without condrv being involved at all.

All 5 comments

(Don't worry too much about using issues to start discussions - this is the best place to actually get our attention 馃槃 )

We debated a while about the pros and cons of having the API create the HANDLEs or having the caller create the HANDLEs. You're right that the *nix model would more accurately create the handles on behalf of the caller, but we found that we had a lot of partners who already had a pair of handles that they wanted to lug directly into conpty.

Say you had some network socket - by accepting HANDLEs as _In_ parameters, ConPTY can just read directly from the network socket and write directly too it, without the caller needing to spawn a thread to shuttle bytes from one handle to the next. If we created the handles for you, then there would NEED to be another thread connecting the two sets of pipes.

This also lets the caller make the handles however they want - I believe they could be handles to a file (though I haven't ever tried that), they can be named pipes, whatever you want.

Hopefully we'll have a sample out soon (cough @bitcrazed) that includes a dummy wrapper around CreatePseudoConsole that combines creating a pair of anonymous pipes and creating the pseudoconsole, and I expect that function to be basically what you're looking for in terms of openpty returning the handles to read/write.

These handles passed to CreatePseudoConsole are totally unrelated to ConDrv - condrv's handles are used to facilitate the Console API, which is supposed to be a commandline client API. These handles are on the other side of conhost, between conhost and the terminal app, without condrv being involved at all.

Hopefully we'll have a sample out soon (cough @bitcrazed) that includes a dummy wrapper around CreatePseudoConsole that combines creating a pair of anonymous pipes and creating the pseudoconsole, and I expect that function to be basically what you're looking for in terms of openpty returning the handles to read/write.

Yes definitely this would provide for an implementation of openpty() in a way.

Thanks for your explanations!

I have a second question:
Why choosing a HRESULT return type for the ConPTY functions? This seems to be on odds with the other kernel32 functions (and the existing console API functions). Wouldn't a DWORD reporting the win32 last-error code be sufficient?

I serve at the pleasure of the API review board - it does seem that even BOOLs would be more stylistically consistent with kernel32, but I believe HRESULTs are the preferred way of returning error codes in newer Windows APIs.

Thanks for your questions @HBelusca - appreciate you reaching out. Closing this issue since there's no action to be taken.

Was this page helpful?
0 / 5 - 0 ratings