Rust: Windows 7: std::io::last_os_error is set after printing to stdout

Created on 7 Aug 2018  路  10Comments  路  Source: rust-lang/rust

This happens on Windows 7, cannot test on newer Windows.
Basically, something wrong happens with file handles when using the println! macro, not sure what exactly.

Minimal repro:

use std::io;
fn main() {
    println!("{:?}", io::Error::last_os_error());
    println!("{:?}", io::Error::last_os_error());
}

Actual output:

Os { code: 0, kind: Other, message: "Der Vorgang wurde erfolgreich beendet." }
Os { code: 6, kind: Other, message: "Das Handle ist ung眉ltig." }

Expected output:

Os { code: 0, kind: Other, message: "Der Vorgang wurde erfolgreich beendet." }
Os { code: 0, kind: Other, message: "Der Vorgang wurde erfolgreich beendet." }

Sorry for German localization in the error messages.

I noticed this because of some obscure behaviour in the windows API (a function returned != 0, but LastError wasn't set accordingly).

cc @retep998
cc https://github.com/retep998/winapi-rs/issues/658

C-bug O-windows T-libs

Most helpful comment

Windows system functions generally guarantee that they will set the last error when they fail, but offer no guarantees as to the state of the last error when they succeed (some may clear the error, some may leave it alone, some may change it).

The only action that Rust could take here is for any libstd function that calls system functions to clear the last error when it returns success.

All 10 comments

Additional info: I am using stable rust 1.28

Works for me on Windows 10:

  • 1.27.2
  • 1.28
  • beta
  • nightly

Can't test Windows 7 :( sorry

Does it occur more than once? (e.g. can you reproduce it?)

Yes, this happens every time I execute the program

("Das Handle ist ung眉ltig" means "The handle is invalid" in English)

Windows system functions generally guarantee that they will set the last error when they fail, but offer no guarantees as to the state of the last error when they succeed (some may clear the error, some may leave it alone, some may change it).

The only action that Rust could take here is for any libstd function that calls system functions to clear the last error when it returns success.

@sfackler I'm using git bashon windows 7 (which is just the mingw terminal if I'm not mistaken).
Probably that resolves to Pipe in the call you mentioned.

Maybe we should SetLastError(0) in that branch?

I understand this is not really a bug (if the function errors, we have a pipe, otherwise a terminal), but perhaps we can reduce the confusion if we reset the OS error in the former case.

Personally I'd rather that Rust offer no guarantees about the result of Error::last_os_error() when called after any libstd function that calls some system function. It should only be used directly after calling a system function yourself and only when that function is documented to have set the last error.

There is a case to be made here about documenting this though.

Triage:

There is a case to be made here about documenting this though.

I agree, though we should get @rust-lang/libs signoff before re-categorizing this bug.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Robbepop picture Robbepop  路  3Comments

pedrohjordao picture pedrohjordao  路  3Comments

mcarton picture mcarton  路  3Comments

modsec picture modsec  路  3Comments

jmegaffin picture jmegaffin  路  3Comments