aboutsummaryrefslogtreecommitdiffstats
path: root/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c')
-rw-r--r--lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c b/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c
new file mode 100644
index 0000000000..c333c455a3
--- /dev/null
+++ b/lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c
@@ -0,0 +1,151 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1998-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+#include "elog_global.h"
+#include "elog_pipe_stdin.h"
+
+/*
+ * Data for the handling of a pipe stdin,
+ * data is read in a separate thread, so locking and
+ * event signaling needs to be done.
+ */
+
+static CRITICAL_SECTION io_crit;
+static char *stdin_buff = NULL;
+static int stdin_siz = 0;
+static int stdin_len = 0;
+static int stdin_eof = 0;
+/* end syncronized objects */
+static int stdin_is_console = 0;
+static HANDLE stdin_event;
+
+DWORD WINAPI stdin_thread(LPVOID ptr){
+ HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
+ char buff[1];
+ DWORD red;
+ for(;;){
+ if(!ReadFile(in, buff, (DWORD) 1, &red, NULL)){
+ if(GetLastError() == ERROR_BROKEN_PIPE){
+ EnterCriticalSection(&io_crit);
+ stdin_eof = 1;
+ SetEvent(stdin_event);
+ LeaveCriticalSection(&io_crit);
+ return 0;
+ }
+ return 1;
+ }else if(red == 0){
+ EnterCriticalSection(&io_crit);
+ stdin_eof = 1;
+ SetEvent(stdin_event);
+ LeaveCriticalSection(&io_crit);
+ return 0;
+ }
+#ifdef HARDDEBUG
+ fprintf(stderr,"stdin_thread go data (%d)\n",(int)*buff);
+#endif
+ EnterCriticalSection(&io_crit);
+ if(stdin_len + 1 >= stdin_siz){
+ if(!stdin_siz)
+ stdin_buff = malloc(stdin_siz = 100);
+ else
+ stdin_buff = realloc(stdin_buff, stdin_siz +=100);
+ }
+ stdin_buff[stdin_len++] = *buff;
+ SetEvent(stdin_event);
+ LeaveCriticalSection(&io_crit);
+ }
+ return 0;
+}
+
+BOOL peek_pipe_stdin_eof(void){
+ BOOL ret;
+ EnterCriticalSection(&io_crit);
+ if((ret = !!stdin_eof))
+ ResetEvent(stdin_event); /* Now we "unsignal" */
+ LeaveCriticalSection(&io_crit);
+ return ret;
+}
+
+int read_pipe_stdin(char *buff, int max){
+ int ret;
+ EnterCriticalSection(&io_crit);
+ if(stdin_len == 0){
+ if(!stdin_eof){
+ LeaveCriticalSection(&io_crit);
+ WaitForSingleObject(stdin_event,INFINITE);
+ EnterCriticalSection(&io_crit);
+ if(!stdin_len){
+ if(stdin_eof){
+ /* Stay signaled */
+ LeaveCriticalSection(&io_crit);
+ return 0;
+ } else {
+ ResetEvent(stdin_event);
+ LeaveCriticalSection(&io_crit);
+ return -1;
+ }
+ }
+ } else {
+ /* Stay signaled */
+ LeaveCriticalSection(&io_crit);
+ return 0;
+ }
+ }
+#ifdef HARDDEBUG
+ fprintf(stderr,"read_pipe_stdin got data.\n"
+ "max = %d, stdin_len = %d, *stdin_buff = %d\n",
+ max,stdin_len,*stdin_buff);
+#endif
+ /* stdin_len should be something now */
+ if(stdin_len > max){
+ memcpy(buff,stdin_buff,max);
+ memmove(stdin_buff,stdin_buff + max,stdin_len - max);
+ stdin_len -= max;
+ ret = max;
+ } else {
+ memcpy(buff,stdin_buff,stdin_len);
+ ret = stdin_len;
+ stdin_len = 0;
+ }
+ if(!stdin_eof) /* Stay signaled if EOF */
+ ResetEvent(stdin_event);
+ LeaveCriticalSection(&io_crit);
+ return ret;
+}
+
+BOOL setup_pipe_stdin(void){
+ HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
+ DWORD dummy;
+ if(GetConsoleMode(in, &dummy)){
+ stdin_is_console = 1;
+ stdin_event = in;
+ return TRUE;
+ }
+ stdin_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ InitializeCriticalSection(&io_crit);
+ return (_beginthreadex(NULL,0,&stdin_thread,NULL,0,&dummy));
+}
+
+BOOL console_stdin(void){
+ return stdin_is_console;
+}
+
+HANDLE get_stdin_event(void){
+ return stdin_event;
+}
+