diff --git a/mc_work/dorun.go b/mc_work/dorun.go index 5ae54601514234ae76769dafdaa1a697238c135d..a6d4f7e687845f73c800c4e7b912431d0f6a76fa 100644 --- a/mc_work/dorun.go +++ b/mc_work/dorun.go @@ -4,8 +4,10 @@ package mcwork import ( "bufio" "bytes" + "errors" "fmt" "io" + "io/fs" "math" "math/rand" "os" @@ -62,6 +64,43 @@ func isNotSane(mcPrm *McPrm) error { return nil } +// fExists returns true if the file exists. +// It is part of the exercise, working around file permissions on windows +func fExists (name string) bool { + var err error + if _, err := os.Stat (name); err == nil { + return true + } + if errors.Is (err, fs.ErrNotExist) { + return false + } + return true +} + + +// createFix is a wrapper around os.Create() which I seem to need for windows. +// On windows, I cannot overwrite an existing file. To be very exact, the +// O_CREATE fails if a file exists. O_TRUNC also fails. +func createFix (name string) (*os.File, error) { + var rErr = `Remove the file %s and try again. This only happens on windows: %w` + var f *os.File + var err error + if f, err = os.Create(name); err == nil { + return f, nil // Most common path (no problem) + } + + if !fExists(name) { // does not exist, but we have a real error. + return nil, err // Return original error + } // Next step try to remove original file + if e := os.Remove (name); e != nil { + return nil, fmt.Errorf (rErr, name, e) + } + if f, err = os.Create(name); err == nil { // second attempt, after removing name + return f, nil + } + return nil, err +} + // setupRun does things like get the cooling rate, seed the random numbers. func setupRun(mcPrm *McPrm, cprm *cprm) error { var err error @@ -83,7 +122,7 @@ func setupRun(mcPrm *McPrm, cprm *cprm) error { if mcPrm.fOutName, err = setSuffix(mcPrm.fOutName, ".csv"); err != nil { return err } - if cprm.fOutRaw, err = os.Create(mcPrm.fOutName); err != nil { + if cprm.fOutRaw, err = createFix(mcPrm.fOutName); err != nil { return err } cprm.fOut = bufio.NewWriter(cprm.fOutRaw)