Date: Sun, 1 Nov 2015 22:17:34 -0800 From: Russell Haley <russ.haley@gmail.com> To: freebsd-mono@freebsd.org, monodevelop-list@lists.ximian.com, romain@blogreen.org Subject: Re: [MonoDevelop] Monodevelop 5.10 Message-ID: <CABx9NuRv8USi9UAhN4GcSafR=%2BKkmASU3djRaWrs2kSq6Db0WA@mail.gmail.com> In-Reply-To: <20151101093408.GA4994@FreeBSD.org> References: <CABx9NuQwXXjkzJ1d-158T%2BSDA_ycQT%2Bgphut28PYXJ%2Bnx4v4Cw@mail.gmail.com> <BN3PR13MB0852D6C1FF7ADAEB708687AFA62F0@BN3PR13MB0852.namprd13.prod.outlook.com> <CABx9NuQ0u=GBUNnDSw6ftv-7rch7k=PsU6KbhVJ5HyAfwd9GMg@mail.gmail.com> <BN3PR13MB085247B3FD2551A19391F211A62E0@BN3PR13MB0852.namprd13.prod.outlook.com> <CABx9NuSvZNyDy3N5dZ0d0GutKzoag74Dj0S2QYb7evXUh8NEaA@mail.gmail.com> <20151101093408.GA4994@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Hey Guys, Romains suggestion was what I needed. The offending code is at the bottom of SystemRename(string sourceFile,string destFile) in the file src/core/MonoDevelop.Core/MonoDevelop.Core/FileService.cs: else { if (Syscall.rename (sourceFile, destFile) !=3D 0) { //Should this be Stdlib as well? switch (Stdlib.GetLastError ()) { case Errno.EACCES: case Errno.EPERM: throw new UnauthorizedAccessException (); case Errno.EINVAL: throw new InvalidOperationException (); case Errno.ENOTDIR: throw new DirectoryNotFoundException (); case Errno.ENOENT: throw new FileNotFoundException (); case Errno.ENAMETOOLONG: throw new PathTooLongException (); default: throw new IOException (); } } } Notice there is no case for ErrNo.EXDEV. I have added a new control case as such: else { if (Stdlib.rename (sourceFile, destFile) !=3D 0) { switch (Stdlib.GetLastError ()) { case Errno.EACCES: case Errno.EPERM: throw new UnauthorizedAccessException (); case Errno.EINVAL: throw new InvalidOperationException (); case Errno.ENOTDIR: throw new DirectoryNotFoundException (); case Errno.ENOENT: throw new FileNotFoundException (); case Errno.ENAMETOOLONG: throw new PathTooLongException (); case Errno.EXDEV: CrossFilesystemRename (sourceFile, destFile); break; default: throw new IOException (); } } } With the new function here: private static void CrossFilesystemRename(string sourceFile, string destFile) { //copy the existing destfile to tmp //move the sourceFile to the destFilename //delete the old destFile contents string tempFile =3D Path.Combine ("/tmp/", Path.GetRandomFileName () + ".tmp"); try{ InternalMoveFile (destFile, tempFile); InternalMoveFile(sourceFile,destFile); DeleteFile(tempFile); } catch { if (!File.Exists (destFile)) { InternalMoveFile (tempFile, destFile); } if (File.Exists (tempFile)) { DeleteFile(tempFile); } throw; } } Two things to note: 1) I noticed that the original was using Syscall.rename, when the rename function seems to be part of StdLib. Syscall in fact seems to only have a reference to renameat not rename, so I changed FileService.cs to StdLib with no discernible difference. Does anyone have some input on this? 2) As you can see there is a horrible hard coded /tmp file path. I am not sure how to determine the temp directory in a unix system. That said in FreeBSD, /tmp is part of the rootfs and seems to be pretty standard in Linux too: https://docs.freebsd.org/doc/5.4-RELEASE/usr/share/doc/handbook/dirstructur= e.html Does anyone have a different solution? Anyway, this fixes the issue I was having. Thank you everyone for helping me pull this together. I'll look to submit a patch to Xamarin sometime later in the week. Cheers, Russ On Sun, Nov 1, 2015 at 1:34 AM, Romain Tarti=C3=A8re <romain@blogreen.org> = wrote: > Hi, > > On Sat, Oct 31, 2015 at 09:48:03PM -0700, Russell Haley wrote: > > Any thoughts? I am guessing that the syscall.rename is doing something > > other than an mv and zfs doesn't like it. Or conversly, zfs is doing > > something funky and the mono wrapper library doesn't like it? > > rename(2) is intended to rename a link, so can't move a file from a > filesystem to another. mv(1) tries to rename(2) files, and if the > rename failed with EXDEV, attempts to create the target file, copy data > from the source file, copy permissions and unlink(2) the source (see > fastcopy() function in mv.c). > > Mono should have a similar behavior, and something may get wrong in this > logic. Maybe you can try to search what is happening there? > > -- > Romain Tarti=C3=A8re <romain@FreeBSD.org> http://people.FreeBSD.org/~rom= ain/ > pgp: 8234 9A78 E7C0 B807 0B59 80FF BA4D 1D95 5112 336F (ID: 0x5112336F) > (plain text =3Dnon-HTML=3D PGP/GPG encrypted/signed e-mail much appreciat= ed) >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CABx9NuRv8USi9UAhN4GcSafR=%2BKkmASU3djRaWrs2kSq6Db0WA>