В приложении я создаю gdb и подключаю его stdout
(и другие) к каналам. Затем я epoll_wait
в этом канале (и других), чтобы получать уведомления о получении ответа от gdb.
Каждый раз, когда epoll_wait
просыпается с положительным возвращаемым значением (есть fd для чтения), я читаю одну строку из канала stdout
gdb (если это fd с событием) и возвращаюсь к epoll_wait
.
Все это работает нормально, за исключением того, что иногда последняя строка ответа gdb (которая неизменно "(gdb)\n"
) не читается, а epoll_wait
возвращает 0 навсегда. Если я подожду несколько секунд, а затем прочитаю из канала stdout
gdb, несмотря на то, что epoll_wait
возвращает 0, я могу получить строку "(gdb)\n"
.
В чем дело? Эти данные явно находятся в конвейере и готовы к чтению, но epoll, запускаемый уровнем, не генерирует для них событие.
Некоторые примечания:
- Канал, подключенный к
stdout
gdb, создается с помощьюO_NONBLOCK
. epoll_create1
вызывается сEPOLL_CLOEXEC
(и никак иначе), т.е. срабатывает по уровню.- Я использую GNU
getline()
для чтения строки - После каждого вызова
getline()
яclearerr()
выполняю fd конвейера (я делаю это, потому что в тестовом приложении я заметил, достигнут ли конец EOF (потому что другой конец конвейера не закончил запись всей строки до того, как я ее прочитал), функции на основе stdio застревают, думая, что EOF достигнут. Я могу справиться с чтением строки по частям, так что это нормально. Я также пытался удалить вызовclearerr()
безрезультатно) - Если я добавлю задержку в одну секунду после каждой прочитанной строки и перед повторным
epoll_wait
ing,epoll_wait
немедленно вернетstdout
fd для каждой строки исходного сообщения версии+лицензии, но не для последней"(gdb)\n"
строки.