@@ -17,6 +17,8 @@ import (
1717 "io/fs"
1818 "math/rand"
1919 "os"
20+ "path/filepath"
21+ "runtime"
2022 "strconv"
2123 "strings"
2224 "time"
@@ -390,6 +392,49 @@ func (c *common) Setenv(key, value string) {
390392 }
391393}
392394
395+ // Chdir calls os.Chdir(dir) and uses Cleanup to restore the current
396+ // working directory to its original value after the test. On Unix, it
397+ // also sets PWD environment variable for the duration of the test.
398+ //
399+ // Because Chdir affects the whole process, it cannot be used
400+ // in parallel tests or tests with parallel ancestors.
401+ func (c * common ) Chdir (dir string ) {
402+ // Note: function copied from the Go 1.24.0 source tree.
403+
404+ oldwd , err := os .Open ("." )
405+ if err != nil {
406+ c .Fatal (err )
407+ }
408+ if err := os .Chdir (dir ); err != nil {
409+ c .Fatal (err )
410+ }
411+ // On POSIX platforms, PWD represents “an absolute pathname of the
412+ // current working directory.” Since we are changing the working
413+ // directory, we should also set or update PWD to reflect that.
414+ switch runtime .GOOS {
415+ case "windows" , "plan9" :
416+ // Windows and Plan 9 do not use the PWD variable.
417+ default :
418+ if ! filepath .IsAbs (dir ) {
419+ dir , err = os .Getwd ()
420+ if err != nil {
421+ c .Fatal (err )
422+ }
423+ }
424+ c .Setenv ("PWD" , dir )
425+ }
426+ c .Cleanup (func () {
427+ err := oldwd .Chdir ()
428+ oldwd .Close ()
429+ if err != nil {
430+ // It's not safe to continue with tests if we can't
431+ // get back to the original working directory. Since
432+ // we are holding a dirfd, this is highly unlikely.
433+ panic ("testing.Chdir: " + err .Error ())
434+ }
435+ })
436+ }
437+
393438// runCleanup is called at the end of the test.
394439func (c * common ) runCleanup () {
395440 for {
0 commit comments