[0.17.68] Server started from cmd has broken input stream (Windows)
-
- Fast Inserter
- Posts: 205
- Joined: Fri Oct 05, 2018 4:34 pm
- Contact:
[0.17.68] Server started from cmd has broken input stream (Windows)
When I start a Factorio server through cmd with a command like "bin\x64\factorio.exe --start-server save.zip" on Windows 7 it imminently signals completion and returns to the shell, but keeps the stdin/out streams open. This results in input written to the terminal alternating between being sent to cmd and to the Factorio process (see attached image.)
- Attachments
-
- bad-input.png (60.18 KiB) Viewed 4734 times
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
you need to start it with
Code: Select all
start /wait bin\x64\factorio.exe --start-server save.zip
-
- Fast Inserter
- Posts: 205
- Joined: Fri Oct 05, 2018 4:34 pm
- Contact:
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
How am I supposed to send input to a factorio server on Windown when it ignores stdin and instead opt hijack the input stream of the console belonging to the process group it's associated with?
Edit: Programatically speaking that is. Like from a process manager for factorio servers.
Edit: Programatically speaking that is. Like from a process manager for factorio servers.
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
The Windows command prompt has a special feature that all windows applications (as opposed to console applications) are started as if you'd ended the command with & in bash. Use something that doesn't have this feature, or use "start /wait".
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
I'd like to know the same thing. I had no idea why my server manager refused to work with Factorio until I found this thread. All I'm trying to do is pass I/O to a server without using RCON, but nothing I've tried has worked.Hornwitser wrote: βThu Sep 12, 2019 5:47 pmHow am I supposed to send input to a factorio server on Windown when it ignores stdin and instead opt hijack the input stream of the console belonging to the process group it's associated with?
Edit: Programatically speaking that is. Like from a process manager for factorio servers.
I make mods! Feedback is appreciated, particularly if I broke something.
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
You can just launch the game without using a command prompt. Just "run" it directly from what ever program you're going to use to send input/output to the game.
If you want to get ahold of me I'm almost always on Discord.
-
- Fast Inserter
- Posts: 205
- Joined: Fri Oct 05, 2018 4:34 pm
- Contact:
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
No. This doesn't work. The Windows Release build does not read from stdin when spawned from a process that owns a console. Here's a few ways you can tell this is the case:
- Input is being read from the console after the command prompt has returned. The console input buffer is no longer connected to the program's stdin at that point, in fact it was never connected to it in the first place as factorio is not a console process, so what Factorio is reading is not stdin.
- Input redirection doesn't work. Appending < input-file.txt to the command executed in cmd does not cause Factorio to read anything in input-file.txt, instead it'll still read input from the console input buffer.
- Spawning factorio from a console application, for example in python with code like does not let you send input to the game from that application. Instead Factorio opens the console input buffer of the parent process' console and reads that.
Code: Select all
import subprocess, sys subprocess.run('factorio.exe --start-server-load-scenario base/freeplay', stdout=sys.stdout, input=b'this is stdin which is completely ignored\n')
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
Can confirm that redirection of stdin doesn't work in that scenario.
I've been writing a wrapper in C# that uses the Process.Start() method to launch the server, which is the standard way of starting a child process. However, attempting to programmatically write to stdin results in the exact behavior described in the original post.
Without going into too much detail about my own code, any input lines that start with "wrapper" are supposed to be processed separately as a means of interacting with the wrapper program itself. In the screenshot above I'm attempting to send a "testecho" command to the wrapper program, which should just echo back the following text argument in a cyan "wrapper" line. However, every other input completely bypasses all of the wrapper code and is sent directly to the Factorio server.
I initially assumed it was a bug in my own code, but even commenting out the entire block of code responsible for sending input to Factorio doesn't change the behavior. The expected behavior is that the server would only respond to input specifically written to its redirected stdin by the wrapper program, but instead it directly receives every other user input and ignores all attempts at programmatic input.
I've been writing a wrapper in C# that uses the Process.Start() method to launch the server, which is the standard way of starting a child process. However, attempting to programmatically write to stdin results in the exact behavior described in the original post.
Without going into too much detail about my own code, any input lines that start with "wrapper" are supposed to be processed separately as a means of interacting with the wrapper program itself. In the screenshot above I'm attempting to send a "testecho" command to the wrapper program, which should just echo back the following text argument in a cyan "wrapper" line. However, every other input completely bypasses all of the wrapper code and is sent directly to the Factorio server.
I initially assumed it was a bug in my own code, but even commenting out the entire block of code responsible for sending input to Factorio doesn't change the behavior. The expected behavior is that the server would only respond to input specifically written to its redirected stdin by the wrapper program, but instead it directly receives every other user input and ignores all attempts at programmatic input.
I make mods! Feedback is appreciated, particularly if I broke something.
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
Is your program compiled as a console application? So, Factorio sees it as a console and attaches to it?
If you want to get ahold of me I'm almost always on Discord.
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
Yes, my program is compiled as a console app. I'm not familiar enough with the inner workings of Windows to know whether or not that's exactly the right description of the behavior, but it certainly sounds correct.
I make mods! Feedback is appreciated, particularly if I broke something.
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
If you compile as not-a-console-application Factorio won't attach itself to your program when you launch it.
If you want to get ahold of me I'm almost always on Discord.
-
- Fast Inserter
- Posts: 205
- Joined: Fri Oct 05, 2018 4:34 pm
- Contact:
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
This is not an option for Clusterio which runs on Node.js which in turn does not provide a windows subsystem build of their runtime. Not having a console is also kind of inconvenient for this kind of application.
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
For now I'll look into making my program work as a GUI program. Not looking forward to refactoring my code, but also excited to make it finally work.
However, it still seems like this is not desirable behavior since dedicated servers are usually run via console to save resources. Is there any possibility this could be looked into further?
Edit:
After further investigation, it seems that everything works as expected so long as there's no console for Factorio to attach to shortly after launching. Using a block of code like this fixes the issue without needing to compile as a GUI program. There's probably a simpler way of implementing this, but it's the first thing I found that reliably works.
I make mods! Feedback is appreciated, particularly if I broke something.
[1.1.107] Factorio continues to steal parent's STDIN
This continues to happen with 1.1.107 on Windows and only on Windows. Discussion started in this thread: Console / stdin especially on windows
Expected:
1. Parent program launches, reads from shell -> stdin
2. Parent starts Factorio as a subprocess with its STDIN pipe open
3. Parent receives commands from user, some of them relayed to the Factorio child process
Actual:
Factorio inherits parent's STDIN pipe (between shell -> stdin of parent) and interferes with it. Therefore writing lines on shell causes them to go round-robin between Parent and Factorio. A line received by parent isn't seen by Factorio (even if children's pipe is written to) and the line Factorio receives never goes to Parent.
---
Untested code for now because I can't reach the partition with real code. I will update this post later.
---
Lua 5.1, Windows 10, both CMD or Powershell as shells.
This is expected to work as a command relay:
---
Minimal repro, there's no pipe:write in while loop, but input still gets stolen:
---
Minimal repro, null hypothesis, Lua itself works fine:
Expected:
1. Parent program launches, reads from shell -> stdin
2. Parent starts Factorio as a subprocess with its STDIN pipe open
3. Parent receives commands from user, some of them relayed to the Factorio child process
Actual:
Factorio inherits parent's STDIN pipe (between shell -> stdin of parent) and interferes with it. Therefore writing lines on shell causes them to go round-robin between Parent and Factorio. A line received by parent isn't seen by Factorio (even if children's pipe is written to) and the line Factorio receives never goes to Parent.
---
Untested code for now because I can't reach the partition with real code. I will update this post later.
---
Lua 5.1, Windows 10, both CMD or Powershell as shells.
This is expected to work as a command relay:
Code: Select all
local pipe = io.popen("factorio.exe --start-server-load-latest > stdout.txt 2> stderr.txt", "w")
print("Please wait a couple seconds, press Enter when Factorio is done loading")
print("You should run 'tail -f stdout.txt' in another console to see Factorio's output")
print()
print("waiting for you...")
io.read()
print("OK, entering command input mode. Anything you send will be relayed to Factorio's console")
print("if you want to stop the server, it says /quit works."
print("... and I found CTRL+C does too :) Pay attention if Factorio's process exists")
print("send 'q!' if you want the Lua script itself to quit")
print()
print("Start writing and then press ENTER:")
while true do
local line = io.read()
if not line then break end
line = line:gsub("\r$", "")
if line == "q!" then
break
end
print("You entered line: '".. line .."'")
pipe:write(line, "\r\n")
-- you MUST flush the line for Factorio to receive it
-- or make sure you are in line-buffered mode if provided by your library
pipe:flush()
end
print("Quitting Lua script. Bye!")
Minimal repro, there's no pipe:write in while loop, but input still gets stolen:
Code: Select all
local pipe = io.popen("factorio.exe --start-server-load-latest > stdout.txt 2> stderr.txt", "w")
print("Please wait a couple seconds, press Enter when Factorio is done loading")
print("You should run 'tail -f stdout.txt' in another console to see Factorio's output")
print()
print("waiting for you...")
io.read()
print("OK, entering command input mode. Anything you send will be relayed to Factorio's console")
print("if you want to stop the server, it says /quit works."
print("... and I found CTRL+C does too :) Pay attention if Factorio's process exists")
print("send 'q!' if you want the Lua script itself to quit")
print()
print("Start writing and then press ENTER:")
while true do
local line = io.read()
if not line then break end
line = line:gsub("\r$", "")
if line == "q!" then
break
end
print("You entered line: '".. line .."'")
end
print("Quitting Lua script. Bye!")
Minimal repro, null hypothesis, Lua itself works fine:
Code: Select all
while true do
local line = io.read()
if not line then break end
line = line:gsub("\r$", "")
if line == "q!" then
break
end
print("You entered line: '".. line .."'")
end
print("Quitting Lua script. Bye!")
Re: [1.1.107] Factorio continues to steal parent's STDIN
Yes, it still works as described years ago. If launched from a console application factorio will attach to the processes stdin, stdout, and stderr handles.vadcx wrote: βMon Apr 29, 2024 9:02 pmThis continues to happen with 1.1.107 on Windows and only on Windows. Discussion started in this thread: Console / stdin especially on windows
If you want to get ahold of me I'm almost always on Discord.
Re: [1.1.107] Factorio continues to steal parent's STDIN
Thanks Rseding, as silly as it sounds, that was the answer to really nudge me to look into Windows' text vs GUI mode differences:
Read everything, but the real hint is the answer at the end: win32 GUI app that writes usage text to stdout when invoked as "app.exe --help"
https://learn.microsoft.com/en-us/windo ... locconsole
https://learn.microsoft.com/en-us/windo ... achconsole
As far as I understand this, the parent application (regardless of type) must provide a new console for Factorio to attach to. Then parent can return to its real console. Otherwise, Factorio (being a GUI application) has no other choice but to share parent's console or nothing at all. And this is by design on Windows. Therefore there are no portable workarounds and pipes don't work as expected due to this architecture.
Read everything, but the real hint is the answer at the end: win32 GUI app that writes usage text to stdout when invoked as "app.exe --help"
https://learn.microsoft.com/en-us/windo ... locconsole
https://learn.microsoft.com/en-us/windo ... achconsole
As far as I understand this, the parent application (regardless of type) must provide a new console for Factorio to attach to. Then parent can return to its real console. Otherwise, Factorio (being a GUI application) has no other choice but to share parent's console or nothing at all. And this is by design on Windows. Therefore there are no portable workarounds and pipes don't work as expected due to this architecture.
Re: [0.17.68] Server started from cmd has broken input stream (Windows)
I could potentially add a command line option to suppress the pipe attachment logic. But I have no idea if it will work and it wouldn't be until 2.0 at the earliest.
If you want to get ahold of me I'm almost always on Discord.