More fRustration.
So, last week I finally managed to get arglist parsing to work. I tried to take the next step, starting to implement the real code.
As no longer surprises me, I have failed. Since the C version did
some initialization before parsing the arglist, I started out to add
that. But that initialization is driven off what uname(3) calls
`machine
', the hardware platform architecture. So I went
looking for a Rust binding for uname(3).
I found two of them...sort of.
One of them is a crate uname
which contains a function
uname()
which returns a Result<Info>
.
uname::Info
is a struct containing String
s,
meaning that trying to use it on a system where the relevant strings
aren't UTF-8 must break somehow; the failure modes that seem likely to
me are (1) a panic, (2) a Result
containing an error
value, and (3) strings with non-UTF-8 octets mangled into something
else (most likely U+FFFD). None of these is acceptable. (In general,
that is. The last one would be acceptable for my particular use case,
because the strings I want to compare machine
against are
all ASCII and thus all UTF-8.)
So I went to the other one, libc::uname
. This one is
marked unsafe (I do not understand why) and, based on its documented
declaration (https://docs.rs/libc/latest/libc/fn.uname.html),
is a direct call to the C uname()
function. However, the
argument struct, utsname
, is documented as being made up
of a bunch of [c_char; 65]
s, whereas the Ubuntu I'm trying
to do this on says, in its uname(2) manpage, that
The length of the fields in the struct varies. Some operating systems or libraries use a hardcoded 9 or 33 or 65 or 257. Other systems use SYS_NMLN or _SYS_NMLN or UTSLEN or _UTSNAME_LENGTH.but it turns out, when I look under the hood, that it uses 65. My NetBSD machines use 256. Presumably other systems use yet other values. But Rust insists on 65. I can only infer that either the documentation lies or they don't care about portability off glibc/Linux, neither of which is good. (EDIT: In passing, on my dev machine, hostname(1) refuses to set certain hostnames, apparently including all non-ASCII ones (even if valid UTF-8) but also including some pure-ASCII ones. Contrastingly, sethostname(2) accepts a non-UTF-8 setting just fine.)
But the size Rust documents itself as using matches the system I'm developing on, so I tried to use it anyway.
I have failed. At first, I just wrote the code and added
use
s for libc::uname
and
libc::utsname
. This produced unresolved import
`libc`
. The help for this suggested adding extern crate
libc
, which looked plausible. So I did. This then complained
about a missing semicolon; apparently the `help' suggestion was
incomplete. So I added that too. Now I'm getting error[E0658]:
use of unstable library feature 'rustc_private': this crate is being
loaded from the sysroot, an unstable location; did you mean to load
this crate from crates.io via `Cargo.toml` instead?
.
Apparently you can't use libc unless you're using cargo. Which, of course, I'm not; as outlined over the last few weeks, I think it is a catastrophe waiting to happen.
At this point, I will take quite a bit of convincing to not call Rust a pretty much total fail. It appears to be more a tool for ramming its creators' religion down our collective throat than a useful language.