D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4243 - [snn.lib] setmode doesn't set stdin/stdout to binary
Summary: [snn.lib] setmode doesn't set stdin/stdout to binary
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL: http://www.digitalmars.com/d/archives...
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-27 15:32 UTC by Shin Fujishiro
Modified: 2021-03-17 14:23 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Shin Fujishiro 2010-05-27 15:32:13 UTC
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
--------------------
Comment 1 Johan Engelen 2016-01-13 00:04:45 UTC
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.
Comment 2 RazvanN 2021-03-17 14:23:09 UTC
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.