Estou tentando usar luv para construir um plugin emulador de NES que pode se comunicar com outro processo sem pausar a emulação do jogo. Eu tinha algo que estava funcionando perfeitamente quando testei digitando manualmente os dados de entrada, mas quando fui testar a comunicação com outro processo por meio de um pipe, o script lua nunca pareceu receber nenhum dado.
Como um exemplo mínimo reproduzível, use o seguinte script lua:
local uv = require("luv")
local stdin = uv.new_poll(1)
stdin:start("r", function() print("uv callback") end)
uv.run("once")
Quando pressiono Enter manualmente, tudo funciona como esperado:
% lua-5.1 min.lua
uv callback
%
Entretanto, passar uma linha em branco de outro programa por meio de um pipe não parece funcionar:
% echo | lua-5.1 min.lua
-- nothing happens, and lua-5.1 does not exit
Acredito, a partir de testes adicionais, que isso não é um problema de buffer: escrever um programa que libera manualmente para colocar no lugar de echo
e adicionar io.stdin:setvbuf("no")
no topo do script lua não altera o comportamento. (Na verdade, experimentalmente, parece ter sido anexado diretamente ao terminal: pressionar enter manualmente ainda faz com que o retorno de chamada seja executado e o programa saia!)
Por que meu script não vê os dados canalizados e como posso alterá-lo para que isso aconteça?
A entrada padrão é FD 0, não FD 1, então faça
uv.new_poll(0)
em vez deuv.new_poll(1)
. O motivo pelo qual funcionou quando você pressionou Enter manualmente em vez de canalizar para ele é que, sem canais, todos os FDs padrão são o TTY aberto no modo de leitura-escrita.