From owner-freebsd-mono@freebsd.org Mon Nov 2 06:17:35 2015 Return-Path: Delivered-To: freebsd-mono@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B4493A23985 for ; Mon, 2 Nov 2015 06:17:35 +0000 (UTC) (envelope-from russ.haley@gmail.com) Received: from mail-vk0-x231.google.com (mail-vk0-x231.google.com [IPv6:2607:f8b0:400c:c05::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 7B68D14CA for ; Mon, 2 Nov 2015 06:17:35 +0000 (UTC) (envelope-from russ.haley@gmail.com) Received: by vkgy127 with SMTP id y127so79971334vkg.0 for ; Sun, 01 Nov 2015 22:17:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=o+nPJWCJYC9wb3/eZ7cLKwcHjYRYIv/un8SxgDmFgdo=; b=zebKEVSjW05ULMQWZoxwuyq0rkBFm3urbpMda3KwLSs8Hv0SfCU2JrVWvVlKiXHyvg 51fKs++XI4kFZOzQos1mV+q/JmaLJNoqB0/pxhv+w9x4fiQhynCk2aglTPiVYjO2G/mg DGvXFIFIKBirK+ze1NxLMXo1DTwFpbobgesixyjNUCAhkgtFBxCoYqUHdJZG9wP9PP36 H4orWkzOtfBbCfwrsg5BvLiZGXuQKLPXHPuUwWUQRTPgrge/8OAdui+07kMpY/30wTze 4YMaOAt/xwo0ISYso3vt2Zp0sWYCA+J61vjDDaAC9NCnyFrIE2eq0I8KJlwx61yoJFag U14g== MIME-Version: 1.0 X-Received: by 10.31.47.207 with SMTP id v198mr14051009vkv.145.1446445054214; Sun, 01 Nov 2015 22:17:34 -0800 (PST) Received: by 10.31.66.9 with HTTP; Sun, 1 Nov 2015 22:17:34 -0800 (PST) In-Reply-To: <20151101093408.GA4994@FreeBSD.org> References: <20151101093408.GA4994@FreeBSD.org> Date: Sun, 1 Nov 2015 22:17:34 -0800 Message-ID: Subject: Re: [MonoDevelop] Monodevelop 5.10 From: Russell Haley To: freebsd-mono@freebsd.org, monodevelop-list@lists.ximian.com, romain@blogreen.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.20 X-BeenThere: freebsd-mono@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Mono and C# applications on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Nov 2015 06:17:35 -0000 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 = 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 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) >