24
24
#include < signal.h>
25
25
#ifdef WIN32
26
26
#include < Mmsystem.h>
27
+ #include < io.h>
27
28
#else
28
29
#include < termios.h>
29
30
#include < unistd.h>
@@ -160,6 +161,16 @@ void CServerImpl::Daemonize () const
160
161
close ( 2 );
161
162
assert ( open ( " /dev/null" , O_WRONLY ) == 2 );
162
163
}
164
+
165
+ #endif
166
+
167
+ #ifdef WIN32
168
+ bool CServerImpl::HasConsole ()
169
+ {
170
+ // Getting it a single time is sufficient
171
+ static bool isTTY = _isatty (_fileno (stdin));
172
+ return isTTY;
173
+ }
163
174
#endif
164
175
165
176
@@ -196,36 +207,47 @@ int CServerImpl::Run ( int iArgumentCount, char* szArguments [] )
196
207
std::setlocale (LC_ALL," C" );
197
208
assert ( strcoll ( " a" , " B" ) > 0 );
198
209
199
- // Disable QuickEdit mode to prevent text selection causing server freeze
200
- HANDLE hConIn = GetStdHandle ( STD_INPUT_HANDLE );
201
- DWORD dwConInMode;
202
- GetConsoleMode ( hConIn, &dwConInMode );
203
- SetConsoleMode ( hConIn, dwConInMode & ~ENABLE_QUICK_EDIT_MODE );
210
+ // Get the console handles
211
+ m_hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
212
+ m_hConsoleInput = GetStdHandle (STD_INPUT_HANDLE);
204
213
205
- // Get the console handle
206
- m_hConsole = GetStdHandle ( STD_OUTPUT_HANDLE );
214
+ // If stdout is piped GetConsoleScreenBufferInfo will fail
215
+ // ==> check if stdin is piped
216
+ if (HasConsole ())
217
+ {
218
+ // Disable QuickEdit mode to prevent text selection causing server freeze
219
+ DWORD dwConInMode;
220
+ GetConsoleMode (m_hConsoleInput, &dwConInMode);
221
+ SetConsoleMode (m_hConsoleInput, dwConInMode & ~ENABLE_QUICK_EDIT_MODE);
207
222
208
- // Enable the default grey color with a black background
209
- SetConsoleTextAttribute ( m_hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
223
+ // Enable the default grey color with a black background
224
+ SetConsoleTextAttribute ( m_hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
210
225
211
- // Get the console's width
212
- CONSOLE_SCREEN_BUFFER_INFO ScrnBufferInfo;
213
- if ( !GetConsoleScreenBufferInfo ( m_hConsole, &ScrnBufferInfo ) )
214
- {
215
- Print ( " ERROR: GetConsoleScreenBufferInfo failed (%08x)\n " , GetLastError () );
216
- Print ( " Press Q to shut down the server!\n " );
217
- WaitForKey ( ' q' );
218
- DestroyWindow ( );
219
- return ERROR_OTHER;
220
- }
226
+ // Get the console's width
227
+ CONSOLE_SCREEN_BUFFER_INFO ScrnBufferInfo;
228
+ if (!GetConsoleScreenBufferInfo (m_hConsole, &ScrnBufferInfo) )
229
+ {
230
+ Print ( " ERROR: GetConsoleScreenBufferInfo failed (%08x)\n " , GetLastError ());
231
+ Print ( " Press Q to shut down the server!\n " );
232
+ WaitForKey ( ' q' );
233
+ DestroyWindow ( );
234
+ return ERROR_OTHER;
235
+ }
221
236
222
- // Adjust the console's screenbuffer so we can disable a bar at the top
223
- if ( !g_bNoTopBar )
224
- ScrnBufferInfo.dwSize .Y = ScrnBufferInfo.srWindow .Bottom + 1 ;
237
+ // Adjust the console's screenbuffer so we can disable a bar at the top
238
+ if (!g_bNoTopBar)
239
+ ScrnBufferInfo.dwSize .Y = ScrnBufferInfo.srWindow .Bottom + 1 ;
225
240
226
- SetConsoleWindowInfo ( m_hConsole, TRUE , &ScrnBufferInfo.srWindow );
227
- SetConsoleScreenBufferSize ( m_hConsole, ScrnBufferInfo.dwSize );
228
- SetConsoleOutputCP (CP_UTF8);
241
+ SetConsoleWindowInfo (m_hConsole, TRUE , &ScrnBufferInfo.srWindow );
242
+ SetConsoleScreenBufferSize (m_hConsole, ScrnBufferInfo.dwSize );
243
+ SetConsoleOutputCP (CP_UTF8);
244
+ }
245
+ else if (GetFileType (m_hConsoleInput) == FILE_TYPE_PIPE)
246
+ {
247
+ // Enable non-blocking read mode
248
+ DWORD pipeState = PIPE_NOWAIT;
249
+ SetNamedPipeHandleState (GetStdHandle (STD_INPUT_HANDLE), &pipeState, nullptr , nullptr );
250
+ }
229
251
#else
230
252
// support user locales
231
253
std::setlocale (LC_ALL, " " );
@@ -673,7 +695,16 @@ void CServerImpl::HandleInput ( void )
673
695
674
696
// Get the STDIN input
675
697
#ifdef WIN32
676
- if ( kbhit () )
698
+ if (!HasConsole ())
699
+ {
700
+ // Read from pipe instead of tty
701
+ // however, the encoding is dependent on the writer
702
+ // so just accept ASCII here by convention
703
+ DWORD read;
704
+ if (!ReadFile (GetStdHandle (STD_INPUT_HANDLE), &iStdIn, 1 , &read, nullptr ) || read == 0 )
705
+ iStdIn = 0 ;
706
+ }
707
+ else if ( kbhit () )
677
708
{
678
709
iStdIn = _getwch ();
679
710
}
@@ -766,7 +797,7 @@ void CServerImpl::HandleInput ( void )
766
797
#ifdef WIN32 // WIN32: we have to use a prefix code, this routine opens an extra switch
767
798
case KEY_EXTENDED:
768
799
// Color the text
769
- if ( !g_bSilent )
800
+ if (!g_bSilent && HasConsole () )
770
801
SetConsoleTextAttribute ( m_hConsole, FOREGROUND_GREEN | FOREGROUND_RED );
771
802
772
803
iStdIn = _getwch ();
@@ -830,7 +861,7 @@ void CServerImpl::HandleInput ( void )
830
861
#ifdef WIN32 // WIN32: Close the switch again
831
862
}
832
863
// Restore the color
833
- if ( !g_bSilent )
864
+ if (!g_bSilent && HasConsole () )
834
865
SetConsoleTextAttribute ( m_hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
835
866
836
867
break ; // KEY_EXTENDED
@@ -845,7 +876,7 @@ void CServerImpl::HandleInput ( void )
845
876
846
877
#ifdef WIN32
847
878
// Color the text
848
- if ( !g_bSilent )
879
+ if (!g_bSilent && HasConsole () )
849
880
SetConsoleTextAttribute ( m_hConsole, FOREGROUND_GREEN | FOREGROUND_RED );
850
881
851
882
// Echo the input
@@ -861,7 +892,7 @@ void CServerImpl::HandleInput ( void )
861
892
862
893
#ifdef WIN32
863
894
// Restore the color
864
- if ( !g_bSilent )
895
+ if (!g_bSilent && HasConsole () )
865
896
SetConsoleTextAttribute ( m_hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
866
897
#endif
867
898
break ;
0 commit comments