55 comments

[ 3.3 ms ] story [ 92.5 ms ] thread
Seems to consist mostly of a copy of Busybox’s C code auto-translated to Rust using c2rust – resulting in ubiquitous use of raw pointers and `unsafe` for mundane operations. That’s technically “written entirely in Rust”, but not in the way you’d expect… On the other hand, it could serve as a good starting point for a gradual rewrite into idiomatic Rust.
Two of the bullet points they list ask for help in doing this conversion:

* Replace some extern "C" includes with more idiomatic uses. Pretty straightforward find/replace-all usually does the trick. * Pick a utility, like cat or touch, and work on translating it into safer, more idiomatic rust. There are plenty of unsafes lying around that you can tackle!

(comment deleted)
Rust is going to take credibility hits if more people do this. Once it becomes socially acceptable to use unsafe all over the place in the community, it might be hard to win the user trust back.
I don't think 1) unsafe will ever become prevalent in the ecosystem nor 2) that unsafe should be seen as anything other than an escape hatch that is sometimes necessary.

Autotranslations from C will be seen as what they are, a transliteration from a less safe language with exactly the same bugs as the preexisting codebase. You could think of the case of calling a COM library that has a leak or a OOB error, I wouldn't blame the language doing the calling for the bug.

Having said that, these translations are still useful as a starting point, not a destination. Think of a case where the external C API is retained, but all the innards are gradually converted to a more idiomatic codebase.

`unsafe` is already very prevalent in the ecosystem and this is a big point of contention.

https://github.com/actix/actix-web/issues/289

This would be anecdotal, and caused massive stir in the community when it was realized.
And a lot of the usages were promptly fixed when people made a stink about it.
It was only fixed when a fuzzer showed a lot of vulnerabilities. Up until then the attitude was "stop demonizing unsafe, we know what we're doing."
I don't know about those particular authors. However, the vibe I get from the rust community as a whole is "unsafe is where dragons lay". Most, I'd say, treat it just like inline asm in C++. Sometimes a necessary evil, but not something you should be in the habit of using.
Actix is currently popular, but only because the rest of the ecosystem has been waiting for `async-await`, and taking a slow-and-steady approach to getting things right. I'd expect Actix's popularity to take a dramatic downturn right about when Rocket releases a async version that runs on stable Rust.
> these translations are still useful as a starting point, not a destination.

This was the case for the Go compiler (automatic translation from C to Go), and it has worked out well in practice. There are still some vestiges, but it's moving more and more toward idiomatic Go all the time.

Yeah, this is the broad goal of the project. As much as I love fresh rewrites, I don't think they have nearly the same hope of becoming successful as this sort of gradual approach. It's a big project, and there's lots of code that's still not idiomatic by any means, but the goal is to get 1% better every day.
> Autotranslations from C will be seen as what they are, a transliteration from a less safe language with exactly the same bugs as the preexisting codebase.

Yes. But I agree with the parent that there is a credibility problem here. The featured repository calls itself a fork "written entirely in Rust" (emphasis mine). It doesn't call itself "autotranslated to Rust". There would be enough room for that in the title, but the author decided to spend that room on calling it "free-range, non-GMO" instead. It doesn't acknowledge the point you raise, that this is apparently much closer to a starting point than to the destination.

The README is somewhat circumspect about the fact that this is autotranslated. It does mention c2rust, but doesn't actually say anything about the status of a conversion to safe, idiomatic Rust. There is a long list of commits which suggest that the author did a lot of manual fixes, so something was done beyond just autotranslation, but it's hard to judge.

So I think the credibility danger is that if HN were to get more frequent "X written in Rust" that would turn out to just be "X autotranslated to Rust", at some point the community might tire of upvoting these, and other "X actually written in Rust" submissions might get buried. Or similarly, instead of a general "it's feasible and useful to rewrite X in Rust" impression, the wider community (somewhat open to Rust but not diehard fans) might get an impression of "even Rust fans are too lazy to actually rewrite stuff in safe Rust".

But doesn't "fork" imply that it's not actually a re-write or a clone?
> Rust is going to take credibility hits if more people do this

I disagree on that. Rust also took a credibility hit for people advertising exactly the opposite: To rewrite things from scratch. While that approach certainly helps with getting idiomatic code right from the start, years of feature development will get lost, and the chances for introducing non memory related bugs are still there.

The ability to transfer a project to Rust in 1 step, and then to gradually improve it seems like a big plus to me. Of course it would not be great if projects are just auto-translated and then kept that way. But I don't think that is the intention of most authors who do that.

Almost seems like it would be easier to just write it from scratch in idiomatic Rust than to try and refactor a code base of this size that makes such extensive use of unsafe blocks and pointers.
"New bugs for old! New bugs for old!"

(With apologies to to Aladdin.)

