[lxc-devel] [lxd/master] shared: Handle symlinks in FileCopy()

monstermunchkin on Github lxc-bot at linuxcontainers.org
Wed Aug 14 15:48:58 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 355 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190814/fdbd126f/attachment.bin>
-------------- next part --------------
From 57e81062b022c0b545cef542fccdd96c4b8a03b0 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Wed, 14 Aug 2019 17:45:35 +0200
Subject: [PATCH] shared: Handle symlinks in FileCopy()

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 shared/util.go | 58 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 16 deletions(-)

diff --git a/shared/util.go b/shared/util.go
index 4ee9b179fa..8c06cfd51f 100644
--- a/shared/util.go
+++ b/shared/util.go
@@ -348,33 +348,59 @@ func FileMove(oldPath string, newPath string) error {
 
 // FileCopy copies a file, overwriting the target if it exists.
 func FileCopy(source string, dest string) error {
-	s, err := os.Open(source)
+	fi, err := os.Lstat(source)
 	if err != nil {
 		return err
 	}
-	defer s.Close()
 
-	fi, err := s.Stat()
-	if err != nil {
-		return err
-	}
+	var d *os.File
 
-	d, err := os.Create(dest)
-	if err != nil {
-		if os.IsExist(err) {
-			d, err = os.OpenFile(dest, os.O_WRONLY, fi.Mode())
+	if fi.Mode()&os.ModeSymlink != 0 {
+		target, err := os.Readlink(source)
+		if err != nil {
+			return err
+		}
+
+		if PathExists(dest) {
+			err = os.Remove(dest)
 			if err != nil {
 				return err
 			}
-		} else {
+		}
+
+		err = os.Symlink(target, dest)
+		if err != nil {
 			return err
 		}
-	}
-	defer d.Close()
 
-	_, err = io.Copy(d, s)
-	if err != nil {
-		return err
+		d, err = os.OpenFile(dest, os.O_WRONLY, fi.Mode())
+		if err != nil {
+			return err
+		}
+	} else {
+		s, err := os.Open(source)
+		if err != nil {
+			return err
+		}
+		defer s.Close()
+
+		d, err = os.Create(dest)
+		if err != nil {
+			if os.IsExist(err) {
+				d, err = os.OpenFile(dest, os.O_WRONLY, fi.Mode())
+				if err != nil {
+					return err
+				}
+			} else {
+				return err
+			}
+		}
+		defer d.Close()
+
+		_, err = io.Copy(d, s)
+		if err != nil {
+			return err
+		}
 	}
 
 	/* chown not supported on windows */


More information about the lxc-devel mailing list