...

Source file src/syscall/pwd_plan9.go

     1	// Copyright 2015 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	// The working directory in Plan 9 is effectively per P, so different
     6	// goroutines and even the same goroutine as it's rescheduled on
     7	// different Ps can see different working directories.
     8	//
     9	// Instead, track a Go process-wide intent of the current working directory,
    10	// and switch to it at important points.
    11	
    12	package syscall
    13	
    14	import "sync"
    15	
    16	var (
    17		wdmu  sync.Mutex // guards following
    18		wdSet bool
    19		wdStr string
    20	)
    21	
    22	func Fixwd() {
    23		wdmu.Lock()
    24		defer wdmu.Unlock()
    25		fixwdLocked()
    26	}
    27	
    28	func fixwdLocked() {
    29		if !wdSet {
    30			return
    31		}
    32		// always call chdir when getwd returns an error
    33		wd, _ := getwd()
    34		if wd == wdStr {
    35			return
    36		}
    37		if err := chdir(wdStr); err != nil {
    38			return
    39		}
    40	}
    41	
    42	func fixwd(paths ...string) {
    43		for _, path := range paths {
    44			if path != "" && path[0] != '/' && path[0] != '#' {
    45				Fixwd()
    46				return
    47			}
    48		}
    49	}
    50	
    51	// goroutine-specific getwd
    52	func getwd() (wd string, err error) {
    53		fd, err := open(".", O_RDONLY)
    54		if err != nil {
    55			return "", err
    56		}
    57		defer Close(fd)
    58		return Fd2path(fd)
    59	}
    60	
    61	func Getwd() (wd string, err error) {
    62		wdmu.Lock()
    63		defer wdmu.Unlock()
    64	
    65		if wdSet {
    66			return wdStr, nil
    67		}
    68		wd, err = getwd()
    69		if err != nil {
    70			return
    71		}
    72		wdSet = true
    73		wdStr = wd
    74		return wd, nil
    75	}
    76	
    77	func Chdir(path string) error {
    78		fixwd(path)
    79		wdmu.Lock()
    80		defer wdmu.Unlock()
    81	
    82		if err := chdir(path); err != nil {
    83			return err
    84		}
    85	
    86		wd, err := getwd()
    87		if err != nil {
    88			return err
    89		}
    90		wdSet = true
    91		wdStr = wd
    92		return nil
    93	}
    94	

View as plain text