Writing binary data to Windows stdout

The C version of rsvg-convert would simply use the stdio.h functions, in particular fwrite(..., stdout), to write its PNG output; this worked on Windows just fine as in rsvg-convert foo.svg > foo.png.

The Rust version uses io::stdout(), and converts that to a raw HANDLE to wrap it with a gio::Win32OutputStream. However, this is causing Windows to mangle the binary data being written.

Do I need to do anything special to io::stdout() to write binary data to it under Windows?

It sounds like this is also a problem in Python because stdout seems to be opened for writing text. You might need to call the equivalent of Python's winrt.setmode() (_setmode() in C), but I wasn't able to find it in the winapi or libc crates.

1 Like

Thanks, reading the docs for that was interesting. Now I'm not convinced that setting the HANDLE to binary is something rsvg-convert would need to do, since it doesn't use msvcrt/winrt. As far as I can tell all that text/binary distinction is implemented at the C library level, but I'm not 100% sure yet.

The bug I'm tracking down is detailed in rsvg-convert on Windows mangles binary output to stdout (#812) · Issues · GNOME / librsvg · GitLab for if anyone is interested.

Summary: rsvg-convert foo.svg > foo.png corrupts the output, but rsvg-convert -o foo.png foo.svg works correctly. The only difference is in how the output stream is created.

Out of curiosity, is this specific to how Windows implements stdout/pipes or the implementation of > for a particular shell (e.g. msys, cmd.exe, or PowerShell)?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.