Source file src/runtime/os_workdir_ios_arm64.go

     1  // Copyright 2026 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 runtime
     6  
     7  import "unsafe"
     8  
     9  const (
    10  	maxPathLen             = 1024
    11  	_kCFStringEncodingUTF8 = 0x08000100
    12  )
    13  
    14  // initWorkingDir sets the current working directory to the app root on iOS.
    15  // By default ios/arm64 processes start in "/".
    16  func initWorkingDir() {
    17  	bundle := cfBundleGetMainBundle()
    18  	if bundle == 0 {
    19  		writeErrStr("runtime/cgo: no main bundle\n")
    20  		return
    21  	}
    22  	if !bundleHasInfoPlist(bundle) {
    23  		// Not an app bundle; keep the inherited working directory.
    24  		return
    25  	}
    26  	url := cfBundleCopyBundleURL(bundle)
    27  	if url == 0 {
    28  		// No app bundle URL found.
    29  		return
    30  	}
    31  
    32  	var buf [maxPathLen]byte
    33  	path := &buf[0]
    34  	ok := cfURLGetFileSystemRepresentation(url, true, path, uintptr(len(buf)))
    35  	cfRelease(url)
    36  	if !ok {
    37  		writeErrStr("runtime/cgo: cannot get bundle URL path\n")
    38  		return
    39  	}
    40  
    41  	if chdir(path) != 0 {
    42  		writeErrStr("runtime/cgo: chdir(")
    43  		writeErrData(path, int32(findnull(path)))
    44  		writeErrStr(") failed\n")
    45  	}
    46  
    47  	const goExecWrapperWorkingDirectoryKey = "GoExecWrapperWorkingDirectory\x00"
    48  	key := cfStringCreateWithCString(0, unsafe.StringData(goExecWrapperWorkingDirectoryKey), _kCFStringEncodingUTF8)
    49  	if key == 0 {
    50  		writeErrStr("runtime/cgo: cannot create GoExecWrapperWorkingDirectory string\n")
    51  		return
    52  	}
    53  	wd := cfBundleGetValueForInfoDictionaryKey(bundle, key)
    54  	cfRelease(key)
    55  	if wd == 0 {
    56  		return
    57  	}
    58  	if !cfStringGetCString(wd, path, uintptr(len(buf)), _kCFStringEncodingUTF8) {
    59  		writeErrStr("runtime/cgo: cannot get GoExecWrapperWorkingDirectory string\n")
    60  		return
    61  	}
    62  
    63  	if chdir(path) != 0 {
    64  		writeErrStr("runtime/cgo: chdir(")
    65  		writeErrData(path, int32(findnull(path)))
    66  		writeErrStr(") failed\n")
    67  	}
    68  }
    69  
    70  // bundleHasInfoPlist reports whether bundle contains an Info.plist. The main
    71  // bundle of an executable that is not inside an app bundle is the directory
    72  // holding the executable, which has no Info.plist. It can also happen on
    73  // Corellium virtual devices.
    74  func bundleHasInfoPlist(bundle uintptr) bool {
    75  	const (
    76  		infoName = "Info\x00"
    77  		infoType = "plist\x00"
    78  	)
    79  	name := cfStringCreateWithCString(0, unsafe.StringData(infoName), _kCFStringEncodingUTF8)
    80  	if name == 0 {
    81  		writeErrStr("runtime/cgo: cannot create Info.plist strings\n")
    82  		return false
    83  	}
    84  	typ := cfStringCreateWithCString(0, unsafe.StringData(infoType), _kCFStringEncodingUTF8)
    85  	if typ == 0 {
    86  		cfRelease(name)
    87  		writeErrStr("runtime/cgo: cannot create Info.plist strings\n")
    88  		return false
    89  	}
    90  	url := cfBundleCopyResourceURL(bundle, name, typ, 0)
    91  	cfRelease(name)
    92  	cfRelease(typ)
    93  	if url == 0 {
    94  		return false
    95  	}
    96  	cfRelease(url)
    97  	return true
    98  }
    99  

View as plain text