prop.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright (c) 2020 Tailscale Inc & 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. package version
  5. import (
  6. "os"
  7. "path/filepath"
  8. "runtime"
  9. "strings"
  10. "tailscale.com/syncs"
  11. )
  12. // IsMobile reports whether this is a mobile client build.
  13. func IsMobile() bool {
  14. return runtime.GOOS == "android" || runtime.GOOS == "ios"
  15. }
  16. // OS returns runtime.GOOS, except instead of returning "darwin" it
  17. // returns "iOS" or "macOS".
  18. func OS() string {
  19. if runtime.GOOS == "ios" {
  20. return "iOS"
  21. }
  22. if runtime.GOOS == "darwin" {
  23. return "macOS"
  24. }
  25. return runtime.GOOS
  26. }
  27. // IsSandboxedMacOS reports whether this process is a sandboxed macOS
  28. // process (either the app or the extension). It is true for the Mac App Store
  29. // and macsys (System Extension) version on macOS, and false for
  30. // tailscaled-on-macOS.
  31. func IsSandboxedMacOS() bool {
  32. if runtime.GOOS != "darwin" {
  33. return false
  34. }
  35. if IsMacSysExt() {
  36. return true
  37. }
  38. exe, _ := os.Executable()
  39. return strings.HasSuffix(exe, "/Contents/MacOS/Tailscale") || strings.HasSuffix(exe, "/Contents/MacOS/IPNExtension")
  40. }
  41. var isMacSysExt syncs.AtomicValue[bool]
  42. // IsMacSysExt whether this binary is from the standalone "System
  43. // Extension" (a.k.a. "macsys") version of Tailscale for macOS.
  44. func IsMacSysExt() bool {
  45. if runtime.GOOS != "darwin" {
  46. return false
  47. }
  48. if b, ok := isMacSysExt.LoadOk(); ok {
  49. return b
  50. }
  51. exe, err := os.Executable()
  52. if err != nil {
  53. return false
  54. }
  55. v := filepath.Base(exe) == "io.tailscale.ipn.macsys.network-extension"
  56. isMacSysExt.Store(v)
  57. return v
  58. }
  59. // IsWindowsGUI reports whether the current process is the Windows GUI.
  60. func IsWindowsGUI() bool {
  61. if runtime.GOOS != "windows" {
  62. return false
  63. }
  64. exe, _ := os.Executable()
  65. exe = filepath.Base(exe)
  66. return strings.EqualFold(exe, "tailscale-ipn.exe") || strings.EqualFold(exe, "tailscale-ipn")
  67. }