[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: first contribution: smart rename for the mv command
From: |
Stéphane Archer |
Subject: |
Re: first contribution: smart rename for the mv command |
Date: |
Sun, 15 Jan 2023 09:15:18 -0300 |
Thanks a lot for your feedback ☺️
I will try my best to improve my patch
I have to admit that understanding the code base and the idioms is
currently difficult for me. I imagine it comes with practice. Is there any
resources or books that have helped you in this area or is it just pure
practice?
On Sat, Jan 14, 2023, 04:57 Kaz Kylheku <962-396-1872@kylheku.com> wrote:
> On 2022-12-22 07:59, Stéphane Archer wrote:
> > Dear Gnu Coreutils community,
> >
> > I would like to contribute to the project a feature I miss a lot in the
> > `mv` command.
> > I currently have a working patch but it's clearly not perfect. I would
> like
> > to have feedback on it and would like to know if you are willing to
> accept
> > this change.
> > Do you think it's possible?
>
> I have only technical feedback about code.
>
> 1. access function: you probably don't want to use this.
>
> The purpose of the access function is for setuid programs to determine
> whether the real user ID would have a certain access, without having
> to drop privileges to that ID.
>
> This is almost certainly not what you want in a utility like this;
> mv just should wield whatever effective user ID powers it has, and
> not hold back.
>
> Even if the operation is F_OK for simple existence, the function is not
> appropriate, because POSIX says:
>
> The checks for accessibility (including directory permissions
> checked during pathname resolution) shall be performed using
> the real user ID in place of the effective user ID and the real
> group ID in place of the effective group ID.
>
> So if you do access("/home/bob/private/xyzzy.txt", F_OK), as EUID =
> root,
> but RUID = alice, access will pretend that it's running as alice and
> not allow the existence check through bob's private directory.
>
> 2. Don't invent new functions from scratch.
>
> find_dot(str) -> strcspn(str, ".") // mostly
>
> This strcspn will return the length of the prefix of str
> before the first dot. If there is not dot, it returns strlen(str).
>
> 3. string functions like strlen return size_t, not unsigned int;
> don't mix types. It's not a huge deal because you probably
> won't get a 64 bit size_t value that is truncated when converted
> to a 32 bit unsigned int. It's untidy though.
>
> 4. I see a malloc call, but most GNU programs don't use malloc directly
> and the Coreutils are no exception: they use xmalloc, xzalloc
> and such, which are wrappers. Always look around in the code base
> for examples of the kind of thing you're trying to do, to see what
> functions it's using; reuse its idioms so your patch blends in.
>
> 5. I think your create_smart_name function can be condensed with some
> creative use of the snprintf function. Possibly one call to that,
> with some conditional in the argument list, could do the whole job
> of combining the pieces.
>
> 6. Re:
>
> + unsigned int i = 0;
> + char is[100]; // What len should I put?
> + sprintf(is, "%d", i);
>
> Because i is unsigned int, use "%u" and not "%d",
> which will interpret it as int, possibly negative.
>
> Your loop should test for i hitting UINT_MAX;
> you don't want to increment from there to zero.
> One fine day someone will have that many files;
> and filesystems can be virtual (e.g. we could use
> FUSE in some way to make a test case for this without
> making billions of files.)
>
> Since the index is unsigned int with a UINT_MAX
> maximum value, we can conservatively estimate
> the number of digits needed by dividing
> (UINT_MAX * CHAR_BIT) / 3. (The idea being every 3
> binary digits encodes one decimal digit's worth of
> entropy). Then add 1 for the null terminator.
>
> For 32 bits we get 32 / 3 + 1 = 11. (exact fit for UINT_MAX)
>
> For 63 bits we get 64 / 3 + 1 = 22. (one byte wasted)
>
> 7. Pay attention to coding style. GNU uses funny indentation for braces:
>
> if (smart_rename)
> { // + 2
> dest = // + 2 again
> }
>
> Do not even think about doing this outside of GNU, though. :)
>