forked from External/grumble
Major gofix run.
This commit is contained in:
parent
92e6ac5276
commit
71b8314c2e
28 changed files with 522 additions and 559 deletions
|
|
@ -8,9 +8,9 @@ import (
|
|||
"bytes"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"hash"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// blobReader is based on the principles of the checksumReader from the archive/zip
|
||||
|
|
@ -18,7 +18,7 @@ import (
|
|||
|
||||
// ErrHashMismatch is returned if a blobReader has read a file whose computed hash
|
||||
// did not match its key.
|
||||
var ErrHashMismatch = os.NewError("hash mismatch")
|
||||
var ErrHashMismatch = errors.New("hash mismatch")
|
||||
|
||||
// blobReader reads a blob from disk, hashing all incoming data. On EOF, it checks
|
||||
// whether the read data matches the key.
|
||||
|
|
@ -28,7 +28,7 @@ type blobReader struct {
|
|||
hash hash.Hash
|
||||
}
|
||||
|
||||
func newBlobReader(rc io.ReadCloser, key string) (br *blobReader, err os.Error) {
|
||||
func newBlobReader(rc io.ReadCloser, key string) (br *blobReader, err error) {
|
||||
sum, err := hex.DecodeString(key)
|
||||
if err != nil {
|
||||
return
|
||||
|
|
@ -36,10 +36,10 @@ func newBlobReader(rc io.ReadCloser, key string) (br *blobReader, err os.Error)
|
|||
return &blobReader{rc, sum, sha1.New()}, nil
|
||||
}
|
||||
|
||||
func (r *blobReader) Read(b []byte) (n int, err os.Error) {
|
||||
func (r *blobReader) Read(b []byte) (n int, err error) {
|
||||
n, err = r.rc.Read(b)
|
||||
r.hash.Write(b[:n])
|
||||
if err != os.EOF {
|
||||
if err != io.EOF {
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(r.sum, r.hash.Sum()) {
|
||||
|
|
@ -48,6 +48,6 @@ func (r *blobReader) Read(b []byte) (n int, err os.Error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (r *blobReader) Close() os.Error {
|
||||
func (r *blobReader) Close() error {
|
||||
return r.rc.Close()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ package blobstore
|
|||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -26,11 +27,11 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrLocked = os.NewError("lockfile acquired by another process")
|
||||
ErrLockAcquirement = os.NewError("unable to acquire lockfile")
|
||||
ErrBadFile = os.NewError("a bad file exists in the blobstore directory. unable to create container directores.")
|
||||
ErrNoSuchKey = os.NewError("no such key")
|
||||
ErrInvalidKey = os.NewError("invalid key")
|
||||
ErrLocked = errors.New("lockfile acquired by another process")
|
||||
ErrLockAcquirement = errors.New("unable to acquire lockfile")
|
||||
ErrBadFile = errors.New("a bad file exists in the blobstore directory. unable to create container directores.")
|
||||
ErrNoSuchKey = errors.New("no such key")
|
||||
ErrInvalidKey = errors.New("invalid key")
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -41,7 +42,7 @@ var (
|
|||
// Open an existing, or create a new BlobStore at path.
|
||||
// Path must point to a directory, and must already exist.
|
||||
// See NewBlobStore for more information.
|
||||
func Open(path string, makeall bool) (err os.Error) {
|
||||
func Open(path string, makeall bool) (err error) {
|
||||
defaultMutex.Lock()
|
||||
defer defaultMutex.Unlock()
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ func Open(path string, makeall bool) (err os.Error) {
|
|||
|
||||
// Close the open default BlobStore. This removes the lockfile allowing
|
||||
// other processes to open the BlobStore.
|
||||
func Close() (err os.Error) {
|
||||
func Close() (err error) {
|
||||
if defaultStore == nil {
|
||||
panic("DefaultStore not open")
|
||||
}
|
||||
|
|
@ -71,17 +72,16 @@ func Close() (err os.Error) {
|
|||
|
||||
// Lookup a blob by its key and return a buffer containing the contents
|
||||
// of the blob.
|
||||
func Get(key string) (buf []byte, err os.Error) {
|
||||
func Get(key string) (buf []byte, err error) {
|
||||
return defaultStore.Get(key)
|
||||
}
|
||||
|
||||
// Store a blob. If the blob was successfully stored, the returned key
|
||||
// can be used to retrieve the buf from the BlobStore.
|
||||
func Put(buf []byte) (key string, err os.Error) {
|
||||
func Put(buf []byte) (key string, err error) {
|
||||
return defaultStore.Put(buf)
|
||||
}
|
||||
|
||||
|
||||
// Open an existing, or create a new BlobStore residing at path.
|
||||
// Path must point to a directory, and must already exist.
|
||||
//
|
||||
|
|
@ -92,7 +92,7 @@ func Put(buf []byte) (key string, err os.Error) {
|
|||
// some I/O operations when writing blobs. (Since the BlobStore
|
||||
// knows that all directories will exist, it does not need to check
|
||||
// whether they do, and create them if they do not.).
|
||||
func NewBlobStore(path string, makeall bool) (bs *BlobStore, err os.Error) {
|
||||
func NewBlobStore(path string, makeall bool) (bs *BlobStore, err error) {
|
||||
// Does the directory exist?
|
||||
dir, err := os.Open(path)
|
||||
if err != nil {
|
||||
|
|
@ -130,7 +130,7 @@ func NewBlobStore(path string, makeall bool) (bs *BlobStore, err os.Error) {
|
|||
if !fi.IsDirectory() {
|
||||
return nil, ErrBadFile
|
||||
}
|
||||
} else if e.Error == os.ENOTDIR {
|
||||
} else if e.Err == os.ENOTDIR {
|
||||
return nil, ErrBadFile
|
||||
}
|
||||
} else if err != nil {
|
||||
|
|
@ -150,7 +150,7 @@ func NewBlobStore(path string, makeall bool) (bs *BlobStore, err os.Error) {
|
|||
if !fi.IsDirectory() {
|
||||
return nil, ErrBadFile
|
||||
}
|
||||
} else if e.Error == os.ENOTDIR {
|
||||
} else if e.Err == os.ENOTDIR {
|
||||
return nil, ErrBadFile
|
||||
}
|
||||
} else if err != nil {
|
||||
|
|
@ -170,14 +170,14 @@ func NewBlobStore(path string, makeall bool) (bs *BlobStore, err os.Error) {
|
|||
|
||||
// Close an open BlobStore. This removes the lockfile allowing
|
||||
// other processes to open the BlobStore.
|
||||
func (bs *BlobStore) Close() (err os.Error) {
|
||||
func (bs *BlobStore) Close() (err error) {
|
||||
return os.Remove(bs.lockfn)
|
||||
}
|
||||
|
||||
// Checks that a given key is a valid key for the BlobStore.
|
||||
// If it is, it returns the three components that make up the on-disk path
|
||||
// the given key can be found or should be stored at.
|
||||
func getKeyComponents(key string) (dir1, dir2, fn string, err os.Error) {
|
||||
func getKeyComponents(key string) (dir1, dir2, fn string, err error) {
|
||||
// SHA1 digests are 40 bytes long when hex-encoded
|
||||
if len(key) != 40 {
|
||||
err = ErrInvalidKey
|
||||
|
|
@ -195,7 +195,7 @@ func getKeyComponents(key string) (dir1, dir2, fn string, err os.Error) {
|
|||
|
||||
// Lookup the path hat a key would have on disk.
|
||||
// Returns an error if the key is not a valid BlobStore key.
|
||||
func (bs *BlobStore) pathForKey(key string) (fn string, err os.Error) {
|
||||
func (bs *BlobStore) pathForKey(key string) (fn string, err error) {
|
||||
dir1, dir2, rest, err := getKeyComponents(key)
|
||||
if err != nil {
|
||||
return
|
||||
|
|
@ -207,14 +207,14 @@ func (bs *BlobStore) pathForKey(key string) (fn string, err os.Error) {
|
|||
|
||||
// Lookup a blob by its key and return a buffer containing the contents
|
||||
// of the blob.
|
||||
func (bs *BlobStore) Get(key string) (buf []byte, err os.Error) {
|
||||
func (bs *BlobStore) Get(key string) (buf []byte, err error) {
|
||||
fn, err := bs.pathForKey(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.Open(fn)
|
||||
if e, ok := err.(*os.PathError); ok && (e.Error == os.ENOENT || e.Error == os.ENOTDIR) {
|
||||
if e, ok := err.(*os.PathError); ok && (e.Err == os.ENOENT || e.Err == os.ENOTDIR) {
|
||||
err = ErrNoSuchKey
|
||||
return
|
||||
} else if err != nil {
|
||||
|
|
@ -238,7 +238,7 @@ func (bs *BlobStore) Get(key string) (buf []byte, err os.Error) {
|
|||
|
||||
// Store a blob. If the blob was successfully stored, the returned key
|
||||
// can be used to retrieve the buf from the BlobStore.
|
||||
func (bs *BlobStore) Put(buf []byte) (key string, err os.Error) {
|
||||
func (bs *BlobStore) Put(buf []byte) (key string, err error) {
|
||||
// Calculate the key for the blob. We can't really delay it more than this,
|
||||
// since we need to know the key for the blob to check whether it's already on
|
||||
// disk.
|
||||
|
|
@ -263,7 +263,7 @@ func (bs *BlobStore) Put(buf []byte) (key string, err os.Error) {
|
|||
file.Close()
|
||||
return
|
||||
} else {
|
||||
if e, ok := err.(*os.PathError); ok && (e.Error == os.ENOENT || e.Error == os.ENOTDIR) {
|
||||
if e, ok := err.(*os.PathError); ok && (e.Err == os.ENOENT || e.Err == os.ENOTDIR) {
|
||||
// No such file exists on disk. Ready to rock!
|
||||
} else {
|
||||
return
|
||||
|
|
@ -315,10 +315,10 @@ func (bs *BlobStore) Put(buf []byte) (key string, err os.Error) {
|
|||
// On Unix, it checks for EEXIST. On Windows, it checks for EEXIST
|
||||
// and Errno code 183 (ERROR_ALREADY_EXISTS)
|
||||
func isExistError(err *os.PathError) (exists bool) {
|
||||
if e, ok := err.Error.(os.Errno); ok && e == win32AlreadyExists {
|
||||
if e, ok := err.Err.(os.Errno); ok && e == win32AlreadyExists {
|
||||
exists = true
|
||||
}
|
||||
if err.Error == os.EEXIST {
|
||||
if err.Err == os.EEXIST {
|
||||
exists = true
|
||||
}
|
||||
return
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ import (
|
|||
func TestMakeAllCreateAll(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, true)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -35,7 +35,7 @@ func TestMakeAllCreateAll(t *testing.T) {
|
|||
dirname := filepath.Join(dir, hex.EncodeToString([]byte{byte(i)}), hex.EncodeToString([]byte{byte(j)}))
|
||||
fi, err := os.Stat(dirname)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
if !fi.IsDirectory() {
|
||||
t.Errorf("Not a directory")
|
||||
|
|
@ -47,65 +47,65 @@ func TestMakeAllCreateAll(t *testing.T) {
|
|||
func TestAllInvalidFiles(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(dir, "00"), []byte{0x0f, 0x00}, 0600)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = NewBlobStore(dir, true)
|
||||
if err == ErrBadFile {
|
||||
// Success
|
||||
} else if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
} else {
|
||||
t.Errorf("NewBlobStore returned without error")
|
||||
t.Error("NewBlobStore returned without error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllInvalidFilesLevel2(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
err = os.Mkdir(filepath.Join(dir, "00"), 0700)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(dir, "00", "00"), []byte{0x0f, 0x00}, 0600)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = NewBlobStore(dir, true)
|
||||
if err == ErrBadFile {
|
||||
// Success
|
||||
} else if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
} else {
|
||||
t.Errorf("NewBlobStore returned without error")
|
||||
t.Error("NewBlobStore returned without error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreRetrieve(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -114,13 +114,13 @@ func TestStoreRetrieve(t *testing.T) {
|
|||
|
||||
key, err := bs.Put(data)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
recv, err := bs.Get(key)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(recv, data) {
|
||||
|
|
@ -131,14 +131,14 @@ func TestStoreRetrieve(t *testing.T) {
|
|||
func TestReadNonExistantKey(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -148,7 +148,7 @@ func TestReadNonExistantKey(t *testing.T) {
|
|||
key := hex.EncodeToString(h.Sum())
|
||||
buf, err := bs.Get(key)
|
||||
if err != ErrNoSuchKey {
|
||||
t.Errorf("Expected no such key %v, found it anyway. (buf=%v, err=%v)", key, buf, err)
|
||||
t.Error("Expected no such key %v, found it anyway. (buf=%v, err=%v)", key, buf, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -156,13 +156,13 @@ func TestReadNonExistantKey(t *testing.T) {
|
|||
func TestReadInvalidKeyLength(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -174,7 +174,7 @@ func TestReadInvalidKeyLength(t *testing.T) {
|
|||
|
||||
_, err = bs.Get(key)
|
||||
if err != ErrInvalidKey {
|
||||
t.Errorf("Expected invalid key for %v, got %v", key, err)
|
||||
t.Error("Expected invalid key for %v, got %v", key, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -182,14 +182,14 @@ func TestReadInvalidKeyLength(t *testing.T) {
|
|||
func TestReadInvalidKeyNonHex(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
bs, err := NewBlobStore(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer bs.Close()
|
||||
|
|
@ -209,26 +209,26 @@ func TestReadInvalidKeyNonHex(t *testing.T) {
|
|||
func TestDefaultBlobStore(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "blobstore")
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
err = Open(dir, false)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
data := []byte{0xf, 0x0, 0x0, 0xb, 0xa, 0xf}
|
||||
|
||||
key, err := Put(data)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
fetchedData, err := Get(key)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(fetchedData, data) {
|
||||
|
|
|
|||
|
|
@ -1,73 +1,73 @@
|
|||
// Copyright (c) 2011 The Grumble Authors
|
||||
// The use of this source code is goverened by a BSD-style
|
||||
// license that can be found in the LICENSE-file.
|
||||
|
||||
package blobstore
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
|
||||
package blobstore
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Acquire lockfile at path.
|
||||
func AcquireLockFile(path string) os.Error {
|
||||
dir, fn := filepath.Split(path)
|
||||
lockfn := filepath.Join(dir, fn)
|
||||
|
||||
lockfile, err := os.OpenFile(lockfn, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
|
||||
if e, ok := err.(*os.PathError); ok && e.Error == os.EEXIST {
|
||||
content, err := ioutil.ReadFile(lockfn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(string(content))
|
||||
if err == nil {
|
||||
if syscall.Kill(pid, 0) == 0 {
|
||||
return ErrLocked
|
||||
}
|
||||
}
|
||||
|
||||
lockfile, err = ioutil.TempFile(dir, "lock")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = lockfile.WriteString(strconv.Itoa(syscall.Getpid()))
|
||||
if err != nil {
|
||||
lockfile.Close()
|
||||
return ErrLockAcquirement
|
||||
}
|
||||
|
||||
curfn := lockfile.Name()
|
||||
|
||||
err = lockfile.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Rename(curfn, lockfn)
|
||||
if err != nil {
|
||||
os.Remove(curfn)
|
||||
return ErrLockAcquirement
|
||||
}
|
||||
} else if err != nil {
|
||||
return err
|
||||
} else {
|
||||
_, err = lockfile.WriteString(strconv.Itoa(syscall.Getpid()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lockfile.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func AcquireLockFile(path string) error {
|
||||
dir, fn := filepath.Split(path)
|
||||
lockfn := filepath.Join(dir, fn)
|
||||
|
||||
lockfile, err := os.OpenFile(lockfn, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
|
||||
if e, ok := err.(*os.PathError); ok && e.Err == os.EEXIST {
|
||||
content, err := ioutil.ReadFile(lockfn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(string(content))
|
||||
if err == nil {
|
||||
if syscall.Kill(pid, 0) == 0 {
|
||||
return ErrLocked
|
||||
}
|
||||
}
|
||||
|
||||
lockfile, err = ioutil.TempFile(dir, "lock")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = lockfile.WriteString(strconv.Itoa(syscall.Getpid()))
|
||||
if err != nil {
|
||||
lockfile.Close()
|
||||
return ErrLockAcquirement
|
||||
}
|
||||
|
||||
curfn := lockfile.Name()
|
||||
|
||||
err = lockfile.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Rename(curfn, lockfn)
|
||||
if err != nil {
|
||||
os.Remove(curfn)
|
||||
return ErrLockAcquirement
|
||||
}
|
||||
} else if err != nil {
|
||||
return err
|
||||
} else {
|
||||
_, err = lockfile.WriteString(strconv.Itoa(syscall.Getpid()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lockfile.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Release lockfile at path.
|
||||
func ReleaseLockFile(path string) os.Error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
func ReleaseLockFile(path string) error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,26 @@
|
|||
// Copyright (c) 2011 The Grumble Authors
|
||||
// The use of this source code is goverened by a BSD-style
|
||||
// license that can be found in the LICENSE-file.
|
||||
|
||||
package blobstore
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000
|
||||
)
|
||||
|
||||
|
||||
package blobstore
|
||||
|
||||
import "syscall"
|
||||
|
||||
const (
|
||||
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000
|
||||
)
|
||||
|
||||
// Acquire a lockfile at path.
|
||||
func AcquireLockFile(path string) os.Error {
|
||||
handle, _ := syscall.CreateFile(syscall.StringToUTF16Ptr(path), syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0)
|
||||
if handle < 0 {
|
||||
return ErrLocked
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func AcquireLockFile(path string) error {
|
||||
handle, _ := syscall.CreateFile(syscall.StringToUTF16Ptr(path), syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0)
|
||||
if handle < 0 {
|
||||
return ErrLocked
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Release the lockfile at path.
|
||||
func ReleaseLockFile(path string) os.Error {
|
||||
func ReleaseLockFile(path string) error {
|
||||
// No-op because we use FLAG_DELETE_ON_CLOSE.
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue