From 39c7060d3bb99b99b099a3515ec3d7b11b86c93d Mon Sep 17 00:00:00 2001 From: Alexander Kolbasov Date: Fri, 24 Apr 2015 12:18:08 -0700 Subject: [PATCH] pkg/fileutil: add filelock support for solaris --- pkg/fileutil/lock_solaris.go | 98 ++++++++++++++++++++++++++++++++++++ pkg/fileutil/lock_unix.go | 2 +- 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 pkg/fileutil/lock_solaris.go diff --git a/pkg/fileutil/lock_solaris.go b/pkg/fileutil/lock_solaris.go new file mode 100644 index 000000000..1929bd1fc --- /dev/null +++ b/pkg/fileutil/lock_solaris.go @@ -0,0 +1,98 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build solaris + +package fileutil + +import ( + "errors" + "os" + "syscall" +) + +var ( + ErrLocked = errors.New("file already locked") +) + +type Lock interface { + Name() string + TryLock() error + Lock() error + Unlock() error + Destroy() error +} + +type lock struct { + fd int + file *os.File +} + +func (l *lock) Name() string { + return l.file.Name() +} + +// TryLock acquires exclusivity on the lock without blocking +func (l *lock) TryLock() error { + var lock syscall.Flock_t + lock.Start = 0 + lock.Len = 0 + lock.Pid = 0 + lock.Type = syscall.F_WRLCK + lock.Whence = 0 + lock.Pid = 0 + err := syscall.FcntlFlock(uintptr(l.fd), syscall.F_SETLK, &lock) + if err != nil && err == syscall.EAGAIN { + return ErrLocked + } + return err +} + +// Lock acquires exclusivity on the lock without blocking +func (l *lock) Lock() error { + var lock syscall.Flock_t + lock.Start = 0 + lock.Len = 0 + lock.Type = syscall.F_WRLCK + lock.Whence = 0 + lock.Pid = 0 + return syscall.FcntlFlock(uintptr(l.fd), syscall.F_SETLK, &lock) +} + +// Unlock unlocks the lock +func (l *lock) Unlock() error { + var lock syscall.Flock_t + lock.Start = 0 + lock.Len = 0 + lock.Type = syscall.F_UNLCK + lock.Whence = 0 + err := syscall.FcntlFlock(uintptr(l.fd), syscall.F_SETLK, &lock) + if err != nil && err == syscall.EAGAIN { + return ErrLocked + } + return err +} + +func (l *lock) Destroy() error { + return l.file.Close() +} + +func NewLock(file string) (Lock, error) { + f, err := os.OpenFile(file, os.O_WRONLY, 0600) + if err != nil { + return nil, err + } + l := &lock{int(f.Fd()), f} + return l, nil +} diff --git a/pkg/fileutil/lock_unix.go b/pkg/fileutil/lock_unix.go index ce7bc9d6f..f6e69cc34 100644 --- a/pkg/fileutil/lock_unix.go +++ b/pkg/fileutil/lock_unix.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows,!plan9 +// +build !windows,!plan9,!solaris package fileutil