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 } }