diff options
author | unknown <SergeyV@selena.> | 2005-09-16 01:56:16 +0400 |
---|---|---|
committer | unknown <SergeyV@selena.> | 2005-09-16 01:56:16 +0400 |
commit | 627bf43d9ff9c4b1b5cde1463cf5d03cf5e92c3d (patch) | |
tree | 0dd45aa9200f62048bab12884a63a483e4f9ef52 /mysys/my_conio.c | |
parent | d026dd0e4532b51d49cd14cbcba4cb693155f0d0 (diff) | |
download | mariadb-git-627bf43d9ff9c4b1b5cde1463cf5d03cf5e92c3d.tar.gz |
Fixes bug #12929. Uses my_cgets instead of _cgets function, thus eliminating
a restriction to 255 chars for editable buffer.
VC++Files/mysys/mysys.dsp:
Added my_conio.c
VC++Files/mysys/mysys_ia64.dsp:
Added my_conio.c
include/my_sys.h:
Added declarations for my_conio.c functions
mysys/my_conio.c:
Added _cgets() replacement that is not limited to 255 chars retrieval
from win32 console.
Diffstat (limited to 'mysys/my_conio.c')
-rw-r--r-- | mysys/my_conio.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/mysys/my_conio.c b/mysys/my_conio.c new file mode 100644 index 00000000000..2bf2c1cf1c0 --- /dev/null +++ b/mysys/my_conio.c @@ -0,0 +1,146 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#include "mysys_priv.h" + +#ifdef __WIN__ +static int my_coninpfh= 0; /* console input */ + +#define pthread_auto_mutex_decl(name) \ + HANDLE __h##name= NULL; \ + char __p##name[sizeof(#name)+16]; + +#define pthread_auto_mutex_lock(name, proc, time) \ + sprintf(__p##name, "%s-%08X", #name, (proc)); \ + __h##name= CreateMutex(NULL, FALSE, __p##name); \ + WaitForSingleObject(__h##name, (time)); + +#define pthread_auto_mutex_free(name) \ + if (__h##name) \ + { \ + ReleaseMutex(__h##name); \ + CloseHandle(__h##name); \ + } + + +/* + char* my_cgets(char *string, unsigned long clen, unsigned long* plen) + + NOTES + Replaces _cgets from libc to support input of more than 255 chars. + Reads from the console via ReadConsole into buffer which + should be at least clen characters. + Actual length of string returned in plen. + + WARNING + my_cgets() does NOT check the pushback character buffer (i.e., _chbuf). + Thus, my_cgets() will not return any character that is pushed back by + the _ungetch() call. + + RETURN + string pointer ok + NULL Error + +*/ +char* my_cgets(char *buffer, unsigned long clen, unsigned long* plen) +{ + ULONG state; + char *result; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + pthread_auto_mutex_decl(my_conio_mutex); + + /* lock the console */ + pthread_auto_mutex_lock(my_conio_mutex, GetCurrentProcessId(), INFINITE); + + /* init console input */ + if (my_coninpfh == 0) + { + /* same handle will be used until process termination */ + my_coninpfh= (int)CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + } + + if (my_coninpfh == -1) + { + /* unlock the console */ + pthread_auto_mutex_free(my_conio_mutex); + return(NULL); + } + + GetConsoleMode((HANDLE)my_coninpfh, &state); + SetConsoleMode((HANDLE)my_coninpfh, ENABLE_LINE_INPUT | + ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT); + + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + + /* + there is no known way to determine allowed buffer size for input + though it is known it should not be more than 64K + so we cut 64K and try first size of screen buffer + if it is still to large we cut half of it and try again + later we may want to cycle from min(clen, 65535) to allowed size + with small decrement to determine exact allowed buffer + */ + clen= min(clen, 65535); + do + { + clen= min(clen, (unsigned long)csbi.dwSize.X*csbi.dwSize.Y); + if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, clen - 1, plen, NULL)) + { + result= NULL; + clen>>= 1; + } + else + { + result= buffer; + break; + } + } + while (GetLastError() == ERROR_NOT_ENOUGH_MEMORY); + + + if (result != NULL) + { + if (buffer[*plen - 2] == '\r') + { + *plen= *plen - 2; + } + else + { + if (buffer[*plen - 1] == '\r') + { + char tmp[3]; + int tmplen= sizeof(tmp); + + *plen= *plen - 1; + /* read /n left in the buffer */ + ReadConsole((HANDLE)my_coninpfh, (LPVOID)tmp, tmplen, &tmplen, NULL); + } + } + buffer[*plen]= '\0'; + } + + SetConsoleMode((HANDLE)my_coninpfh, state); + /* unlock the console */ + pthread_auto_mutex_free(my_conio_mutex); + + return result; +} + +#endif /* __WIN__ */ |