]> Sergey Matveev's repositories - mmc.git/blob - lock.go
internal package
[mmc.git] / lock.go
1 // mmc -- Mattermost client
2 // Copyright (C) 2023-2024 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU Affero General Public License for more details.
13 //
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 package mmc
18
19 import (
20         "io"
21         "os"
22
23         "golang.org/x/sys/unix"
24 )
25
26 func Lock(what string) (func(), error) {
27         fd, err := os.OpenFile(
28                 what,
29                 os.O_WRONLY|os.O_TRUNC|os.O_CREATE,
30                 os.FileMode(0666),
31         )
32         dummy := func() {}
33         if err != nil {
34                 return dummy, err
35         }
36         flock := unix.Flock_t{
37                 Type:   unix.F_WRLCK,
38                 Whence: io.SeekStart,
39         }
40         if err = unix.FcntlFlock(fd.Fd(), unix.F_SETLKW, &flock); err != nil {
41                 fd.Close()
42                 return dummy, err
43         }
44         return func() {
45                 flock.Type = unix.F_UNLCK
46                 unix.FcntlFlock(fd.Fd(), unix.F_SETLK, &flock)
47                 fd.Close()
48         }, nil
49 }