-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Add std::os::set_errno as a counterpart to std::os::errno #17265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
||
#[cfg(unix)] | ||
/// Returns the platform-specific value of errno | ||
pub fn errno() -> int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're at it, the return types of errno
on unix and windows should be the same, not different. Could you change windows to returning an int
as well? I think that most consider errno
as being a signed integer as opposed to an unsigned one.
Additionally, set_errno
for windows would be updated to take an int
instead of a uint
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those should be c_int and not int or uint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, they should not. We do not expose C types at the std layer where c_int
is a platform-specific definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
errno() is mostly (only?!) useful with the values in libc::consts::os::posix88 which are all c_int. If you don't want c_int in the stdlib then maybe the safe version of errno and set_errno should be moved to libc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to expose errno()
in std
as an int
, but have it be a wrapper around a c_int
-based errno()
in libc
, and then set_errno()
can go into libc
.
The reasoning is that reporting the errno
in error messages is not an uncommon thing, so having read-only access from std
makes sense. Setting errno
is much rarer, and presumably if you need that you're going to be doing other FFI work as well, so using libc
is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thestinger Right; that's exactly what I said.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Rust's int
type is ever smaller than a C compiler's int
when compiling for the same target, then either the C compiler is broken, or Rust is. More generally, under that circumstance, I think we'd have more issues than just errno
.
Given that, and since errno
is not defined to be any specific bit width but instead defined to be the C int
type, I think it's much more natural to expose errno
from std
as int
instead of trying to claim it's some particular bit width. Yes, it's not a perfect match, but it seems like a better choice than i32
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that my above comment is predicated on std
only exposing errno
as a read-only value, and libc
exposing errno
as a read/write value using c_int
, as stated in my previous comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A C compiler with a 32-bit int
type and 16-bit pointers is not "broken". The same applies to one with a 64-bit int
type and 32-bit pointers. If a compiler tied int
to general purpose register size, it would be 64-bit on x32 while pointers (and thus int
and uint
in Rust) are 32-bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not expose C types at the std layer
You're already doing this by re-exporting CString which takes c_char.
Some possibly relevant information about the current usage of
|
cc #16786 |
Closing due to inactivity, but feel free to reopen with a rebase! |
@alexcrichton I reopened this as PR #18642, which adds |
This pull request adds a
std::os::set_errno
function to allow rust to manipulate the thread'serrno
value. In my particular case, I am needing to do this when interacting with a c-library I am wrapping.Note I don't have rust building on a Windows platform currently so have been unable to test my implementation for
[cfg(windows)]