update ipc

This commit is contained in:
hslam 2020-11-30 18:20:17 +08:00
parent ed1be34b5c
commit afc7e4e499
6 changed files with 115 additions and 36 deletions

View File

@ -43,7 +43,18 @@ var send = flag.Bool("s", true, "send")
func main() {
flag.Parse()
key, _ := ipc.Ftok("/tmp", 0x22)
semid, _ := ipc.Semget(key)
semnum := 0
semid, err := ipc.Semget(key, 1, 0666)
if err != nil {
semid, err = ipc.Semget(key, 1, ipc.IPC_CREAT|ipc.IPC_EXCL|0666)
if err != nil {
panic(err)
}
_, err := ipc.Semsetvalue(semid, semnum, 1)
if err != nil {
panic(err)
}
}
defer ipc.Semrm(semid)
shmid, data, _ := ipc.Shmgetat(key, 128, ipc.IPC_CREAT|0600)
defer ipc.Shmrm(shmid)
@ -60,11 +71,11 @@ func main() {
buf := make([]byte, 10)
for {
fmt.Scanln(&text)
if _, err := ipc.Semp(semid, ipc.SEM_UNDO); err != nil {
if _, err := ipc.Semp(semid, semnum, ipc.SEM_UNDO); err != nil {
return
}
copy(data, text)
if _, err := ipc.Semv(semid, ipc.SEM_UNDO); err != nil {
if _, err := ipc.Semv(semid, semnum, ipc.SEM_UNDO); err != nil {
return
}
n := binary.PutUvarint(buf, uint64(len(text)))
@ -80,11 +91,11 @@ func main() {
return
}
length, _ := binary.Uvarint(m)
if _, err := ipc.Semp(semid, ipc.SEM_UNDO); err != nil {
if _, err := ipc.Semp(semid, semnum, ipc.SEM_UNDO); err != nil {
return
}
text = string(data[:length])
if _, err := ipc.Semv(semid, ipc.SEM_UNDO); err != nil {
if _, err := ipc.Semv(semid, semnum, ipc.SEM_UNDO); err != nil {
return
}
fmt.Println(text)

7
ipc.go
View File

@ -8,14 +8,17 @@ package ipc
const (
// IPC_CREAT creates if key is nonexistent
IPC_CREAT = 00001000
IPC_CREAT = 01000
// IPC_EXCL fails if key exists.
IPC_EXCL = 00002000
IPC_EXCL = 02000
// IPC_NOWAIT returns error no wait.
IPC_NOWAIT = 04000
// IPC_PRIVATE is private key
IPC_PRIVATE = 00000
// SEM_UNDO sets up adjust on exit entry
SEM_UNDO = 010000

View File

@ -4,6 +4,7 @@
package ipc
import (
"github.com/hslam/sem"
"strings"
"testing"
"time"
@ -12,21 +13,31 @@ import (
func TestIPC(t *testing.T) {
context := strings.Repeat("1", 64)
done := make(chan struct{})
semnum := 0
go func() {
key, _ := Ftok("/tmp", 0x22)
semid, _ := Semget(key)
semid, err := Semget(key, 1, 0600)
if err != nil {
semid, err = Semget(key, 1, IPC_CREAT|IPC_EXCL|0600)
if err != nil {
panic(err)
}
_, err := Semsetvalue(semid, semnum, 1)
if err != nil {
panic(err)
}
}
defer Semrm(semid)
shmid, data, _ := Shmgetat(key, 128, IPC_CREAT|0600)
defer Shmrm(shmid)
defer Shmdt(data)
msgid, _ := Msgget(key, IPC_CREAT|0600)
defer Msgrm(msgid)
if _, err := Semp(semid, SEM_UNDO); err != nil {
if _, err := Semp(semid, semnum, SEM_UNDO); err != nil {
return
}
copy(data, context)
if _, err := Semv(semid, SEM_UNDO); err != nil {
if _, err := Semv(semid, semnum, SEM_UNDO); err != nil {
return
}
if err := Msgsnd(msgid, 1, []byte{byte(len(context))}, 0600); err != nil {
@ -39,12 +50,22 @@ func TestIPC(t *testing.T) {
time.Sleep(time.Millisecond * 100)
key, _ := Ftok("/tmp", 0x22)
semid, _ := Semget(key)
semid, err := Semget(key, 1, 0600)
if err != nil {
semid, err = Semget(key, 1, IPC_CREAT|IPC_EXCL|0600)
if err != nil {
panic(err)
}
_, err := Semsetvalue(semid, semnum, 1)
if err != nil {
panic(err)
}
}
defer Semrm(semid)
shmid, data, _ := Shmgetat(key, 128, IPC_CREAT|0600)
shmid, data, _ := Shmgetat(key, 128, 0600)
defer Shmrm(shmid)
defer Shmdt(data)
msgid, _ := Msgget(key, IPC_CREAT|0600)
msgid, _ := Msgget(key, 0600)
defer Msgrm(msgid)
m, err := Msgrcv(msgid, 1, 0600)
@ -52,16 +73,20 @@ func TestIPC(t *testing.T) {
return
}
length := int(m[0])
if ret, err := Semgetvalue(semid); err != nil {
if ret, err := Semgetvalue(semid, semnum); err != nil {
t.Error(err)
} else if ret < 1 {
t.Error()
}
if _, err := Semp(semid, SEM_UNDO); err != nil {
var sops [1]sem.Sembuf
sops[0] = sem.Sembuf{SemNum: uint16(semnum), SemFlg: SEM_UNDO}
sops[0].SemOp = -1
if _, err := Semop(semid, sops[:]); err != nil {
return
}
text := string(data[:length])
if _, err := Semv(semid, SEM_UNDO); err != nil {
sops[0].SemOp = 1
if _, err := Semop(semid, sops[:]); err != nil {
return
}

8
msg.go
View File

@ -8,21 +8,21 @@ import (
)
// Msgget calls the msgget system call.
func Msgget(key int, msgflg int) (uintptr, error) {
func Msgget(key int, msgflg int) (int, error) {
return msg.Get(key, msgflg)
}
// Msgsnd calls the msgsnd system call.
func Msgsnd(msgid uintptr, msgType uint, msgText []byte, flags uint) error {
func Msgsnd(msgid int, msgType uint, msgText []byte, flags int) error {
return msg.Snd(msgid, msgType, msgText, flags)
}
// Msgrcv calls the msgrcv system call.
func Msgrcv(msgid uintptr, msgType uint, flags uint) ([]byte, error) {
func Msgrcv(msgid int, msgType uint, flags int) ([]byte, error) {
return msg.Rcv(msgid, msgType, flags)
}
// Msgrm removes the shm with the given id.
func Msgrm(msgid uintptr) error {
func Msgrm(msgid int) error {
return msg.Remove(msgid)
}

66
sem.go
View File

@ -8,26 +8,66 @@ import (
)
// Semget calls the semget system call.
func Semget(key int) (uintptr, error) {
return sem.Get(key)
//
// The semget() system call returns the System V semaphore set identifier
// associated with the argument key.
//
// A new set of nsems semaphores is created if key has the value
// IPC_PRIVATE or if no existing semaphore set is associated with key
// and IPC_CREAT is specified in semflg.
//
// If semflg specifies both IPC_CREAT and IPC_EXCL and a semaphore set
// already exists for key, then semget() fails with errno set to EEXIST.
//
// The argument nsems can be 0 (a don't care) when a semaphore set is
// not being created. Otherwise, nsems must be greater than 0 and less
// than or equal to the maximum number of semaphores per semaphore set.
//
// If successful, the return value will be the semaphore set identifier,
// otherwise, -1 is returned, with errno indicating the error.
func Semget(key int, nsems int, semflg int) (int, error) {
return sem.Get(key, nsems, semflg)
}
// Semp calls the semop P system call.
func Semp(semid uintptr, flg int16) (bool, error) {
return sem.P(semid, flg)
}
// Semv calls the semop V system call.
func Semv(semid uintptr, flg int16) (bool, error) {
return sem.V(semid, flg)
// Semsetvalue calls the semctl SETVAL system call.
func Semsetvalue(semid int, semnum int, semun int) (bool, error) {
return sem.SetValue(semid, semnum, semun)
}
// Semgetvalue calls the semctl GETVAL system call.
func Semgetvalue(semid uintptr) (int, error) {
return sem.GetValue(semid)
func Semgetvalue(semid int, semnum int) (int, error) {
return sem.GetValue(semid, semnum)
}
// Semp calls the semop P system call.
// Flags recognized in semflg are IPC_NOWAIT and SEM_UNDO.
// If an operation specifies SEM_UNDO, it will be automatically undone when the
// process terminates.
func Semp(semid int, semnum int, semflg int) (bool, error) {
return sem.P(semid, semnum, semflg)
}
// Semv calls the semop V system call.
// Flags recognized in semflg are IPC_NOWAIT and SEM_UNDO.
// If an operation specifies SEM_UNDO, it will be automatically undone when the
// process terminates.
func Semv(semid int, semnum int, semflg int) (bool, error) {
return sem.V(semid, semnum, semflg)
}
// Semop calls the semop system call.
// Flags recognized in SemFlg are IPC_NOWAIT and SEM_UNDO.
// If an operation specifies SEM_UNDO, it will be automatically undone when the
// process terminates.
// Op calls the semop system call.
// Flags recognized in SemFlg are IPC_NOWAIT and SEM_UNDO.
// If an operation specifies SEM_UNDO, it will be automatically undone when the
// process terminates.
func Semop(semid int, sops []sem.Sembuf) (bool, error) {
return sem.Op(semid, sops)
}
// Semrm removes the semaphore with the given id.
func Semrm(semid uintptr) error {
func Semrm(semid int) error {
return sem.Remove(semid)
}

4
shm.go
View File

@ -8,7 +8,7 @@ import (
)
// Shmgetat calls the shmget and shmat system call.
func Shmgetat(key int, size int, shmFlg int) (uintptr, []byte, error) {
func Shmgetat(key int, size int, shmFlg int) (int, []byte, error) {
return shm.GetAt(key, size, shmFlg)
}
@ -18,6 +18,6 @@ func Shmdt(b []byte) error {
}
// Shmrm removes the shm with the given id.
func Shmrm(shmid uintptr) error {
func Shmrm(shmid int) error {
return shm.Remove(shmid)
}