How to resume reading after EOF in a named pipe

I am writing a program that opens a named pipe for reading and then processes any lines written on that pipe:

err = syscall.Mkfifo("/tmp/myfifo", 0666)
if err != nil {
    panic(err)
}

pipe, err := os.OpenFile("/tmp/myfifo", os.O_RDONLY, os.ModeNamedPipe)
if err != nil {
    panic(err)
}

reader := bufio.NewReader(pipe)
scanner := bufio.NewScanner(reader)

for scanner.Scan() {
    line := scanner.Text()
    process(line)
}

      

This works fine until the write process restarts or sends an EOF for other reasons. When this happens, the loop ends (as expected from the spec Scanner

).

However, I want the channel to be open to receive further entries. I could just reinitialize the scanner, but I believe this will create a race condition where the scanner might not be ready when a new process starts writing to the pipe.

Are there any other options? Do I need to work directly with the type File

?

+3


source to share


1 answer


From bufio GoDoc :

Scan ... returns false when scanning stops, either reaching the end of input, or an error.



This way you can leave the file open and read until EOF and then run again scanner.Scan()

when the file has changed or at regular intervals (i.e. do a goroutine) and make sure the variable is pipe

out of scope so you can reference it again ...

If I understand your concern about the race condition correctly, this won't be a problem (unless the read and write operations need to be synchronized), but when the scanner is reinitialized it will return at the beginning of the file.

0


source







All Articles