coreutils
[Top][All Lists]
Advanced

[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. :)
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]