From 82539ad8d59729fb45b0bb0edda8f2bddb719eb1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 15:15:26 +0200 Subject: Adding upstream version 1.17.13. Signed-off-by: Daniel Baumann --- src/syscall/pwd_plan9.go | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/syscall/pwd_plan9.go (limited to 'src/syscall/pwd_plan9.go') diff --git a/src/syscall/pwd_plan9.go b/src/syscall/pwd_plan9.go new file mode 100644 index 0000000..1deeaa9 --- /dev/null +++ b/src/syscall/pwd_plan9.go @@ -0,0 +1,93 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The working directory in Plan 9 is effectively per P, so different +// goroutines and even the same goroutine as it's rescheduled on +// different Ps can see different working directories. +// +// Instead, track a Go process-wide intent of the current working directory, +// and switch to it at important points. + +package syscall + +import "sync" + +var ( + wdmu sync.Mutex // guards following + wdSet bool + wdStr string +) + +func Fixwd() { + wdmu.Lock() + defer wdmu.Unlock() + fixwdLocked() +} + +func fixwdLocked() { + if !wdSet { + return + } + // always call chdir when getwd returns an error + wd, _ := getwd() + if wd == wdStr { + return + } + if err := chdir(wdStr); err != nil { + return + } +} + +func fixwd(paths ...string) { + for _, path := range paths { + if path != "" && path[0] != '/' && path[0] != '#' { + Fixwd() + return + } + } +} + +// goroutine-specific getwd +func getwd() (wd string, err error) { + fd, err := open(".", O_RDONLY) + if err != nil { + return "", err + } + defer Close(fd) + return Fd2path(fd) +} + +func Getwd() (wd string, err error) { + wdmu.Lock() + defer wdmu.Unlock() + + if wdSet { + return wdStr, nil + } + wd, err = getwd() + if err != nil { + return + } + wdSet = true + wdStr = wd + return wd, nil +} + +func Chdir(path string) error { + fixwd(path) + wdmu.Lock() + defer wdmu.Unlock() + + if err := chdir(path); err != nil { + return err + } + + wd, err := getwd() + if err != nil { + return err + } + wdSet = true + wdStr = wd + return nil +} -- cgit v1.2.3