I'd like to get the piped content in stdin of a D program only IF it is there.
Considering the following
string output;
char[] buf;
while (stdin.readln(buf))
{
output ~= buf;
}
return output;
This works great if you pipe content e.g
echo "poop" | test.exe
will print out "poop" and continue execution.
However if you just run test.exe, it will hang there waiting for CTRL+C before continuing.
I'd like to assess the fact that content has been piped in so that I'm not doing a readline() if there is no piped content.
Any clues? Thanks!
There's two ways you can do this: ask if data is available on stdin with a timeout, or see if stdin is a pipe or the user-interactive console. Both of these are platform specific; the D std library doesn't include a function to check them. Since you're talking exe, I'll give an answer for Windows. (If you aren't on Windows, the posix functions you want are probably select
and isatty
, search the web for info about them. You could also set the files to non-blocking mode and try to read.)
To check if data is available, you can call WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 50)
. The second argument is a timeout in milliseconds - 50 will be quick enough that it looks basically instant to a user, while giving a program time to pipe stuff to it. It will return zero if the object is ready; if there's data available.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx
WaitForSingleObject
and STD_INPUT_HANDLE
are both defined in D by first doing import core.sys.windows.windows;
import core.sys.windows.windows;
import std.stdio;
void main() {
if(WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 50) == 0) {
string output;
char[] buf;
while (stdin.readln(buf))
{
output ~= buf;
}
writeln(output);
}
}
To tell if stdin is a console.... well, to be honest with you, I don't remember how to do it in Win32 off the top of my head and need to go right now! Maybe I can come back later tonight and edit it in, but if you can find a C solution, the same thing can be done in D too.
See also my comment on the question about end-of-file.