C2Rust contributor here. Yes, the conversion to unsafe is indeed only intended as a stepping stone for a rewrite into idiomatic Rust. In fact, we're hard at work on a refactoring tool that will (hopefully, one day) take some of the tedium out of that process by doing things such as identifying raw pointers that can be upgraded to proper Rust references.
Automatically rewriting raw pointers to Rust references would be amazing.
To be fair, it calls itself a fork of Busybox, which implies that most of its source originated in Busybox.
What is this used for? I am interested in contributing
(comment deleted)
Out of curiosity, how does one become interested in contributing to a thing when one doesn't even know what the thing is?
The name has pointers to english-as-a-second-language. It could be they were seeking "what are you using this for" or "what are you targetting with this work" which goes to the higher purpose. General use of busybox is implied by what you know of /rescue and/or the small unix for containers work, but there are also tiny unixes for small computer systems, Pi based embedded systems, IoT, you name it (busybox is probably overkill for IoT devices but I could believe its part of the diagnostic)
They understand the tool but not the plan. If they don't like the plan, they may c2rust it themselves and try a different angle.
Fair point. It looks cool so I am interested. I am also a Rust beginner
He asked what it was used for, not what it does.
busybox provides coreutils, with a focus on being as stripped-down as possible. in other words, busybox provides binaries like cat, ls, nano, sudo, etc. (basically enough to be able to do shell scripting) for use in memory-constrained embedded linux systems like internet routers or in-vehicle infotainment systems.
Gotcha. Might be out of my league
don't discount it!

can you write a program that opens a text file and dumps its contents on STDOUT? then you can write `cat`! and there are oodles of tools that are as simple as that.

the nice thing about contributing to a busybox-like distribution of coreutils is that they intentionally leave out the bells and whistles, since the target systems are memory-constrained. and you can do the development and testing right on your workstation. busybox is designed to be suitable for embedded devices, but the tools will run on any device with a linux kernel, as long as you can compile for the target CPU.

Is C2R (and the precursor I know of F2C) strictly speaking "without a line of C" in it?

Yes, literally. But figuratively, No, because you used the C as a higher order definition language and did translation not re-implementation.

So this might (in some cases) be bug for bug compatible (a good thing?) if the bug is a logic bug, not a C boundary error or a type cast effect or something not strictly defined. It isn't an "independently implemented suite" if you wanted to e.g. use it for conformance testing to a spec.

Missing license.
Which would surely need to be GPL given it seems to be an auto-converted version of BusyBox, so I would have thought that makes it a derivative?
Oh no, it seems to just be c2rust. I wish they actually meant "written" as in "written" and not as in "compiled".
If this started with BusyBox translated from C to Rust, is this code also under the GPL, as is BusyBox?

I don't see any LICENSE or COPYING files in the repo.

Seems like it would have to be the same license as BusyBox, since it is a "compiled" artifact of BusyBox (just compiled to another high level language).
Yes, it is a derived work, automatic translation (or even any kind of translation) does not create a new work.
I've always been interested in busybox and other similar tool sets - I even wrote a very simple set of coreutils clones at one point; but I've never really understood the use case. I like Rust & I like using modern tools when there's a benefit. But whatever coreutils Apple ship or come with a reasonable Linux distro seem to work 99% of the time for my work. Simpler & smaller I get for restricted embedded, I'm sure I've used them doing embedded work with small ARM boards & a custom tiny Linux - but the payoffs have never seemed too enticing.
Busybox is quite literally “POSIX in a box”. It’s useful to have on systems where you’d like a shell and some utilities but don’t want to bother with having anything fancy.
For coreutils actually written from scratch, see a more interesting project: https://github.com/uutils/coreutils
Yeah, I'm a fan of the uutils project but I haven't tested it out myself yet! It would be neat to start incorporating some of those commands into rustybox in place of the old implementations.
"Written in Rust" is overselling it.

It's somewhat impressive that c2rust is can translate so much code, but without following it up with refactoring into more idiomatic Rust (which is a lot of work), this is merely replacing gcc with rustc.

If you're looking for an alternative to BusyBox, a former BusyBox maintainer has written ToyBox[1], which has a similar collection of command-line utilities, but with a BSD license. It's still in C, though.

[1] https://github.com/landley/toybox

Making this code more idiomatic seems like a really cool opportunity to get some Rust experience. I imagine there's a ton of low-hanging fruit in here, especially given how minimal and modular the different utilities tend to be. And at the same time, you're touring idioms and optimizations copied from some of the most refined C code out there.
Unless Rust suffers some catastrophic leadership or design choices, I'm convinced it will be the next language to "eat the world."
If a GPL code is auto-translated to another language, shouldn't the fork have the same GPL license? Or does the new author get to put a new license?
It should be GPL.
Given that busybox is structured as one function per command

    int COMMAND_main(int argc, char **argv)
and that it's compilable as a library already, I wonder if it would make more sense to use bindgen or the like to start with the actual busybox C code, but with a (trivial) Rust main function. You'd have the current busybox source compiling an ever-smaller library, and a Rust lib next to it. Then move things over to the Rust side one command at a time.
I've actually thought about doing this. There are some "applets" that are just so complex or have so many gotos that I really don't want to touch the rust code any more than I want to touch the C code, so it may make sense to take this route with them in the future.
This is a very welcome addition to our existing system's core toolchain :)

I just wish that all Rust implementations would include a "Git" or "Docker containers" section as a stepping stone in the right direction for other projects.