From b59a46eef09f8a4a4e11ab604b26db6c7607d750 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 13 Aug 2020 15:27:15 +0200 Subject: [PATCH] loader: work around Windows symlink limitation Currently there will be a problem if the TinyGo installation directory is not the same filesystem as the cache directory (usually the C drive) and Developer Mode is disabled. Therefore, let's add another fallback for when both conditions are true, falling back to copying the file instead of symlinking/hardlinking it. --- loader/goroot.go | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/loader/goroot.go b/loader/goroot.go index d9cf6ad7ec..621b92cb36 100644 --- a/loader/goroot.go +++ b/loader/goroot.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "errors" "fmt" + "io" "io/ioutil" "math/rand" "os" @@ -228,10 +229,27 @@ func symlink(oldname, newname string) error { return symlinkErr } } else { - // Make a hard link. + // Try making a hard link. err := os.Link(oldname, newname) if err != nil { - return symlinkErr + // Making a hardlink failed. Try copying the file as a last + // fallback. + inf, err := os.Open(oldname) + if err != nil { + return err + } + defer inf.Close() + outf, err := os.Create(newname) + if err != nil { + return err + } + defer outf.Close() + _, err = io.Copy(outf, inf) + if err != nil { + os.Remove(newname) + return err + } + // File was copied. } } return nil // success