]> Cypherpunks.ru repositories - nncp.git/blobdiff - src/tmp.go
Sync directories for rename assurance
[nncp.git] / src / tmp.go
index 3c305ce36a54d7ec4432d8d98c1c43392a1311a5..0784b996eea067656966f6e2b5bfb8a516f31242 100644 (file)
@@ -21,20 +21,28 @@ import (
        "bufio"
        "hash"
        "io"
-       "io/ioutil"
        "os"
        "path/filepath"
+       "strconv"
+       "time"
 
        "golang.org/x/crypto/blake2b"
 )
 
+func TempFile(dir, prefix string) (*os.File, error) {
+       // Assume that probability of suffix collision is negligible
+       suffix := strconv.FormatInt(time.Now().UnixNano()+int64(os.Getpid()), 16)
+       name := filepath.Join(dir, "nncp"+prefix+suffix)
+       return os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, os.FileMode(0666))
+}
+
 func (ctx *Ctx) NewTmpFile() (*os.File, error) {
        jobsPath := filepath.Join(ctx.Spool, "tmp")
        var err error
-       if err = os.MkdirAll(jobsPath, os.FileMode(0700)); err != nil {
+       if err = os.MkdirAll(jobsPath, os.FileMode(0777)); err != nil {
                return nil, err
        }
-       fd, err := ioutil.TempFile(jobsPath, "")
+       fd, err := TempFile(jobsPath, "")
        if err == nil {
                ctx.LogD("tmp", SDS{"src": fd.Name()}, "created")
        }
@@ -71,9 +79,22 @@ func (tmp *TmpFileWHash) Cancel() {
        os.Remove(tmp.Fd.Name())
 }
 
+func DirSync(dirPath string) error {
+       fd, err := os.Open(dirPath)
+       if err != nil {
+               return err
+       }
+       err = fd.Sync()
+       if err != nil {
+               fd.Close()
+               return err
+       }
+       return fd.Close()
+}
+
 func (tmp *TmpFileWHash) Commit(dir string) error {
        var err error
-       if err = os.MkdirAll(dir, os.FileMode(0700)); err != nil {
+       if err = os.MkdirAll(dir, os.FileMode(0777)); err != nil {
                return err
        }
        if err = tmp.W.Flush(); err != nil {
@@ -87,5 +108,8 @@ func (tmp *TmpFileWHash) Commit(dir string) error {
        tmp.Fd.Close()
        checksum := ToBase32(tmp.Hsh.Sum(nil))
        tmp.ctx.LogD("tmp", SDS{"src": tmp.Fd.Name(), "dst": checksum}, "commit")
-       return os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum))
+       if err = os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum)); err != nil {
+               return err
+       }
+       return DirSync(dir)
 }