setmode(stdout, O_BINARY) does not set stdout to binary mode. setmode surely works for fopen'ed files, but does not work for standard file streams. -------------------- test1.d import std.c.stdio; extern(C) int setmode(int, int); enum O_BINARY = 0x8000; void main() { string s = "\n"; // write to stdout setmode(stdout._file, O_BINARY); // set to binary mode fwrite(s.ptr, 1, s.length, stdout); // write to test.dat auto f = fopen("test.dat", "w"); // open in text mode setmode(f._file, O_BINARY); // set to binary mode fwrite(s.ptr, 1, s.length, f); fclose(f); } -------------------- >dmd -run test1 | od -c 0000000 \r \n <-- written in text mode 0000002 >od -c test.dat 0000000 \n <-- okay 0000001 -------------------- This also does not work: -------------------- test2.d import std.c.stdio; enum _IOTRAN = 0x100; // taken from DMC include/stdio.h void main() { string s = "\n"; stdout._flag &= ~_IOTRAN; fwrite(s.ptr, 1, s.length, stdout); } -------------------- >dmd -run test2 | od -c 0000000 \r \n <-- written in text mode 0000002 -------------------- Only this works: -------------------- test3.d import std.c.stdio; void main() { string s = "\n"; __fhnd_info[stdout._file] &= ~FHND_TEXT; fwrite(s.ptr, 1, s.length, stdout); } -------------------- >dmd -run test3 | od -c 0000000 \n <-- okay, written in binary mode 0000001 --------------------
On Windows, with DMD, the following code works to set stdout to binary mode: version(Windows) { // See Phobos' stdio.File.rawWrite { import std.stdio; immutable fd = fileno(stdout.getFP()); setmode(fd, _O_BINARY); version(CRuntime_DigitalMars) { import core.atomic : atomicOp; atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT); } } } Note the extra CRuntime_DigitalMars bit.
I cannot reproduce the initial example (and it doesn't look like it has anything to do with the dmd component, but rather with phobos) and an working alternative has been proposed. Closing as WORKSFORME.