update archive method
parent
1632256ded
commit
9adabd6723
@ -0,0 +1 @@
|
||||
package starlog
|
@ -0,0 +1,44 @@
|
||||
package staros
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
var ERR_ALREADY_LOCKED = errors.New("ALREADY LOCKED")
|
||||
var ERR_TIMEOUT = errors.New("TIME OUT")
|
||||
|
||||
func NewFileLock(filepath string) FileLock {
|
||||
return FileLock{
|
||||
filepath: filepath,
|
||||
}
|
||||
}
|
||||
|
||||
// 检测文件/文件夹是否存在
|
||||
func Exists(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// IsFile 返回给定文件地址是否是一个文件,
|
||||
//True为是一个文件,False为不是文件或路径无效
|
||||
func IsFile(fpath string) bool {
|
||||
s, err := os.Stat(fpath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return !s.IsDir()
|
||||
}
|
||||
|
||||
// IsFolder 返回给定文件地址是否是一个文件夹,
|
||||
//True为是一个文件夹,False为不是文件夹或路径无效
|
||||
func IsFolder(fpath string) bool {
|
||||
s, err := os.Stat(fpath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return s.IsDir()
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
//+build darwin
|
||||
|
||||
package staros
|
||||
|
||||
import (
|
||||
"b612.me/stario"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileLock struct {
|
||||
fd int
|
||||
filepath string
|
||||
}
|
||||
|
||||
func (f *FileLock) openFileForLock() error {
|
||||
fd, err := syscall.Open(f.filepath, syscall.O_CREAT|syscall.O_RDONLY, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.filepath = f.filepath
|
||||
f.fd = fd
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileLock) Lock(Exclusive bool) error {
|
||||
var lockType int
|
||||
if Exclusive {
|
||||
lockType = syscall.LOCK_EX
|
||||
} else {
|
||||
lockType = syscall.LOCK_SH
|
||||
}
|
||||
if err := f.openFileForLock(); err != nil {
|
||||
return err
|
||||
}
|
||||
return syscall.Flock(f.fd, lockType)
|
||||
}
|
||||
|
||||
func (f *FileLock) LockNoBlocking(Exclusive bool) error {
|
||||
var lockType int
|
||||
if Exclusive {
|
||||
lockType = syscall.LOCK_EX
|
||||
} else {
|
||||
lockType = syscall.LOCK_SH
|
||||
}
|
||||
if err := f.openFileForLock(); err != nil {
|
||||
return err
|
||||
}
|
||||
err := syscall.Flock(f.fd, lockType|syscall.LOCK_NB)
|
||||
if err != nil {
|
||||
syscall.Close(f.fd)
|
||||
if err == syscall.EWOULDBLOCK {
|
||||
return ERR_ALREADY_LOCKED
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *FileLock) Unlock() error {
|
||||
err := syscall.Flock(f.fd, syscall.LOCK_UN)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return syscall.Close(f.fd)
|
||||
}
|
||||
|
||||
func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error {
|
||||
return stario.WaitUntilTimeout(tm, func(tmout chan struct{}) error {
|
||||
err := f.Lock(Exclusive)
|
||||
select {
|
||||
case <-tmout:
|
||||
f.Unlock()
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func timespecToTime(ts syscall.Timespec) time.Time {
|
||||
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||
}
|
||||
|
||||
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctimespec)
|
||||
}
|
||||
|
||||
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atimespec)
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
//+build linux
|
||||
|
||||
package staros
|
||||
|
||||
import (
|
||||
"b612.me/stario"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileLock struct {
|
||||
fd int
|
||||
filepath string
|
||||
}
|
||||
|
||||
func timespecToTime(ts syscall.Timespec) time.Time {
|
||||
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||
}
|
||||
|
||||
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctim)
|
||||
}
|
||||
|
||||
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atim)
|
||||
}
|
||||
|
||||
func (f *FileLock) openFileForLock() error {
|
||||
fd, err := syscall.Open(f.filepath, syscall.O_CREAT|syscall.O_RDONLY, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.filepath = f.filepath
|
||||
f.fd = fd
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileLock) Lock(Exclusive bool) error {
|
||||
var lockType int
|
||||
if Exclusive {
|
||||
lockType = syscall.LOCK_EX
|
||||
} else {
|
||||
lockType = syscall.LOCK_SH
|
||||
}
|
||||
if err := f.openFileForLock(); err != nil {
|
||||
return err
|
||||
}
|
||||
return syscall.Flock(f.fd, lockType)
|
||||
}
|
||||
|
||||
func (f *FileLock) LockNoBlocking(Exclusive bool) error {
|
||||
var lockType int
|
||||
if Exclusive {
|
||||
lockType = syscall.LOCK_EX
|
||||
} else {
|
||||
lockType = syscall.LOCK_SH
|
||||
}
|
||||
if err := f.openFileForLock(); err != nil {
|
||||
return err
|
||||
}
|
||||
err := syscall.Flock(f.fd, lockType|syscall.LOCK_NB)
|
||||
if err != nil {
|
||||
syscall.Close(f.fd)
|
||||
if err == syscall.EWOULDBLOCK {
|
||||
return ERR_ALREADY_LOCKED
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *FileLock) Unlock() error {
|
||||
err := syscall.Flock(f.fd, syscall.LOCK_UN)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return syscall.Close(f.fd)
|
||||
}
|
||||
|
||||
func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error {
|
||||
return stario.WaitUntilTimeout(tm, func(tmout chan struct{}) error {
|
||||
err := f.Lock(Exclusive)
|
||||
select {
|
||||
case <-tmout:
|
||||
f.Unlock()
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
// +build windows
|
||||
|
||||
package staros
|
||||
|
||||
import (
|
||||
"b612.me/win32api"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileLock struct {
|
||||
filepath string
|
||||
handle win32api.HANDLE
|
||||
}
|
||||
|
||||
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||
return time.Unix(0, d.CreationTime.Nanoseconds())
|
||||
}
|
||||
|
||||
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||
return time.Unix(0, d.LastAccessTime.Nanoseconds())
|
||||
}
|
||||
|
||||
func SetFileTimes(file *os.File, info os.FileInfo) {
|
||||
|
||||
}
|
||||
|
||||
func SetFileTimesbyTime(file *os.File) {
|
||||
|
||||
}
|
||||
|
||||
func (f *FileLock) openFileForLock() error {
|
||||
name, err := syscall.UTF16PtrFromString(f.filepath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
handle, err := syscall.CreateFile(
|
||||
name,
|
||||
syscall.GENERIC_READ,
|
||||
syscall.FILE_SHARE_READ,
|
||||
nil,
|
||||
syscall.OPEN_ALWAYS,
|
||||
syscall.FILE_FLAG_OVERLAPPED|0x00000080,
|
||||
0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.handle = win32api.HANDLE(handle)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileLock) lockForTimeout(timeout time.Duration, lockType win32api.DWORD) error {
|
||||
var err error
|
||||
if err = f.openFileForLock(); err != nil {
|
||||
return err
|
||||
}
|
||||
event, err := win32api.CreateEventW(nil, true, false, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
myEvent := &syscall.Overlapped{HEvent: syscall.Handle(event)}
|
||||
defer syscall.CloseHandle(myEvent.HEvent)
|
||||
_, err = win32api.LockFileEx(f.handle, lockType, 0, 1, 0, myEvent)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if err != syscall.ERROR_IO_PENDING {
|
||||
return err
|
||||
}
|
||||
millis := uint32(syscall.INFINITE)
|
||||
if timeout >= 0 {
|
||||
millis = uint32(timeout.Nanoseconds() / 1000000)
|
||||
}
|
||||
s, err := syscall.WaitForSingleObject(myEvent.HEvent, millis)
|
||||
switch s {
|
||||
case syscall.WAIT_OBJECT_0:
|
||||
// success!
|
||||
return nil
|
||||
case syscall.WAIT_TIMEOUT:
|
||||
f.Unlock()
|
||||
return ERR_TIMEOUT
|
||||
default:
|
||||
f.Unlock()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FileLock) Lock(Exclusive bool) error {
|
||||
var lockType win32api.DWORD
|
||||
if Exclusive {
|
||||
lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK
|
||||
} else {
|
||||
lockType = 0
|
||||
}
|
||||
return f.lockForTimeout(0, lockType)
|
||||
}
|
||||
|
||||
func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error {
|
||||
var lockType win32api.DWORD
|
||||
if Exclusive {
|
||||
lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK
|
||||
} else {
|
||||
lockType = 0
|
||||
}
|
||||
return f.lockForTimeout(tm, lockType)
|
||||
}
|
||||
|
||||
func (f *FileLock) LockNoBlocking(Exclusive bool) error {
|
||||
var lockType win32api.DWORD
|
||||
if Exclusive {
|
||||
lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK
|
||||
} else {
|
||||
lockType = 0
|
||||
}
|
||||
return f.lockForTimeout(0, lockType|win32api.LOCKFILE_FAIL_IMMEDIATELY)
|
||||
}
|
||||
|
||||
func (f *FileLock) Unlock() error {
|
||||
return syscall.Close(syscall.Handle(f.handle))
|
||||
}
|
Loading…
Reference in New Issue