Skip to content

Instantly share code, notes, and snippets.

@leiless
Last active April 10, 2024 06:48

Revisions

  1. leiless revised this gist Apr 10, 2024. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions _setmode.rs
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,6 @@
    #[cfg(target_os = "windows")]
    extern {
    // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view=msvc-170
    // https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa298581(v=vs.60)
    fn _setmode(fd: std::os::raw::c_int, mode: std::os::raw::c_int) -> std::os::raw::c_int;
    // https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wwfcfxas(v=vs.100)
  2. leiless revised this gist Apr 10, 2024. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions _setmode.rs
    Original file line number Diff line number Diff line change
    @@ -12,6 +12,15 @@ pub const _O_TEXT: i32 = 0x4000;
    #[cfg(target_os = "windows")]
    pub const _O_BINARY: i32 = 0x8000;

    #[cfg(target_os = "windows")]
    pub const _O_WTEXT: i32 = 0x10000;

    #[cfg(target_os = "windows")]
    pub const _O_U16TEXT: i32 = 0x20000;

    #[cfg(target_os = "windows")]
    pub const _O_U8TEXT: i32 = 0x40000;

    #[cfg(target_os = "windows")]
    // Return the previous translation mode
    pub fn fd_setmode(fd: i32, mode: i32) -> anyhow::Result<i32> {
  3. leiless revised this gist Apr 10, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion _setmode.rs
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,7 @@ pub fn fd_setmode(fd: i32, mode: i32) -> anyhow::Result<i32> {
    let rc = unsafe { _setmode(c_int::from(fd), c_int::from(mode)) } as i32;
    if rc < 0 {
    let mut errno = c_int::default();
    let rc2 = unsafe { _get_errno(&mut errno) };
    let rc2 = unsafe { _get_errno(std::ptr::addr_of_mut!(errno)) };
    assert_eq!(rc2, 0, "_get_errno() failed, errno: {}", rc2);
    assert_ne!(errno, 0);
    Err(anyhow::anyhow!("_setmode() failed, errno: {}", errno))
  4. leiless created this gist Apr 10, 2024.
    41 changes: 41 additions & 0 deletions _setmode.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    #[cfg(target_os = "windows")]
    extern {
    // https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa298581(v=vs.60)
    fn _setmode(fd: std::os::raw::c_int, mode: std::os::raw::c_int) -> std::os::raw::c_int;
    // https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wwfcfxas(v=vs.100)
    fn _get_errno(p_value: *mut std::os::raw::c_int) -> std::os::raw::c_int;
    }

    #[cfg(target_os = "windows")]
    pub const _O_TEXT: i32 = 0x4000;

    #[cfg(target_os = "windows")]
    pub const _O_BINARY: i32 = 0x8000;

    #[cfg(target_os = "windows")]
    // Return the previous translation mode
    pub fn fd_setmode(fd: i32, mode: i32) -> anyhow::Result<i32> {
    use std::os::raw::c_int;

    let rc = unsafe { _setmode(c_int::from(fd), c_int::from(mode)) } as i32;
    if rc < 0 {
    let mut errno = c_int::default();
    let rc2 = unsafe { _get_errno(&mut errno) };
    assert_eq!(rc2, 0, "_get_errno() failed, errno: {}", rc2);
    assert_ne!(errno, 0);
    Err(anyhow::anyhow!("_setmode() failed, errno: {}", errno))
    } else {
    Ok(rc)
    }
    }

    fn main() -> anyhow::Result<()> {
    #[cfg(target_os = "windows")] {
    let prev_mode = fd_setmode(0, _O_BINARY)?;
    eprintln!("Previous stdin translation mode: {:#x}", prev_mode);
    Ok(())
    }

    #[cfg(not(target_os = "windows"))]
    std::compile_error!("unsupported target os");
    }