views:

457

answers:

2

I'm trying to write a lua script that reads input from other processes and analyzes it. For this purpose I'm using io.popen and it works as expected in Windows, but on Unix(Solaris) reading from io.popen blocks, so the script just waits there until something comes along instead of returning immediately...

As far as I know I can't change the functionality of io.popen from within the script, and if at all possible I would rather not have to change the C code, because then the script will then need to be bound with the patched binary.

Does that leave me with any command-line solutions?

+1  A: 

Ok got no answers so far, but for posterity if someone needs a similar solution I did the following more or less

function my_popen(name,cmd)
    local process = {}
    process.__proc = assert(io.popen(cmd..">"..name..".tmp", 'r'))
    process.__file = assert(io.open(name..".tmp", 'r'))
    process.lines  = function(self)
     return self.__file:lines()
    end
    process.close = function(self)
     self.__proc:close()
     self.__file:close()
    end
    return process
end

proc = my_popen("somename","some command")
while true
    --do stuf
    for line in proc:lines() do
     print(line)
    end
    --do stuf
end
Robert Gould
+1  A: 

Your problems seems to be related to buffering. For some reason the pipe is waiting for some data to be read before it allows the opened program to write more to it, and it seems to be less than a line. What you can do is use io.popen(cmd):read"*a" to read everything. This should avoid the buffering problem. Then you can split the returned string in lines with for line in string.gmatch("[^\n]+") do someting_with(line) end.

Your solution consist in dumping the output of the process to a file, and reading that file. You can replace your use or io.popen with io.execute, and discard the return value (just check it's 0).

Doub