Subject: bug#69532: mv's new -x option should be made orthogonal to -t/-T/default

From: Pádraig Brady <[email-masked]>
Date: Sun, 17 Mar 2024 11:32:15 +0000

On 17/03/2024 06:10, Paul Eggert wrote:
> On 2024-03-05 06:16, Pádraig Brady wrote:
>> I think I'll remove the as yet unreleased mv --swap from coreutils,
>> given that
>> util-linux is as widely available as coreutils on GNU/Linux platforms.
> 
> Although removing that "mv --swap" implementation was a win, I don't
> think we can simply delegate this to util-linux's exch command.
> Exchanging files via a renameat-like call is not limited to the Linux
> kernel; it's also possible on macOS via renameatx_np with RENAME_SWAP,
> and there have been noises about adding similar things to other
> operating systems.
> 
> I just now added support for macOS renameatx_np to Gnulib, so coreutils
> does not need to worry about the macOS details; it can simply use
> renameatu with the Linux flags. See:
> 
> https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=af32ee824ee18255839f9812b8ed61aa5257a82b
> 
> Even with Linux it's dicey. People may have older util-linux installed
> and so lack the 'exch' utility; this is true for both Fedora 39 and
> Ubuntu 23.10, the current releases. Ubuntu is also odd in that it
> doesn't install all the util-linux utilities as part of the util-linux
> package, so it's not clear what they will do with 'exch'.
> 
> So I propose that we implement the idea in coreutils in a better way,
> that interacts more nicely with -t, -T, etc. Also, I suggest using the
> Linuxish name "--exchange" instead of the macOSish name "--swap", and
> (for now at least) not giving the option a single-letter equivalent as I
> expect it to be useful from scripts, not interactively.
> 
> After looking at various ways to do it I came up with the attached
> proposed patch. This should work on both GNU/Linux and macOS, if your OS
> is recent enough and the file system supports atomic exchange.

The implementation looks good.

Re exch(1) on macos, I see util-linux is on homebrew,
so it would be relatively easy to ifdef renameatx_np in util-linux also.

I think the --no-copy situation is brittle, as scripts not using it now
would be atomic, but then if we ever supported cross fs swaps
it may become non atomic. I'd at least doc with a line in the --exchange
description in usage() to say something like:
   "Use --no-copy to enforce atomic operation"

While the most flexible, it's also quite awkward to need
`mv --exchange --no-copy --no-target-directory` for most uses.
I.e. it's tempting to imply the --no-... options with --exchange,
but I suppose since scripting is the primary use case for this
flexibility trumps conciseness, so I'm ok with the verbosity I think.

thanks,
Pádraig