coreutils
coreutils copied to clipboard
What's the problem with uutils?
This is not a complain, I just want to understand the reason behind this project, since another trying to do the something similar exists, I understand the part that this don't try to be 100% compatible with coreutils (maybe making this easier to implement?), so would be cool to have the goals a bit more explained in the README
For me, and that's my take on this matter, there are 4 things
- uutils/coreutils uses some weird stuff, like the uumain function that goes somewhere (that I don't know) that has a Rust main, that could be cause it started way before cargo supported workspaces, not sure, but I try, hopefully, a more idiomatic approach using 2018 Rust;
- each utility uses a different cli helper;
- I feel like uutils try hard to implement everything mainly for Windows, Linux and MacOS,(there some utilities that compiles just fine for FreeBSD and Fuchsia) and for me that's ok, but my main goal about platform is support the more Unix/Unix-like platforms that I can, following the same guarantees of compilations for the Rust platform Tiers;
- the uutils core, usually the struct for some stuff is a struct with one inner field that holds the c struct for that thing, I don't like this and prefer to reimplement the structure as a proper Rust one and no raw pointers inside the structure tree;
The last one, I see several people doing this, but I consider a anti-patterns that I would like to avoid.
I'll try to put in better words on the README as goals
Hey, so I just stumbled upon this project and felt like I might as well answer some of these.
-
uumain
exists so that there is a unified entrypoint to each utility. This allows the multicall binary (namedcoreutils
currently, but formerly it was calleduutils
) to use the exact same code for a utility as when you compile the utility individually (e.g. you want acp
binary, not a symlink namedcp
that points to thecoreutils
binary). - I assume by CLI helper you are referring to
clap
,getopts
, etc. This is indeed an issue that I am in the midst of fixing (everything is migrating toclap
orstructopt
. Unfortunately, some utilities still require manual argument parsing, and there's not really much that I can do about that - Ideally the utilities would work everywhere, but obviously more focus is put on platforms that the maintainers and users actually use (hence the focus on Windows beyond just Unix-like platforms)
- I think you are referring to using a newtype to hold a pointer to a
libc
struct
? Doing so seems safer to me than reimplementing everything as you don't really need to worry about new fields being added as you are just using the underlying Cstruct
. If you reimplement everything and aren't careful, you could assume thestruct
is some specific size, end up being wrong, and then cause a buffer overflow. This, of course, assumes I'm correctly interpreting what you mean.
* `uumain` exists so that there is a unified entrypoint to each utility. This allows the multicall binary (named `coreutils` currently, but formerly it was called `uutils`) to use the exact same code for a utility as when you compile the utility individually (_e.g._ you want a `cp` binary, not a symlink named `cp` that points to the `coreutils` binary).
I see, like busybox, right?
* Ideally the utilities would work everywhere, but obviously more focus is put on platforms that the maintainers and users actually use (hence the focus on Windows beyond just Unix-like platforms)
Yeah, I agree, I mostly use Linux, FreeBSD and also NetBSD in some degree, so I decided to focus mostly on UNIX, but I don't have problems supporting Windows as well, I just don't use it and have no knowledge about the Windows API to do the same for every utility. Haiku is there because I do have a crazy friend that loves haiku and was interest in trying the project in that OS. Fuchsia was just a test since it's a tier2 target and I could easily check the code if it compiles or not.
* I think you are referring to using a newtype to hold a pointer to a `libc` `struct`? Doing so seems safer to me than reimplementing everything as you don't really need to worry about new fields being added as you are just using the underlying C `struct`. If you reimplement everything and aren't careful, you could assume the `struct` is some specific size, end up being wrong, and then cause a buffer overflow. This, of course, assumes I'm correctly interpreting what you mean.
Now that's a interesting subject cause I have a different opinion compared to Sep 2019. I do not consider that a anti-pattern anymore.
What I was talking about is creating a new high level struct with all new fields using a more rusty types, but with a condition, it cannot be used as is in C call that would require the C version of the struct, till now I just got utilities that don't write into those structures, so the idea was just have new struct holding the data in a easier to use rust types just to look at the data and print it in a way. I still think that this is a better approach for the sole purpose is to read data in a easy way, but now I don't consider the raw pointer in the inner of the struct a bad idea.
Even before I thought that if you mainly need to either to change data inside and/or keep passing the C struct back and forth to C calls and/or depend of the size of the struct, inner field with the C struct is the way to go, for the same reasons you mentioned, and now I do think recreating the struct in rust a anti-pattern, always.