Skip to content

Commit 70c3f31

Browse files
committed
Use short path for LIMA_HOME on windows
Other commands such as qemu-system-x86_64.exe don't work with C:\Users\AndersBjörklund, they need to use C:\Users\ANDERS~1 In theory they could have supported using UNC paths such as \\?\C:\Users\AndersBjörklund, but in practice they do not... Signed-off-by: Anders F Björklund <[email protected]>
1 parent b53e7df commit 70c3f31

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

pkg/store/dirnames/dirnames.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"runtime"
89

910
"github.com/lima-vm/lima/pkg/store/filenames"
1011
)
@@ -24,11 +25,22 @@ func LimaDir() (string, error) {
2425
if err != nil {
2526
return "", err
2627
}
28+
// on windows, DOS paths are needed by some tools like QEMU
29+
if runtime.GOOS == "windows" {
30+
homeDir, err = ShortName(homeDir)
31+
if err != nil {
32+
return "", err
33+
}
34+
}
2735
dir = filepath.Join(homeDir, DotLima)
2836
}
2937
if _, err := os.Stat(dir); errors.Is(err, os.ErrNotExist) {
3038
return dir, nil
3139
}
40+
// on windows, EvalSymlinks translates short paths back to long again
41+
if runtime.GOOS == "windows" {
42+
return dir, nil
43+
}
3244
realdir, err := filepath.EvalSymlinks(dir)
3345
if err != nil {
3446
return "", fmt.Errorf("cannot evaluate symlinks in %q: %w", dir, err)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//go:build !windows
2+
// +build !windows
3+
4+
package dirnames
5+
6+
func ShortName(path string) (string, error) {
7+
return path, nil
8+
}

pkg/store/dirnames/shortname_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package dirnames
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"gotest.tools/v3/assert"
9+
)
10+
11+
// Note: can't use t.TempDir(), because it is _always_ long... <sigh>
12+
// instead use os.TempDir(), something like `C:\users\anders\Temp`
13+
14+
func TestShortNameShort(t *testing.T) {
15+
d := os.TempDir()
16+
l := filepath.Join(d, "foo")
17+
err := os.Mkdir(l, 0755)
18+
assert.NilError(t, err)
19+
s, err := ShortName(l)
20+
t.Logf("%s => %s", l, s)
21+
assert.NilError(t, err)
22+
os.RemoveAll(l)
23+
}
24+
25+
func TestShortNameLong(t *testing.T) {
26+
d := os.TempDir()
27+
l := filepath.Join(d, "baaaaaaaaaar")
28+
err := os.Mkdir(l, 0755)
29+
assert.NilError(t, err)
30+
s, err := ShortName(l)
31+
t.Logf("%s => %s", l, s)
32+
assert.NilError(t, err)
33+
os.RemoveAll(l)
34+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package dirnames
2+
3+
import (
4+
"syscall"
5+
)
6+
7+
func ShortName(path string) (string, error) {
8+
p := syscall.StringToUTF16(path)
9+
b := p // GetShortPathName says we can reuse buffer
10+
n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
11+
if err != nil {
12+
return "", err
13+
}
14+
if n > uint32(len(b)) {
15+
b = make([]uint16, n)
16+
n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
17+
if err != nil {
18+
return "", err
19+
}
20+
}
21+
return syscall.UTF16ToString(b), nil
22+
}

0 commit comments

Comments
 (0)