I start an external executable with OS.execute_with_pipe() then watch it with a new thread to get its STDIO, works ok with threads that have like 100 lines, but when it takes more time, it stops responding. In other programming languages, we can increase the buffer size for that kind of thing, searched for it but couldn’t find anywhere. Thanks.
Just couple of questions. Does it work with just OS.execute().
Also did you check the stderr.
Here is a class I use for it:
class_name ExecPipeClass
var pipe: FileAccess
var stderr: FileAccess
var pid: int
var thread: Thread
var info
signal pipe_in_progress
func exec_using_pipe(bin: String, args: PackedStringArray):
#func init_exec_with_pipe(bin: String, args: PackedStringArray):
var info = OS.execute_with_pipe(bin, args)
pipe = info["stdio"]
stderr=info["stderr"]
pid=info["pid"]
thread = Thread.new()
func start():
thread.start(_thread_func)
func _thread_func():
# read stdin and report to log.
var line:=""
var pipe_err
var std_err
var count=0
if !pipe.is_open():
pipe_in_progress.emit.call_deferred("Error opening .", pipe.get_error())
while pipe.is_open():
pipe_err=pipe.get_error()
if pipe_err == OK:
line=pipe.get_line()
count+=1
pipe_in_progress.emit.call_deferred(line)
pass
else:
line=stderr.get_line()
if line!="":
pipe_in_progress.emit.call_deferred(line)
else:
break
pipe_in_progress.emit.call_deferred(null)
func clean_thread():
if thread.is_alive():
thread.wait_to_finish()
pipe.close()
OS.kill(pid)
thank you for replying. i didn’t use OS.execute() because i thought it was blocking. but i guess if i put that in a separate function and run it with a thread it would work. not sure if i could get the stdio from it though.
my code is very similar to your suggestion, i check pipe line and stderror with a signal just like while pipe.isopen(). the weird thing is if the stdio is relatively small, it works just fine. if the executed program’s IO gets longer it doesn’t. i had a similar problem in the past with nodejs and solved it with increasing the buffer size, but couldn’t find anything similar in godot. perhaps it’s well hidden
it is a bat file i created that runs a cli program in windows, it’s for data recovery. the program needs quotes for its arguments and i’ve found out that i can’t pass them in OS.execute_with_pipe(), so as a not-so-great solution i wrote the code to a bat file and started it instead.
for anyone interested, the solution was to use OS.create_process(), it doesn’t get stuck like OS.execute_with_pipe() though you need to manually watch its output with another function (timer in my case).