[BusyBox] mv is deleting files!
Jason Schoon
floydpink at gmail.com
Thu Jul 14 14:11:09 MDT 2005
I'll drop this patch onto my system and give it a try. Looks like a
good solution for 1.01 at least.
On 7/14/05, Rob Landley <rob at landley.net> wrote:
> On Thursday 14 July 2005 10:38, Jason Schoon wrote:
> > I actually saw this issue some time ago and posted it to the list, but
> > never got back to it. The cross-filesystem method (I was using tmpfs
> > to jffs2 as well) was the only way I could reproduce the issue as
> > well.
>
> Cross-filesystem is the only way to trigger the actual copy logic. Otherwise
> mv is a rename syscall, and this ain't a kernel bug. :)
>
> > If you come up with a patch, I will happily try it out on my system here.
>
> The bug is that our funky stat lib returns 0 if stat fails with errno=ENOENT,
> but that this line:
>
> else if ((source_exists = cp_mv_stat(*argv, &source_stat)) >= 0) {
>
> Passes 0 through as a success.
>
> Changing the >= to a > fixes the behavior, but then we don't get an error
> message. The interesting question is why the heck does cp_mv_stat.c want
> to single out ENOENT? The case I can think of is that when we can access a
> file in a directory we can't list, we still want cp to work. (mv doesn't care
> so much, I'll have to test what the gnu version does in that case, but
> failing entirely would be a pretty reasonable response...)
>
> Okay, the response from the gnu tools to some of these corner cases is just
> _weird_. Try to chmod a directory to 444 and then ls its contents. You get
> a list of the files in it with "permission denied" for each one. (Not even
> ls -l, just ls, which should be doing about the same as "echo dir/*", which
> works by the way...) Needless to say, gnu "cat", "cp", and "mv" won't
> touch 'em unless the directory they're in has the x bit. So why are we
> jumping through all these hoops to distinguish "didn't exist" with "couldn't
> stat for a reason other than didn't exist?"
>
> So: if we _just_ want to fix mv, then we can change the >= to > and add an
> error message. That's the 1.0.1 fix, and here's the least intrusive patch I
> could come up with.
>
> Index: coreutils/mv.c
> ===================================================================
> --- coreutils/mv.c (revision 10824)
> +++ coreutils/mv.c (working copy)
> @@ -99,10 +99,10 @@
> struct stat source_stat;
> int source_exists;
>
> - if (errno != EXDEV) {
> + if (errno != EXDEV ||
> + (source_exists = cp_mv_stat(*argv, &source_stat)) < 1) {
> bb_perror_msg("unable to rename `%s'", *argv);
> - }
> - else if ((source_exists = cp_mv_stat(*argv, &source_stat)) >= 0) {
> + } else {
> if (dest_exists) {
> if (dest_exists == 3) {
> if (source_exists != 3) {
>
> For 1.1, I think I'd like to take a stab at untangling this logic a bit...
>
> Let me know if that fixes the problem and I'll throw it in 1.0.1-rc1.
>
> Rob
>
More information about the busybox
mailing list