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 solaris
8
9package storage
10
11import (
12	"os"
13	"syscall"
14)
15
16type unixFileLock struct {
17	f *os.File
18}
19
20func (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
27func 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
50func setFileLock(f *os.File, readOnly, lock bool) error {
51	flock := syscall.Flock_t{
52		Type:   syscall.F_UNLCK,
53		Start:  0,
54		Len:    0,
55		Whence: 1,
56	}
57	if lock {
58		if readOnly {
59			flock.Type = syscall.F_RDLCK
60		} else {
61			flock.Type = syscall.F_WRLCK
62		}
63	}
64	return syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &flock)
65}
66
67func rename(oldpath, newpath string) error {
68	return os.Rename(oldpath, newpath)
69}
70
71func syncDir(name string) error {
72	f, err := os.Open(name)
73	if err != nil {
74		return err
75	}
76	defer f.Close()
77	if err := f.Sync(); err != nil {
78		return err
79	}
80	return nil
81}
82