mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
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.
This commit is contained in:
@@ -361,6 +361,10 @@ SOURCE=.\my_compress.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\my_conio.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\my_copy.c
|
SOURCE=.\my_copy.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@@ -362,6 +362,10 @@ SOURCE=.\my_compress.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\my_conio.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\my_copy.c
|
SOURCE=.\my_copy.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@@ -938,10 +938,15 @@ static int get_options(int argc, char **argv)
|
|||||||
|
|
||||||
static int read_lines(bool execute_commands)
|
static int read_lines(bool execute_commands)
|
||||||
{
|
{
|
||||||
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
#if defined(OS2) || defined(__NETWARE__)
|
||||||
char linebuffer[254];
|
char linebuffer[254];
|
||||||
String buffer;
|
String buffer;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__WIN__)
|
||||||
|
String tmpbuf;
|
||||||
|
String buffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
char *line;
|
char *line;
|
||||||
char in_string=0;
|
char in_string=0;
|
||||||
ulong line_number=0;
|
ulong line_number=0;
|
||||||
@@ -972,7 +977,7 @@ static int read_lines(bool execute_commands)
|
|||||||
|
|
||||||
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
||||||
tee_fputs(prompt, stdout);
|
tee_fputs(prompt, stdout);
|
||||||
#ifdef __NETWARE__
|
#if defined(__NETWARE__)
|
||||||
line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
|
line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
|
||||||
/* Remove the '\n' */
|
/* Remove the '\n' */
|
||||||
if (line)
|
if (line)
|
||||||
@@ -981,7 +986,22 @@ static int read_lines(bool execute_commands)
|
|||||||
if (p != NULL)
|
if (p != NULL)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
#else
|
#elif defined(__WIN__)
|
||||||
|
if (!tmpbuf.is_alloced())
|
||||||
|
tmpbuf.alloc(65535);
|
||||||
|
buffer.length(0);
|
||||||
|
unsigned long clen;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
line= my_cgets(tmpbuf.c_ptr(), tmpbuf.alloced_length(), &clen);
|
||||||
|
buffer.append(line, clen);
|
||||||
|
/*
|
||||||
|
if we got buffer fully filled than there is a chance that
|
||||||
|
something else is still in console input buffer
|
||||||
|
*/
|
||||||
|
} while (tmpbuf.alloced_length() <= clen + 1);
|
||||||
|
line= buffer.c_ptr();
|
||||||
|
#else /* OS2 */
|
||||||
buffer.length(0);
|
buffer.length(0);
|
||||||
/* _cgets() expects the buffer size - 3 as the first byte */
|
/* _cgets() expects the buffer size - 3 as the first byte */
|
||||||
linebuffer[0]= (char) sizeof(linebuffer) - 3;
|
linebuffer[0]= (char) sizeof(linebuffer) - 3;
|
||||||
@@ -1057,9 +1077,14 @@ static int read_lines(bool execute_commands)
|
|||||||
status.exit_status=0;
|
status.exit_status=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
|
||||||
buffer.free();
|
buffer.free();
|
||||||
#endif
|
#endif
|
||||||
|
#if defined( __WIN__)
|
||||||
|
tmpbuf.free();
|
||||||
|
#endif
|
||||||
|
|
||||||
return status.exit_status;
|
return status.exit_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -804,6 +804,9 @@ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
|
|||||||
|
|
||||||
void my_security_attr_free(SECURITY_ATTRIBUTES *sa);
|
void my_security_attr_free(SECURITY_ATTRIBUTES *sa);
|
||||||
|
|
||||||
|
/* implemented in my_conio.c */
|
||||||
|
char* my_cgets(char *string, unsigned long clen, unsigned long* plen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef __NETWARE__
|
#ifdef __NETWARE__
|
||||||
void netware_reg_user(const char *ip, const char *user,
|
void netware_reg_user(const char *ip, const char *user,
|
||||||
|
146
mysys/my_conio.c
Normal file
146
mysys/my_conio.c
Normal file
@@ -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__ */
|
Reference in New Issue
Block a user