
Relibc: C Library in Rust for Redox and Linux - dralley
https://github.com/redox-os/relibc
======
dikaiosune
Awesome! It looks like they have some tests in the directory -- I'd be curious
whether they're able to re-use musl's test suite some. I had an experiment a
while ago to incrementally port musl to rust while keeping the test suite
passing: [https://github.com/anp/rusl](https://github.com/anp/rusl). Haven't
put any time into it in a while, but I think matching musl's program-facing
behavior is still a good idea.

------
wyldfire
Also of interest is japaric's steed [1] -- a rust standard library (not a "C
lib").

[1] [https://github.com/japaric/steed](https://github.com/japaric/steed)

~~~
surajrmal
I'm wondering if it was abandoned. It looks like it hasn't had commits in
months.

~~~
dEnigma
Well, the "auto" branch saw a commit 20 days ago, and before that in January.
But they mostly seem to be small changes to "unbreak stuff".

------
HumanDrivenDev
Is there a good guide on how to make libraries with C bindings in rust? I've
been learning it for the past few days but without much of a use case. Fast
libraries with a C API in a higher level language would be very useful though.

~~~
vvanders
It's mostly straightforward, you just define with #[no_mangle] + extern fn ...

The Rust docs cover it in small detail[1]. FWIW you can do the same with JNI
and have direct Java->Rust bindings. If you want to get really clever you can
even parse the Rust AST(using syntex) to auto-generate java/headers(there may
be libs to do this now, I haven't looked in a while).

What's nice about the C FFI is you can pretty much embed Rust anywhere, I've
used it in C/C++, Java, C# and Python pretty easily.

[1] [https://doc.rust-lang.org/book/second-
edition/ch19-01-unsafe...](https://doc.rust-lang.org/book/second-
edition/ch19-01-unsafe-rust.html#calling-rust-functions-from-other-languages)

~~~
Manishearth
There's a tool called cbindgen
([https://github.com/eqrion/cbindgen](https://github.com/eqrion/cbindgen))
that generates header files from rust code . It's a bit experimental.

The reverse tool, bindgen ([https://github.com/rust-lang-nursery/rust-
bindgen/](https://github.com/rust-lang-nursery/rust-bindgen/)) is more mature
-- generates rust bindings from header files.

~~~
vvanders
Oh yeah, I should have mentioned bindgen, it's fantastic!

------
pornel
If I understand correctly, that will eventually allow 100% pure Rust
executables, and these executables will be easily redistributable and work on
any distro (only the latter is currently possible with the MUSL target).

~~~
ris
> these executables will be easily redistributable and work on any distro

While this _sounds_ amazing and I'm sure is very useful in various situations,
I think encouraging a culture of distributing software in such a fashion is an
incredibly bad idea. This is a big issue I have with the Go culture.
Downloading a statically linked binary from some site and just _sticking it
somewhere_ is extremely bad practise to encourage. The user will never get
prompted to update it, vulnerabilities and bugs in the vendored libraries will
never be addressed... the list of issues is endless.

Distributions are not really about _distribution_ , they're about
_maintenance_.

~~~
Goopplesoft
> I think encouraging a culture of distributing software in such a fashion is
> an incredibly bad idea

It isn't obvious to me how that is dramatically different from traditional
package managers as far as the update process goes. Upgrading decencies seems
like a generally active and involved process as far as most package managers
I've seen go.

pip/apt/npm/go-get/glide/yum/nixos etc all require you to actively discover
and upgrade your dependencies and I've never been prompted to upgrade a
package from any of the programs (a few do ask if you actively engage special
subcommands on CLI e.g apt list --upgrade). Unattended-upgrades might be close
but you can really only enable that on security releases and most package
managers don't have the resources to setup special distros (and fewer backport
security fixes).

So is the pain really just not having a quick upgrade cli and is that
dramatically different from going to a github page and getting the new URL for
a new binary? Would something as simple as writing a script to list and
download versions of binaries from github releases make this a non issue?

~~~
sambe
They don't require you to discover - they all have a clear and easy option to
go and find updates automatically. Most of the system-level ones also have
various schedulers & notifiers (both CLI and GUI) which are normally on by
default for common distributions.

------
zakk
How many security-critical bugs have been found in libc in the last ten years?

I know that in principle Rust is safer, but I am wondering it makes sense to
re-implement code so heavily audited as libc.

Wouldn’t it be better to redirect the effort to some other less audited code?

~~~
rwmj
Lots: [https://www.cvedetails.com/vulnerability-
list/vendor_id-72/p...](https://www.cvedetails.com/vulnerability-
list/vendor_id-72/product_id-767/GNU-Glibc.html)

~~~
sebcat
musl: [https://www.cvedetails.com/vulnerability-
list/vendor_id-1685...](https://www.cvedetails.com/vulnerability-
list/vendor_id-16859/Musl-libc.html)

Can't find separate listings for libc in FreeBSD, OpenBSD but the list is
smaller than glibc if you check e.g., VuXML or
[https://www.cvedetails.com/vulnerability-
list/vendor_id-97/p...](https://www.cvedetails.com/vulnerability-
list/vendor_id-97/product_id-163/Openbsd-Openbsd.html)

Looks like glibc is the worst sinner here.

~~~
rwmj
More people study and use glibc, so I guess they find more bugs. On the other
hand glibc has a larger code base. Anyway it's difficult to compare bug counts
across projects.

------
unfamiliar
I wonder how they are going to handle testing. The tests directory seems
pretty bare, surely there are some libc tests (written in C I guess) that can
be directly imported?

~~~
dralley
There has been discussion about leveraging parts of musl's test suite.

------
andrewmcwatters
Gonna go on a tangent here. I'm always curious about stuff like this. Everyone
and their mother wants to replace C, but what's people's answer to it being a
part of POSIX? I mean it's literally a part of the standards family, and no
one seems to address this. I can never take aspiring C-replacements seriously
because no one comes out and openly says, "This is how we replace C."

They're all really just claims that C is bad, and we shouldn't use it. Okay,
well how do you replace it? Or was that never the goal to begin with and you
just want me to use this language?

~~~
jcranmer
A rant I've wanted to do for a while:

We're at the point now where it would be useful to be able to express ABIs and
FFI in a language-agnostic manner without resorting to C. C lacks the
capability to describe fairly widespread functionality: things like fixed-size
integer types [0], pointer lifetimes, arrays with lengths, functions with
bound environments, variable arguments [1]. Keeping distinctions between
binary strings and textual strings would be useful for languages, and tracking
how to deallocate pointers would be beneficial as well. An ABI that allows
systems with different GCs to pass GC information to each other would be
amazing, if challenging.

Unfortunately, we're sort of in a catch-22. The multilingual interoperation
has to go through C, because that's the only standard that exists. The people
who write the standards look at the situation and see no reason to go beyond C
because no one's proposing an alternative.

[0] Sort of. There is <stdint.h>, but C tends to fundamentally think in terms
of char/short/int/long/long long, and there have been issues with trying to
work out what [u]int64_t maps to.

[1] Not in C's broken sense of "there are more arguments after this point, but
you get to guess how many." Rather, I'm thinking of a more Java sense of
"here's the list of extra arguments the caller gave me."

~~~
mjevans
What sort of properties would you consider a "textual string" to have that a
"binary string" would lack?

Offhand I'd assume you mean some of the following, but I'm curious if /my/
assumption about your needs is correct and complete. (Also, note that some of
these may be implied by values elsewhere in the specification, it isn't
strictly a data structure.)

    
    
        * flag:isValidated
        * targetEncoding
        * flag:isNormalized
        * targetNormalization
        * lengthMemory (not including the implicit size of the type's metadata)
        * lengthCodepoints (distinct encoding elements)
        * length(Some word meaning complete display elements, but not the actual width, height, etc.)
    

Do you also need actual random access to individual codepoints/"full
characters"? Or is the assumption that if such a scan is in progress the
entire sequence or major parts of it are being fully-scanned?

What if, within a given function call*, the underlying storage could be
referenced with zero-copying and substrings made? (On exiting that context
they'd be copied if retained.)

It might be useful to have library iterators that split on say, a single given
character, segments up to a maximum memory size of N (and scanning backwards
for the last "full character" or at least complete rune).

Of course, I believe that, by /default/ a program should perform /binary/
interaction with files including standard in/out/err. If there is a process
for converting such binary input/output it should assume and produce data in
UTF-8 (in NFC normalization) (when converting to/from "text" types) as a
default, which should be easy to globally over-ride or set specifically for a
given open file (and change mid use).

Of course I don't normally need to care about the encoding of data directly;
libraries with parsers and writers typically do that as well as other
encoding/decoding for that format for me. Everything else tends to be copy /
compare and do not change, or making filenames (mostly append bits of "should
all be UTF-8").

Actual, hard core, manipulation of encoded streams seems far more like a
composition editing issue (A specific editor where default input dialogs are
insufficient) or something that underlying libraries need to worry about.

~~~
hsivonen
In practice, use cases don't justify strings precalculating their number of
code points or grapheme clusters. Pixel width isn't a property of a string
alone, since it depends on font and the container to render it in (for line
breaks).

So a string should know its number of code units. Validity information should
be part of the type system and not runtime flags. I.e. you have a different
type for arbitrary bytes and for valid UTF-8. (See IDNA for why normalization
guarantee in infra over time is problematic.)

~~~
mjevans
Having thought about it you're probably right. That properly belongs on a
different kind of wrapper around this data structure or ones like it. Maybe in
that /specific/ and /rare/ use case it even makes sense to store the
underlying data in a wide data structure; but my supposition is that handling
it as a series of fragments (which would have a length in memory and in code-
points sizes) would be the answer. If addressing in such a way replacement and
other editing operations seem likely.

------
brianon99
There are many projects recently titled like "xxx in Rust" or "xxx in Go",
rewriting an existing software, seems to be built not because there is a
problem in the existing software, but without a clear reason.

For learning a new language, it can be a good practice. But if you hope the
project to grow successfully I think there is no hope.

~~~
sanxiyn
relibc is built to solve a problem in the existing software, namely newlib. It
has a clear reason.

Redox is an opearting system. An operating system needs a C library. Redox
used to use newlib, but developers found it unsatisfying.

------
snarfy
Once you've built this easy way out I fear it will turn into a crutch that
stops new, pure rust apps from being written. Do you really want a C library
in Redox?

~~~
tdbgamer
There is tons of C software out there that depends on libc that is never going
to be rewritten in Rust. Also think about interpreted languages like Python,
Ruby, etc. I imagine they all depend on libc. The only real way for Redox to
gain adoption is through cross platform compatibility.

~~~
imtringued
Does the rust compiler depend on libc?

~~~
Sean1708
Presumably. Rust _programs_ certainly do.

~~~
steveklabnik
The compiler does. Rust programs don't _inherently_ depend on libc; it's
libstd that does. Build without the standard library, no libc required.

