From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c | 151 ++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c (limited to 'lib/os_mon/c_src/nteventlog/elog_pipe_stdin.c') 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; +} + -- cgit v1.2.3