storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/lock/lock_solaris.go (about) 1 //go:build solaris 2 // +build solaris 3 4 /* 5 * MinIO Cloud Storage, (C) 2017 MinIO, Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package lock 21 22 import ( 23 "os" 24 "syscall" 25 ) 26 27 // lockedOpenFile is an internal function. 28 func lockedOpenFile(path string, flag int, perm os.FileMode, rlockType int) (*LockedFile, error) { 29 var lockType int16 30 switch flag { 31 case syscall.O_RDONLY: 32 lockType = syscall.F_RDLCK 33 case syscall.O_WRONLY: 34 fallthrough 35 case syscall.O_RDWR: 36 fallthrough 37 case syscall.O_WRONLY | syscall.O_CREAT: 38 fallthrough 39 case syscall.O_RDWR | syscall.O_CREAT: 40 lockType = syscall.F_WRLCK 41 default: 42 return nil, &os.PathError{ 43 Op: "open", 44 Path: path, 45 Err: syscall.EINVAL, 46 } 47 } 48 49 var lock = syscall.Flock_t{ 50 Start: 0, 51 Len: 0, 52 Pid: 0, 53 Type: lockType, 54 Whence: 0, 55 } 56 57 f, err := os.OpenFile(path, flag, perm) 58 if err != nil { 59 return nil, err 60 } 61 62 if err = syscall.FcntlFlock(f.Fd(), rlockType, &lock); err != nil { 63 f.Close() 64 if err == syscall.EAGAIN { 65 err = ErrAlreadyLocked 66 } 67 return nil, err 68 } 69 70 st, err := os.Stat(path) 71 if err != nil { 72 f.Close() 73 return nil, err 74 } 75 76 if st.IsDir() { 77 f.Close() 78 return nil, &os.PathError{ 79 Op: "open", 80 Path: path, 81 Err: syscall.EISDIR, 82 } 83 } 84 85 return &LockedFile{f}, nil 86 } 87 88 // TryLockedOpenFile - tries a new write lock, functionality 89 // it is similar to LockedOpenFile with with syscall.LOCK_EX 90 // mode but along with syscall.LOCK_NB such that the function 91 // doesn't wait forever but instead returns if it cannot 92 // acquire a write lock. 93 func TryLockedOpenFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { 94 return lockedOpenFile(path, flag, perm, syscall.F_SETLK) 95 } 96 97 // LockedOpenFile - initializes a new lock and protects 98 // the file from concurrent access across mount points. 99 // This implementation doesn't support all the open 100 // flags and shouldn't be considered as replacement 101 // for os.OpenFile(). 102 func LockedOpenFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { 103 return lockedOpenFile(path, flag, perm, syscall.F_SETLKW) 104 } 105 106 // Open - Call os.OpenFile 107 func Open(path string, flag int, perm os.FileMode) (*os.File, error) { 108 return os.OpenFile(path, flag, perm) 109 }