cwtch/event/bridge/pipeBridge.go

95 lines
2.2 KiB
Go
Raw Normal View History

package bridge
import (
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"cwtch.im/cwtch/event"
"encoding/json"
"os"
"sync"
"syscall"
)
/* pipeBridge creates a pair of named pipes
Needs a call to new client and service to fully successfully open
*/
type pipeBridge struct {
in, out *os.File
closedChan chan bool
closed bool
lock sync.Mutex
}
// NewPipeBridgeClient returns a pipe backed IPCBridge for a client
func NewPipeBridgeClient(inFilename, outFilename string) (event.IPCBridge, error) {
log.Debugf("Making new PipeBridge Client...\n")
syscall.Mkfifo(inFilename, 0600)
in, err := os.OpenFile(inFilename, os.O_RDONLY, 0600)
if err != nil {
return nil, err
}
syscall.Mkfifo(outFilename, 0600)
out, err := os.OpenFile(outFilename, os.O_WRONLY, 0600)
if err != nil {
return nil, err
}
pb := &pipeBridge{in: in, out: out, closedChan: make(chan bool), closed: false}
log.Debugf("Successfully created new PipeBridge Client!\n")
return pb, nil
}
// NewPipeBridgeService returns a pipe backed IPCBridge for a service
func NewPipeBridgeService(inFilename, outFilename string) (event.IPCBridge, error) {
log.Debugf("Making new PipeBridge Service...\n")
syscall.Mkfifo(outFilename, 0600)
out, err := os.OpenFile(outFilename, os.O_WRONLY, 0600)
if err != nil {
return nil, err
}
syscall.Mkfifo(inFilename, 0600)
in, err := os.OpenFile(inFilename, os.O_RDONLY, 0600)
if err != nil {
return nil, err
}
pb := &pipeBridge{in: in, out: out, closedChan: make(chan bool), closed: false}
log.Debugf("Successfully created new PipeBridge Service!\n")
return pb, nil
}
func (pb *pipeBridge) Read() (message event.IPCMessage, ok bool) {
dec := json.NewDecoder(pb.in)
err := dec.Decode(&message)
if err != nil {
log.Errorf("Read error: %v", err)
return event.IPCMessage{}, false
}
return message, true
}
func (pb *pipeBridge) Write(message *event.IPCMessage) {
pb.lock.Lock()
defer pb.lock.Unlock()
if !pb.closed {
messageJSON, _ := json.Marshal(message)
pb.out.Write(messageJSON)
}
}
func (pb *pipeBridge) Shutdown() {
pb.lock.Lock()
defer pb.lock.Unlock()
if !pb.closed {
pb.in.Close()
pb.out.Close()
pb.closed = true
}
}