Home | History | Annotate | Download | only in testenv
      1 // Copyright 2016 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package testenv
      6 
      7 import (
      8 	"io/ioutil"
      9 	"os"
     10 	"path/filepath"
     11 	"sync"
     12 	"syscall"
     13 )
     14 
     15 var symlinkOnce sync.Once
     16 var winSymlinkErr error
     17 
     18 func initWinHasSymlink() {
     19 	tmpdir, err := ioutil.TempDir("", "symtest")
     20 	if err != nil {
     21 		panic("failed to create temp directory: " + err.Error())
     22 	}
     23 	defer os.RemoveAll(tmpdir)
     24 
     25 	err = os.Symlink("target", filepath.Join(tmpdir, "symlink"))
     26 	if err != nil {
     27 		err = err.(*os.LinkError).Err
     28 		switch err {
     29 		case syscall.EWINDOWS, syscall.ERROR_PRIVILEGE_NOT_HELD:
     30 			winSymlinkErr = err
     31 		}
     32 	}
     33 	os.Remove("target")
     34 }
     35 
     36 func hasSymlink() (ok bool, reason string) {
     37 	symlinkOnce.Do(initWinHasSymlink)
     38 
     39 	switch winSymlinkErr {
     40 	case nil:
     41 		return true, ""
     42 	case syscall.EWINDOWS:
     43 		return false, ": symlinks are not supported on your version of Windows"
     44 	case syscall.ERROR_PRIVILEGE_NOT_HELD:
     45 		return false, ": you don't have enough privileges to create symlinks"
     46 	}
     47 
     48 	return false, ""
     49 }
     50