@@ -64,6 +64,43 @@ import (
6464 "tailscale.com/wgengine/router"
6565)
6666
67+ // createTailscaleSymlink creates a 'tailscale' symlink pointing to the current
68+ // 'tailscaled' binary on Android, enabling the combined binary to work with both names.
69+ func createTailscaleSymlink () {
70+ // Get the path to the current executable
71+ execPath , err := os .Executable ()
72+ if err != nil {
73+ return // Silently fail, not critical
74+ }
75+
76+ // Resolve symlinks to get the real binary path
77+ realPath , err := filepath .EvalSymlinks (execPath )
78+ if err != nil {
79+ realPath = execPath // Fallback to execPath if symlink resolution fails
80+ }
81+
82+ // Get the binary name and directory
83+ binName := filepath .Base (realPath )
84+ binDir := filepath .Dir (realPath )
85+ symlinkPath := filepath .Join (binDir , "tailscale" )
86+
87+ // Check if 'tailscale' already exists
88+ if _ , err := os .Lstat (symlinkPath ); err == nil {
89+ // File exists, check if it's already a symlink to us
90+ if target , err := os .Readlink (symlinkPath ); err == nil {
91+ // It's a symlink, check if it points to our binary
92+ if target == binName {
93+ return // Already correctly set up
94+ }
95+ }
96+ // Exists but not the right symlink, remove it
97+ os .Remove (symlinkPath )
98+ }
99+
100+ // Create the symlink: tailscale -> <actual binary name>
101+ _ = os .Symlink (binName , symlinkPath )
102+ }
103+
67104// defaultTunName returns the default tun device name for the platform.
68105func defaultTunName () string {
69106 switch runtime .GOOS {
0 commit comments