Make a backup file: Difference between revisions

→‎{{header|Go}}: modify to require existing file
(Go solution)
(→‎{{header|Go}}: modify to require existing file)
Line 51:
bx := ".backup"
// see if it's a link
var err error
if tf, err := os.Readlink(fn); err == nil {
fn = tf
}
// stat to preserve permissions.
// default permissions, used if file doesn't exist
permvar :=fi os.FileMode(0666)FileInfo
if iffi, err = fos.TruncateStat(0fn); err != nil {
// now see if file exists.
if fi, err := osfmt.StatPrintln(fnerr); err == nil {
return
// it does. use existing permissions instead of default
}
// and rename the file, (losing any existing backup.)
// attemp rename
perm = fi.Mode().Perm()
if err := os.Rename(fn, fn+bx); err != nil {
fmt.Println(err)
// if rename of known existing file fails, we don't continue.
fmt.Println(err)return
return
}
} else {
// stat failed. only allowable error is "no such file..."
// any other error is fatal.
pErr, ok := err.(*os.PathError)
if !ok || pErr.Err.Error() != "no such file or directory" {
fmt.Println(err)
return
}
}
// create new file
err := ioutil.WriteFile(fn, []byte("you too!\n"), permfi.Mode().Perm())
if err != nil {
fmt.Println(err)
Line 92 ⟶ 83:
 
func main() {
err := updateWithBackup("myth", ".backup", 0666,func(f *os.File) (err error) {
func(if _, err = f.Seek(0, *os.FileSEEK_SET); (err error)!= nil {
if _, err = f.Seek(0, os.SEEK_SET); err != nil {
return
}
if err = f.Truncate(0); err != nil {
return
}
_, err = f.WriteString("you too!\n")
return
})
if _, err = f.SeekTruncate(0, os.SEEK_SET); err != nil {
return
} else { }
_, err = f.WriteString("you too!\n")
}return
})
if err != nil {
fmt.Println(err)
Line 112 ⟶ 102:
// update the file as needed and return any error, but should not close
// the file. updateWithBackup will then close the file and return any error.
func updateWithBackup(fn, bx string, permup func(*os.FileMode,File) error) (err error) {
up func(*os.File) error) (err error) {
var f *os.File
if f, err = openWithBackup(fn, bx, perm); err != nil {
return
}
Line 130 ⟶ 119:
// destination file + bx. Any error encountered is returned. tf will be
// an open file if and only if err == nil.
func openWithBackup(fn, bx string, perm os.FileMode) (tf *os.File, err error) {
// follow symlink.
if target, err := os.Readlink(fn); err == nil {
Line 137 ⟶ 126:
// open the target file for exclusive access.
if tf, err = os.OpenFile(fn, os.O_RDWR, 0); err != nil {
return
// oops, that didn't work. see if it's simply missing.
pErr, ok := err.(*os.PathError)
if ok && pErr.Err.Error() == "no such file or directory" {
// yep, that's all it was. return a new file.
return os.OpenFile(fn, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm)
}
return // no, it was some other error. fail.
}
// at this point an existing target file has been opened.
// deferred function closes target file if an error happens
// during the backup operation.
1,707

edits