OSDN Git Service

versoin1.1.9 (#594)
[bytom/vapor.git] / vendor / github.com / syndtr / goleveldb / leveldb / storage / file_storage_unix.go
1 // Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
2 // All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6
7 // +build darwin dragonfly freebsd linux netbsd openbsd
8
9 package storage
10
11 import (
12         "os"
13         "syscall"
14 )
15
16 type unixFileLock struct {
17         f *os.File
18 }
19
20 func (fl *unixFileLock) release() error {
21         if err := setFileLock(fl.f, false, false); err != nil {
22                 return err
23         }
24         return fl.f.Close()
25 }
26
27 func newFileLock(path string, readOnly bool) (fl fileLock, err error) {
28         var flag int
29         if readOnly {
30                 flag = os.O_RDONLY
31         } else {
32                 flag = os.O_RDWR
33         }
34         f, err := os.OpenFile(path, flag, 0)
35         if os.IsNotExist(err) {
36                 f, err = os.OpenFile(path, flag|os.O_CREATE, 0644)
37         }
38         if err != nil {
39                 return
40         }
41         err = setFileLock(f, readOnly, true)
42         if err != nil {
43                 f.Close()
44                 return
45         }
46         fl = &unixFileLock{f: f}
47         return
48 }
49
50 func setFileLock(f *os.File, readOnly, lock bool) error {
51         how := syscall.LOCK_UN
52         if lock {
53                 if readOnly {
54                         how = syscall.LOCK_SH
55                 } else {
56                         how = syscall.LOCK_EX
57                 }
58         }
59         return syscall.Flock(int(f.Fd()), how|syscall.LOCK_NB)
60 }
61
62 func rename(oldpath, newpath string) error {
63         return os.Rename(oldpath, newpath)
64 }
65
66 func isErrInvalid(err error) bool {
67         if err == os.ErrInvalid {
68                 return true
69         }
70         if syserr, ok := err.(*os.SyscallError); ok && syserr.Err == syscall.EINVAL {
71                 return true
72         }
73         return false
74 }
75
76 func syncDir(name string) error {
77         f, err := os.Open(name)
78         if err != nil {
79                 return err
80         }
81         defer f.Close()
82         if err := f.Sync(); err != nil && !isErrInvalid(err) {
83                 return err
84         }
85         return nil
86 }