What is equivalent to unbuffer for Windows?

Hi, according to this post , unbuffer connects to the command through a pseudo-terminal (pty), which forces the system to consider it as an interactive process, therefore it does not use any stdout buffering.

I would like to use this feature on Windows. Can I find out what is equivalent to unbuffer for Windows? Thanks.

+10
source share
3 answers

The behavior you describe is typical of applications that use runtime libraries for I / O. By default, most runtime libraries check if the descriptor is a character mode device, such as a console, and if so, they do not perform any buffering. (Ideally, the runtime library will handle the channel in the same way as the console, but most do not seem to.)

I do not know any reasonable way to make such an application think that it writes to the console when it actually writes to the channel.

Application: seven years later, Windows finally supports pseudo-consoles . If you are running Windows 10 v1809 or later, this new API should solve your problem.

On older versions of Windows, if you know how much data to expect, you could basically use the console API functions to create a console for the application you want to write to and then read the output from the console. But you cannot do it from Java, you need to write a C application to do it for you.

Similarly, in principle, presumably, it should be possible to write a device driver equivalent to the Unix pseudo-terminal, which acts as a channel but reports that it is a symbol mode device. But writing device drivers requires special experience, and they must be digitally signed, so if an existing product does not exist, this approach is unlikely to be feasible.

+3
source

I spent some time on this and succeeded. I found this blog while researching, and decided to go back and provide my solution to save the next guy for a while. I reply as a guest with a false letter, so I will not interact, but no additional information is required.

July 18 December 12 at 19:41 Harry Johnston wrote:

β€œBasically, if you know how much data to expect, you can use the console APIs to create a console for the application to write data to and then read the output from the console. But you can't do it from Java, you need to write a C application to do it for you. "

The fact is that there is already a utility that does this. It is written for a slightly different use, but it can be used to achieve the desired result. Its purpose is to allow a Windows console application to communicate with a Linux-style tty terminal. This is done by launching a hidden console and direct access to the console buffer. If you tried to use it, you would have failed. I was lucky, and I found that there are undocumented keys for this utility that will allow for simple, unbuffered output. Without switches, an error occurs - the output is not tty - when trying to transfer along the pipeline.

The utility is called winpty. You can get it here:

https://github.com/rprichard/winpty/releases

Undocumented keys are mentioned here:

https://github.com/rprichard/winpty/issues/103

I am using the MSYS2 version. You will need msys-2.0.dll to use it.

Just run:

 winpty.exe -Xallow-non-tty -Xplain your_program.exe | receive_unbuffered_output.exe 

-Xallow-non-tty , allow pipelined output

-Xplain will remove the added Linux terminal control codes (or -Xplain they are called)

Required Files:

 winpty.exe winpty-agent.exe winpty.dll msys-2.0.dll 

winpty-debugserver.exe - not required

+7
source

Disclaimer: My answer only applies to executable files compiled using MSVC.

The buffering policy is encoded inside the Microsoft CRT runtime library. You can find out the details here . This article suggests using console descriptors and managing console buffers to receive unbuffered output.

However, in the Microsoft C Runtime environment, there is an undocumented function for inheriting files with some internal flags directly from its parent process using the lpReserved2 and cbReserved2 fields of the cbReserved2 structure. You can find the details in the crt source code provided by Microsoft Visual Studio. Or find something like posfhnd on GitHub.

We can use this undocumented function to provide a stream handle and specify FOPEN | FDEV FOPEN | FDEV flags the child process to trick the child process by handling the same path as the FILE_TYPE_CHAR handle.

I have a working Python3 script to demonstrate this method.

+2
source

Source: https://habr.com/ru/post/920652/


All Articles