1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using System.IO; 10 #if !PLATFORM_WINDOWS 11 using Mono.Unix.Native; 12 #endif 13 using System.Runtime.InteropServices; 14 using Antmicro.Renode.Exceptions; 15 using Antmicro.Renode.Core; 16 17 namespace Antmicro.Renode.Utilities 18 { 19 public static class FileCopier 20 { Copy(string src, string dst, bool overwrite = false)21 public static void Copy(string src, string dst, bool overwrite = false) 22 { 23 try 24 { 25 #if !PLATFORM_WINDOWS 26 if (ConfigurationManager.Instance.Get("file-system", "use-cow", false)) 27 { 28 int sfd = -1, dfd = -1; 29 try 30 { 31 sfd = Syscall.open(src, OpenFlags.O_RDONLY); 32 dfd = Syscall.open(dst, overwrite ? OpenFlags.O_CREAT | OpenFlags.O_TRUNC | OpenFlags.O_WRONLY : (OpenFlags.O_CREAT | OpenFlags.O_EXCL), FilePermissions.S_IRUSR | FilePermissions.S_IWUSR); 33 34 if(sfd != -1 && dfd != -1 && ioctl(dfd, 0x40049409, sfd) != -1) 35 { 36 return; 37 } 38 } 39 finally 40 { 41 if(sfd != -1) 42 { 43 Syscall.close(sfd); 44 } 45 46 if(dfd != -1) 47 { 48 Syscall.close(dfd); 49 } 50 } 51 } 52 #endif 53 54 var lastTime = CustomDateTime.Now; 55 using(var source = File.Open(src, FileMode.Open, FileAccess.Read)) 56 { 57 using(var destination = File.Open(dst, overwrite ? FileMode.Create : FileMode.CreateNew)) 58 { 59 var progressHandler = EmulationManager.Instance.ProgressMonitor.Start("Copying...", false, true); 60 61 var read = 0; 62 var count = 0L; 63 var sourceLength = source.Length; 64 var buffer = new byte[64*1024]; 65 do 66 { 67 read = source.Read(buffer, 0, buffer.Length); 68 destination.Write(buffer, 0, read); 69 count += read; 70 71 var now = CustomDateTime.Now; 72 if(now - lastTime > TimeSpan.FromSeconds(0.25)) 73 { 74 progressHandler.UpdateProgress((int)(100L*count/sourceLength)); 75 lastTime = now; 76 } 77 } 78 while(read > 0); 79 progressHandler.Finish(); 80 } 81 } 82 } 83 catch (IOException e) 84 { 85 throw new RecoverableException(e); 86 } 87 } 88 89 #if !PLATFORM_WINDOWS 90 [DllImport("libc")] ioctl(int d, ulong request, int a)91 private extern static int ioctl(int d, ulong request, int a); 92 #endif 93 } 94 } 95 96