diff options
author | root <sina@snix.ir> | 2022-03-04 09:45:28 +0000 |
---|---|---|
committer | root <sina@snix.ir> | 2022-03-04 09:45:28 +0000 |
commit | 7051e0896a5df51c00d09f1fa1936bc5ae7a6c9e (patch) | |
tree | f8ac703611469f9190de87a2d698288fcf9f2c8e /sysv |
gosema ipc sysv linux
Diffstat (limited to 'sysv')
-rw-r--r-- | sysv/ftok.go | 16 | ||||
-rw-r--r-- | sysv/sem.go | 106 |
2 files changed, 122 insertions, 0 deletions
diff --git a/sysv/ftok.go b/sysv/ftok.go new file mode 100644 index 0000000..94d73cf --- /dev/null +++ b/sysv/ftok.go @@ -0,0 +1,16 @@ +package sysv + +import ( + "golang.org/x/sys/unix" +) + +func Ftok(p string, id uint) (uint, error) { + fss := &unix.Stat_t{} + if err := unix.Stat(p, fss); err != nil { + return 0, err + } + + return uint((uint(fss.Ino) & 0xffff) | + uint((fss.Dev&0xff)<<16) | + ((id & 0xff) << 24)), nil +} diff --git a/sysv/sem.go b/sysv/sem.go new file mode 100644 index 0000000..631a16b --- /dev/null +++ b/sysv/sem.go @@ -0,0 +1,106 @@ +package sysv + +import ( + "unsafe" + + "golang.org/x/sys/unix" +) + +const ( + SYS_GETPID int = 0x0B + iota + SYS_GETVAL + SYS_SETVAL int = 0x010 +) + +const ( + non = iota - one + one = 0x01 + zro = 0x00 +) + +type oprations struct { + num uint16 + opt int16 + flg int16 +} + +type Semaphore struct { + nums int + smid int +} + +func NewSemGet(key, nums, flags int) (*Semaphore, error) { + id, _, errno := unix.Syscall( + unix.SYS_SEMGET, uintptr(key), + uintptr(nums), uintptr(flags), + ) + if errno != 0 { + return nil, error(errno) + } + return &Semaphore{nums: nums, smid: int(id)}, nil +} + +func (sem *Semaphore) GetVal(semnum int) (int, error) { + vl, _, errno := unix.Syscall( + unix.SYS_SEMCTL, uintptr(sem.smid), + uintptr(semnum), uintptr(SYS_GETVAL), + ) + if errno != 0 { + return int(vl), error(errno) + } + return int(vl), nil +} + +func (sem *Semaphore) SetVal(semnum, v int) error { + _, _, errno := unix.Syscall6( + unix.SYS_SEMCTL, uintptr(sem.smid), + uintptr(semnum), uintptr(SYS_SETVAL), uintptr(v), 0, 0, + ) + if errno != 0 { + return error(errno) + } + return nil +} + +func (sem *Semaphore) GetPID(semnum int) (int, error) { + pid, _, errno := unix.Syscall( + unix.SYS_SEMCTL, uintptr(sem.smid), + uintptr(semnum), uintptr(SYS_GETPID), + ) + if errno != 0 { + return int(pid), error(errno) + } + return int(pid), nil +} + +func (sem *Semaphore) setops(n uint16, o, f int16) error { + opt := oprations{num: n, opt: o, flg: f} + _, _, errno := unix.Syscall( + unix.SYS_SEMOP, uintptr(sem.smid), + uintptr(unsafe.Pointer(&opt)), uintptr(sem.nums), + ) + + if errno != 0 { + return error(errno) + } + return nil +} + +func (sem *Semaphore) Lock(semnum int) error { + return sem.setops(uint16(semnum), non, zro) +} + +func (sem *Semaphore) Unlock(semnum int) error { + return sem.setops(uint16(semnum), one, zro) +} + +func (sem *Semaphore) DelSem() error { + _, _, errno := unix.Syscall( + unix.SYS_SEMCTL, uintptr(sem.smid), + uintptr(0), uintptr(unix.IPC_RMID), + ) + if errno != 0 { + return error(errno) + } + return nil +} |