summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VC++Files/mysys/mysys.dsp4
-rw-r--r--VC++Files/mysys/mysys_ia64.dsp4
-rw-r--r--client/mysql.cc31
-rw-r--r--include/my_sys.h3
-rw-r--r--mysys/my_conio.c217
5 files changed, 256 insertions, 3 deletions
diff --git a/VC++Files/mysys/mysys.dsp b/VC++Files/mysys/mysys.dsp
index f47203d37bf..2f3d7bb272c 100644
--- a/VC++Files/mysys/mysys.dsp
+++ b/VC++Files/mysys/mysys.dsp
@@ -361,6 +361,10 @@ SOURCE=.\my_compress.c
# End Source File
# Begin Source File
+SOURCE=.\my_conio.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_copy.c
# End Source File
# Begin Source File
diff --git a/VC++Files/mysys/mysys_ia64.dsp b/VC++Files/mysys/mysys_ia64.dsp
index a0877457286..622ae1d5bce 100644
--- a/VC++Files/mysys/mysys_ia64.dsp
+++ b/VC++Files/mysys/mysys_ia64.dsp
@@ -362,6 +362,10 @@ SOURCE=.\my_compress.c
# End Source File
# Begin Source File
+SOURCE=.\my_conio.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_copy.c
# End Source File
# Begin Source File
diff --git a/client/mysql.cc b/client/mysql.cc
index 51822b64c82..be1541faaf5 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -938,10 +938,15 @@ static int get_options(int argc, char **argv)
static int read_lines(bool execute_commands)
{
-#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
+#if defined(OS2) || defined(__NETWARE__)
char linebuffer[254];
String buffer;
#endif
+#if defined(__WIN__)
+ String tmpbuf;
+ String buffer;
+#endif
+
char *line;
char in_string=0;
ulong line_number=0;
@@ -972,7 +977,7 @@ static int read_lines(bool execute_commands)
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
tee_fputs(prompt, stdout);
-#ifdef __NETWARE__
+#if defined(__NETWARE__)
line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
/* Remove the '\n' */
if (line)
@@ -981,7 +986,22 @@ static int read_lines(bool execute_commands)
if (p != NULL)
*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);
/* _cgets() expects the buffer size - 3 as the first byte */
linebuffer[0]= (char) sizeof(linebuffer) - 3;
@@ -1057,9 +1077,14 @@ static int read_lines(bool execute_commands)
status.exit_status=0;
}
}
+
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
buffer.free();
#endif
+#if defined( __WIN__)
+ tmpbuf.free();
+#endif
+
return status.exit_status;
}
diff --git a/include/my_sys.h b/include/my_sys.h
index 9127a58d71c..02ea188a18e 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -801,6 +801,9 @@ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
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
#ifdef __NETWARE__
void netware_reg_user(const char *ip, const char *user,
diff --git a/mysys/my_conio.c b/mysys/my_conio.c
new file mode 100644
index 00000000000..e381f9f23ef
--- /dev/null
+++ b/mysys/my_conio.c
@@ -0,0 +1,217 @@
+/* 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 HANDLE my_coninpfh= 0; /* console input */
+
+/*
+ functions my_pthread_auto_mutex_lock & my_pthread_auto_mutex_free
+ are experimental at this moment, they are intended to bring
+ ability of protecting code sections without necessity to explicitly
+ initialize synchronization object in one of threads
+
+ if found useful they are to be exported in mysys
+*/
+
+/*
+ int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name,
+ int id, int time)
+
+ NOTES
+ creates a mutex with given name and tries to lock it time msec.
+ mutex name is appended with id to allow system wide or process wide
+ locks. Handle to created mutex returned in ph argument.
+
+ RETURN
+ 0 thread owns mutex
+ <>0 error
+
+*/
+static
+int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name, int id, int time)
+{
+ int res;
+ char tname[FN_REFLEN];
+
+ sprintf(tname, "%s-%08X", name, id);
+
+ *ph= CreateMutex(NULL, FALSE, tname);
+ if (*ph == NULL)
+ return GetLastError();
+
+ res= WaitForSingleObject(*ph, time);
+
+ if (res == WAIT_TIMEOUT)
+ return ERROR_SEM_TIMEOUT;
+
+ if (res == WAIT_FAILED)
+ return GetLastError();
+
+ return 0;
+}
+
+/*
+ int my_pthread_auto_mutex_free(HANDLE* ph)
+
+
+ NOTES
+ releases a mutex.
+
+ RETURN
+ 0 thread released mutex
+ <>0 error
+
+*/
+static
+int my_pthread_auto_mutex_free(HANDLE* ph)
+{
+ if (*ph)
+ {
+ ReleaseMutex(*ph);
+ CloseHandle(*ph);
+ *ph= NULL;
+ }
+
+ return 0;
+}
+
+
+#define pthread_auto_mutex_decl(name) \
+ HANDLE __h##name= NULL;
+
+#define pthread_auto_mutex_lock(name, proc, time) \
+ my_pthread_auto_mutex_lock(&__h##name, #name, (proc), (time))
+
+#define pthread_auto_mutex_free(name) \
+ my_pthread_auto_mutex_free(&__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_cs);
+
+ /* lock the console for the current process*/
+ if (pthread_auto_mutex_lock(my_conio_cs, GetCurrentProcessId(), INFINITE))
+ {
+ /* can not lock console */
+ pthread_auto_mutex_free(my_conio_cs);
+ return NULL;
+ }
+
+ /* init console input */
+ if (my_coninpfh == 0)
+ {
+ /* same handle will be used until process termination */
+ my_coninpfh= CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ }
+
+ if (my_coninpfh == INVALID_HANDLE_VALUE)
+ {
+ /* unlock the console */
+ pthread_auto_mutex_free(my_conio_cs);
+ 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_cs);
+
+ return result;
+}
+
+#endif /* __WIN__ */