github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/ioutils/ioutils.go (about)

     1  package ioutils
     2  
     3  import (
     4  	"io"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  )
     9  
    10  // todo: split docker/pkg/ioutils into a separate repo
    11  
    12  // AtomicWriteFile atomically writes data to a file specified by filename.
    13  func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
    14  	f, err := ioutil.TempFile(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
    15  	if err != nil {
    16  		return err
    17  	}
    18  	err = os.Chmod(f.Name(), perm)
    19  	if err != nil {
    20  		f.Close()
    21  		return err
    22  	}
    23  	n, err := f.Write(data)
    24  	if err == nil && n < len(data) {
    25  		f.Close()
    26  		return io.ErrShortWrite
    27  	}
    28  	if err != nil {
    29  		f.Close()
    30  		return err
    31  	}
    32  	if err := f.Sync(); err != nil {
    33  		f.Close()
    34  		return err
    35  	}
    36  	if err := f.Close(); err != nil {
    37  		return err
    38  	}
    39  	return os.Rename(f.Name(), filename)
    40  }