summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/Makefile.am28
-rw-r--r--mysys/charset.c4
-rw-r--r--mysys/default.c4
-rw-r--r--mysys/mf_iocache.c66
-rw-r--r--mysys/mf_tempfile.c6
-rw-r--r--mysys/my_clock.c4
-rw-r--r--mysys/my_copy.c2
-rw-r--r--mysys/my_getopt.c6
-rw-r--r--mysys/my_getwd.c2
-rw-r--r--mysys/my_init.c107
-rw-r--r--mysys/my_lock.c54
-rw-r--r--mysys/my_messnc.c4
-rw-r--r--mysys/my_netware.c150
-rw-r--r--mysys/my_os2cond.c1
-rw-r--r--mysys/my_os2dirsrch.c192
-rw-r--r--mysys/my_os2dirsrch.h57
-rw-r--r--mysys/my_os2file64.c389
-rw-r--r--mysys/my_os2mutex.c53
-rw-r--r--mysys/my_os2thread.c3
-rw-r--r--mysys/my_os2tls.c201
-rw-r--r--mysys/my_pthread.c13
-rw-r--r--mysys/my_redel.c2
-rw-r--r--mysys/my_sleep.c (renamed from mysys/mf_sleep.c)29
-rw-r--r--mysys/my_tempnam.c10
-rw-r--r--mysys/my_thr_init.c12
-rw-r--r--mysys/mysys_priv.h6
-rw-r--r--mysys/safemalloc.c56
-rw-r--r--mysys/thr_alarm.c19
-rw-r--r--mysys/thr_mutex.c119
29 files changed, 1020 insertions, 579 deletions
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 97eb06c7aa7..5b1c859cb2a 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -49,10 +49,10 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_quick.c my_lockmem.c my_static.c \
my_getopt.c my_mkdir.c \
default.c my_compress.c checksum.c raid.cc \
- my_net.c my_semaphore.c my_port.c \
+ my_net.c my_semaphore.c my_port.c my_sleep.c \
charset.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
- my_handler.c
+ my_handler.c my_netware.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
@@ -78,38 +78,36 @@ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
# which automaticly removes the object files you use to compile a final program
#
-test_thr_alarm: thr_alarm.c $(LIBRARIES)
+test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
$(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
$(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
- $(RM) -f ./test_thr_alarm.*
+ $(RM) -f ./test_thr_alarm.c
-test_thr_lock: thr_lock.c $(LIBRARIES)
+test_thr_lock$(EXEEXT): thr_lock.c $(LIBRARIES)
$(CP) $(srcdir)/thr_lock.c test_thr_lock.c
$(LINK) $(FLAGS) -DMAIN ./test_thr_lock.c $(LDADD) $(LIBS)
- $(RM) -f ./test_thr_lock.*
+ $(RM) -f ./test_thr_lock.c
-test_vsnprintf: my_vsnprintf.c $(LIBRARIES)
+test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LIBRARIES)
$(CP) $(srcdir)/my_vsnprintf.c test_vsnprintf.c
$(LINK) $(FLAGS) -DMAIN ./test_vsnprintf.c $(LDADD) $(LIBS)
- $(RM) -f test_vsnprintf.*
-test_io_cache: mf_iocache.c $(LIBRARIES)
+ $(RM) -f test_vsnprintf.c
+
+test_io_cache$(EXEEXT): mf_iocache.c $(LIBRARIES)
$(CP) $(srcdir)/mf_iocache.c test_io_cache.c
$(LINK) $(FLAGS) -DMAIN ./test_io_cache.c $(LDADD) $(LIBS)
- $(RM) -f test_io_cache.*
+ $(RM) -f test_io_cache.c
-test_dir: test_dir.c $(LIBRARIES)
+test_dir$(EXEEXT): test_dir.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN $(srcdir)/test_dir.c $(LDADD) $(LIBS)
test_charset$(EXEEXT): test_charset.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN $(srcdir)/test_charset.c $(LDADD) $(LIBS)
-test_xml$(EXEEXT): test_xml.c $(LIBRARIES)
- $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_xml.c $(LDADD) $(LIBS)
-
charset2html$(EXEEXT): charset2html.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN $(srcdir)/charset2html.c $(LDADD) $(LIBS)
-testhash: testhash.c $(LIBRARIES)
+testhash$(EXEEXT): testhash.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN $(srcdir)/testhash.c $(LDADD) $(LIBS)
# Don't update the files from bitkeeper
diff --git a/mysys/charset.c b/mysys/charset.c
index a192eab8eb6..2105877d928 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -389,7 +389,11 @@ static my_bool init_compiled_charsets(myf flags __attribute__((unused)))
return FALSE;
}
+#ifdef __NETWARE__
+my_bool STDCALL init_available_charsets(myf myflags)
+#else
static my_bool init_available_charsets(myf myflags)
+#endif
{
char fname[FN_REFLEN];
my_bool error=FALSE;
diff --git a/mysys/default.c b/mysys/default.c
index f5ada19dd78..06557f73d06 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -46,6 +46,8 @@ char *defaults_extra_file=0;
const char *default_directories[]= {
#ifdef __WIN__
"C:/",
+#elif defined(__NETWARE__)
+"sys:/etc/",
#else
"/etc/",
#endif
@@ -53,7 +55,7 @@ const char *default_directories[]= {
DATADIR,
#endif
"", /* Place for defaults_extra_dir */
-#ifndef __WIN__
+#if !defined(__WIN__) && !defined(__NETWARE__)
"~/",
#endif
NullS,
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index e9c35175bf9..0f35ee048bb 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -441,11 +441,10 @@ void init_io_cache_share(IO_CACHE *info, IO_CACHE_SHARE *s, uint num_threads)
DBUG_ASSERT(info->type == READ_CACHE);
pthread_mutex_init(&s->mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init (&s->cond, 0);
- s->count=num_threads-1;
- s->active=0; /* to catch errors */
+ s->total=s->count=num_threads-1;
+ s->active=0;
info->share=s;
info->read_function=_my_b_read_r;
- /* Ensure that the code doesn't use pointer to the IO_CACHE object */
info->current_pos= info->current_end= 0;
}
@@ -456,32 +455,37 @@ void init_io_cache_share(IO_CACHE *info, IO_CACHE_SHARE *s, uint num_threads)
*/
void remove_io_thread(IO_CACHE *info)
{
- pthread_mutex_lock(&info->share->mutex);
- if (! info->share->count--)
- pthread_cond_signal(&info->share->cond);
- pthread_mutex_unlock(&info->share->mutex);
+ IO_CACHE_SHARE *s=info->share;
+
+ pthread_mutex_lock(&s->mutex);
+ s->total--;
+ if (! s->count--)
+ pthread_cond_signal(&s->cond);
+ pthread_mutex_unlock(&s->mutex);
}
-static int lock_io_cache(IO_CACHE *info)
+static int lock_io_cache(IO_CACHE *info, my_off_t pos)
{
- pthread_mutex_lock(&info->share->mutex);
- if (!info->share->count)
- return 1;
+ int total;
+ IO_CACHE_SHARE *s=info->share;
- --(info->share->count);
- pthread_cond_wait(&info->share->cond, &info->share->mutex);
- /*
- count can be -1 here, if one thread was removed (remove_io_thread)
- while all others were locked (lock_io_cache).
- If this is the case, this thread behaves as if count was 0 from the
- very beginning, that is returns 1 and does not unlock the mutex.
- */
- if (++(info->share->count))
+ pthread_mutex_lock(&s->mutex);
+ if (!s->count)
{
- pthread_mutex_unlock(&info->share->mutex);
- return 0;
+ s->count=s->total;
+ return 1;
}
- return 1;
+
+ total=s->total;
+ s->count--;
+ while (!s->active || s->active->pos_in_file < pos)
+ pthread_cond_wait(&s->cond, &s->mutex);
+
+ if (s->total < total)
+ return 1;
+
+ pthread_mutex_unlock(&s->mutex);
+ return 0;
}
static void unlock_io_cache(IO_CACHE *info)
@@ -532,7 +536,7 @@ int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
info->error=(int) read_len;
DBUG_RETURN(1);
}
- if (lock_io_cache(info))
+ if (lock_io_cache(info, pos_in_file))
{
info->share->active=info;
if (info->seek_not_done) /* File touched, do seek */
@@ -1132,19 +1136,15 @@ int end_io_cache(IO_CACHE *info)
DBUG_ENTER("end_io_cache");
#ifdef THREAD
+ /*
+ if IO_CACHE is shared between several threads, only one
+ thread needs to call end_io_cache() - just as init_io_cache()
+ should be called only once and then memcopy'ed
+ */
if (info->share)
{
-#ifdef SAFE_MUTEX
- /* simple protection against multi-close: destroying share first */
- if (pthread_cond_destroy (&info->share->cond) |
- pthread_mutex_destroy(&info->share->mutex))
- {
- DBUG_RETURN(1);
- }
-#else
pthread_cond_destroy (&info->share->cond);
pthread_mutex_destroy(&info->share->mutex);
-#endif
info->share=0;
}
#endif
diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c
index 09fde27afd6..cca80dcd552 100644
--- a/mysys/mf_tempfile.c
+++ b/mysys/mf_tempfile.c
@@ -24,7 +24,7 @@
#endif
#ifdef HAVE_TEMPNAM
-#if !defined( MSDOS) && !defined(OS2)
+#if !defined(MSDOS) && !defined(OS2) && !defined(__NETWARE__)
extern char **environ;
#endif
#endif
@@ -129,7 +129,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
if (buffer[strlen(buffer)-1] == '\\')
buffer[strlen(buffer)-1] = '\0';
putenv( buffer);
-#else
+#elif !defined(__NETWARE__)
old_env= (char**) environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
@@ -151,7 +151,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
{
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
}
-#ifndef OS2
+#if !defined(OS2) && !defined(__NETWARE__)
environ=(const char**) old_env;
#endif
}
diff --git a/mysys/my_clock.c b/mysys/my_clock.c
index e49b2f85b66..a192bde056d 100644
--- a/mysys/my_clock.c
+++ b/mysys/my_clock.c
@@ -17,14 +17,14 @@
#define USES_TYPES
#include "my_global.h"
-#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(OS2)
+#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(OS2) && !defined(__NETWARE__)
#include "mysys_priv.h"
#include <sys/times.h>
#endif
long my_clock(void)
{
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(OS2)
+#if !defined(MSDOS) && !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
struct tms tmsbuf;
VOID(times(&tmsbuf));
return (tmsbuf.tms_utime + tmsbuf.tms_stime);
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index a899835ea62..012eaec4ea8 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -80,7 +80,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)
if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
DBUG_RETURN(0); /* File copyed but not stat */
VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
VOID(chown(to, stat_buff.st_uid,stat_buff.st_gid)); /* Copy ownership */
#endif
#if !defined(VMS) && !defined(__ZTC__)
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 21adb9374ce..c6fe606eaaf 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -300,7 +300,8 @@ int handle_options(int *argc, char ***argv,
*/
*((my_bool*) optp->value)= (my_bool) (!optend || *optend == '1');
(*argc)--;
- continue; /* For GET_BOOL get_one_option() shouldn't be called */
+ get_one_option(optp->id, optp, argument);
+ continue;
}
argument= optend;
}
@@ -348,7 +349,8 @@ int handle_options(int *argc, char ***argv,
if (optp->var_type == GET_BOOL && optp->arg_type == NO_ARG)
{
*((my_bool*) optp->value)= (my_bool) 1;
- continue; /* For GET_BOOL get_one_option() shouldn't be called */
+ get_one_option(optp->id, optp, argument);
+ continue;
}
else if (optp->arg_type == REQUIRED_ARG ||
optp->arg_type == OPT_ARG)
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index 240b17ef87f..adf131c5fd0 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -32,7 +32,7 @@
#endif
#ifdef __EMX__
-// chdir2 support also drive change
+/* chdir2 support also drive change */
#define chdir _chdir2
#endif
diff --git a/mysys/my_init.c b/mysys/my_init.c
index ae7f78b7445..e18467b1235 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000-2003 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
@@ -40,6 +40,12 @@ static my_bool win32_init_tcp_ip();
#else
#define my_win_init()
#endif
+#ifdef __NETWARE__
+static void netware_init();
+#else
+#define netware_init()
+#endif
+
my_bool my_init_done=0;
@@ -63,12 +69,16 @@ void my_init(void)
if (my_init_done)
return;
my_init_done=1;
+#if defined(THREAD) && defined(SAFE_MUTEX)
+ safe_mutex_global_init(); /* Must be called early */
+#endif
+ netware_init();
#ifdef THREAD
#if defined(HAVE_PTHREAD_INIT)
pthread_init(); /* Must be called before DBUG_ENTER */
#endif
my_thread_global_init();
-#if !defined( __WIN__) && !defined(OS2)
+#if !defined( __WIN__) && !defined(OS2) && !defined(__NETWARE__)
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
#endif
#endif /* THREAD */
@@ -143,7 +153,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
rus.ru_nvcsw, rus.ru_nivcsw);
#endif
-#if defined(MSDOS) && !defined(__WIN__)
+#if ( defined(MSDOS) || defined(__NETWARE__) ) && !defined(__WIN__)
fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC);
#endif
#if defined(SAFEMALLOC)
@@ -160,20 +170,26 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
#endif
}
#ifdef THREAD
- pthread_mutex_destroy(&THR_LOCK_keycache);
- pthread_mutex_destroy(&THR_LOCK_malloc);
- pthread_mutex_destroy(&THR_LOCK_open);
DBUG_POP(); /* Must be done before my_thread_end */
my_thread_end();
my_thread_global_end();
-#endif
+#if defined(SAFE_MUTEX)
+ /*
+ Check on destroying of mutexes. A few may be left that will get cleaned
+ up by C++ destructors
+ */
+ safe_mutex_end(infoflag & MY_GIVE_INFO ? stderr : (FILE *) 0);
+#endif /* defined(SAFE_MUTEX) */
+#endif /* THREAD */
+
#ifdef __WIN__
- if (have_tcpip);
- WSACleanup( );
+ if (have_tcpip)
+ WSACleanup();
#endif /* __WIN__ */
- my_init_done=0;
+ my_init_done=0;
} /* my_end */
+
#ifdef __WIN__
/*
@@ -262,10 +278,10 @@ static void my_win_init(void)
/*------------------------------------------------------------------
-** Name: CheckForTcpip| Desc: checks if tcpip has been installed on system
-** According to Microsoft Developers documentation the first registry
-** entry should be enough to check if TCP/IP is installed, but as expected
-** this doesn't work on all Win32 machines :(
+ Name: CheckForTcpip| Desc: checks if tcpip has been installed on system
+ According to Microsoft Developers documentation the first registry
+ entry should be enough to check if TCP/IP is installed, but as expected
+ this doesn't work on all Win32 machines :(
------------------------------------------------------------------*/
#define TCPIPKEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
@@ -291,6 +307,7 @@ static my_bool win32_have_tcpip(void)
return (TRUE);
}
+
static my_bool win32_init_tcp_ip()
{
if (win32_have_tcpip())
@@ -322,4 +339,64 @@ static my_bool win32_init_tcp_ip()
}
return(0);
}
-#endif
+#endif /* __WIN__ */
+
+
+#ifdef __NETWARE__
+/****************************************************************************
+ Do basic initialisation for netware needed by most programs
+****************************************************************************/
+
+static void netware_init()
+{
+ char cwd[PATH_MAX], *name
+
+ /* init only if we are not a client library */
+ if (my_progname)
+ {
+#if SUPPORTED_BY_LIBC /* Removed until supported in Libc */
+ struct termios tp;
+ /* Disable control characters */
+ tcgetattr(STDIN_FILENO, &tp);
+ tp.c_cc[VINTR] = _POSIX_VDISABLE;
+ tp.c_cc[VEOF] = _POSIX_VDISABLE;
+ tp.c_cc[VSUSP] = _POSIX_VDISABLE;
+ tcsetattr(STDIN_FILENO, TCSANOW, &tp);
+#endif /* SUPPORTED_BY_LIBC */
+
+ /* With stdout redirection */
+ if (!isatty(STDOUT_FILENO))
+ {
+ setscreenmode(SCR_AUTOCLOSE_ON_EXIT); /* auto close the screen */
+ }
+ else
+ {
+ setscreenmode(SCR_NO_MODE); /* keep the screen up */
+ }
+
+ /* Parse program name and change to base format */
+ name= my_progname;
+ for (; *name; name++)
+ {
+ if (*name == '\\')
+ {
+ *name = '/';
+ }
+ else
+ {
+ *name = tolower(*name);
+ }
+ }
+ /*
+ Set the current working directory to the base directory of the file
+ name (assuming the binary is in 'base-file-name/bin/'
+ */
+ strmov(cwd, my_progname);
+ if ((name= strindex(cwd, "/bin/")) != NULL)
+ {
+ *name= 0;
+ chdir(cwd);
+ }
+ }
+}
+#endif /* __NETWARE__ */
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index 44ac53677ba..5058c301adb 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000-2003 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
@@ -31,6 +31,9 @@
#define INCL_NOPMAPI
#include <os2emx.h>
#endif
+#ifdef __NETWARE__
+#include <nks/fsio.h>
+#endif
/* Lock a part of a file */
@@ -41,6 +44,9 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
int value;
ALARM_VARIABLES;
#endif
+#ifdef __NETWARE__
+ int nxErrno;
+#endif
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(long) start,(long) length,MyFlags));
@@ -50,7 +56,47 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
if (my_disable_locking)
DBUG_RETURN(0);
-#if defined(__EMX__) || defined(OS2)
+#if defined(__NETWARE__)
+ {
+ NXSOffset_t nxLength = length;
+ unsigned long nxLockFlags = 0;
+
+ if (length == F_TO_EOF)
+ {
+ /* EOF is interpreted as a very large length. */
+ nxLength = 0x7FFFFFFFFFFFFFFF;
+ }
+
+ if (locktype == F_UNLCK)
+ {
+ /* The lock flags are currently ignored by NKS. */
+ if (!(nxErrno= NXFileRangeUnlock(fd, 0L, start, nxLength)))
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ if (locktype == F_RDLCK)
+ {
+ /* A read lock is mapped to a shared lock. */
+ nxLockFlags = NX_RANGE_LOCK_SHARED;
+ }
+ else
+ {
+ /* A write lock is mapped to an exclusive lock. */
+ nxLockFlags = NX_RANGE_LOCK_EXCL;
+ }
+
+ if (MyFlags & MY_DONT_WAIT)
+ {
+ /* Don't block on the lock. */
+ nxLockFlags |= NX_RANGE_LOCK_TRYLOCK;
+ }
+
+ if (!(nxErrno= NXFileRangeLock(fd, nxLockFlags, start, nxLength)))
+ DBUG_RETURN(0);
+ }
+ }
+#elif defined(__EMX__) || defined(OS2)
if (!_lock64( fd, locktype, start, length, MyFlags))
DBUG_RETURN(0);
@@ -103,8 +149,12 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
#endif /* HAVE_FCNTL */
#endif /* HAVE_LOCKING */
+#ifdef __NETWARE__
+ my_errno = nxErrno;
+#else
/* We got an error. We don't want EACCES errors */
my_errno=(errno == EACCES) ? EAGAIN : errno ? errno : -1;
+#endif
if (MyFlags & MY_WME)
{
if (locktype == F_UNLCK)
diff --git a/mysys/my_messnc.c b/mysys/my_messnc.c
index 6bb88443109..1f9df3c7c2c 100644
--- a/mysys/my_messnc.c
+++ b/mysys/my_messnc.c
@@ -23,7 +23,11 @@ int my_message_no_curses(uint error __attribute__((unused)),
DBUG_PRINT("enter",("message: %s",str));
(void) fflush(stdout);
if (MyFlags & ME_BELL)
+#ifdef __NETWARE__
+ ringbell(); /* Bell */
+#else
(void) fputc('\007',stderr); /* Bell */
+#endif /* __NETWARE__ */
if (my_progname)
{
(void)fputs(my_progname,stderr); (void)fputs(": ",stderr);
diff --git a/mysys/my_netware.c b/mysys/my_netware.c
new file mode 100644
index 00000000000..6c3242594df
--- /dev/null
+++ b/mysys/my_netware.c
@@ -0,0 +1,150 @@
+/* Copyright (C) 2003 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 */
+
+/*
+ Function specific to netware
+*/
+
+#include <mysys_priv.h>
+#ifdef __NETWARE__
+ #include <library.h>
+
+/*
+ PMUserLicenseRequest is an API exported by the polimgr.nlm
+ (loaded by the NetWare OS when it comes up) for use by other
+ NLM-based NetWare products/services.
+ PMUserLicenseRequest provides a couple of functions:
+ 1) it will optionally request a User license or ensure that
+ one already exists for the specified User in userInfo
+ 2) it utilizes the NetWare usage metering service to
+ record usage information about your product/service.
+*/
+
+long PMMeteredUsageRequest
+(
+ /*
+ NDS distinguished name or IP address or ??. asciiz string, e.g.
+ ".CN=Admin.O=this.T=MYTREE."
+ */
+ char *userInfo,
+ long infoType, /* see defined values */
+ /*
+ string used to identify the calling service, used to index the
+ metered info e.g. "iPrint"
+ */
+ char *serviceID,
+ char tranAddrType, /* type of address that follows */
+ char *tranAddr, /* ptr to a 10-byte array */
+ long flags, /* see defined values */
+ /* NLS error code, if any. NULL input is okay */
+ long *licRequestErrCode,
+ /* meter service error code, if any. NULL input is okay */
+ long *storeMeterInfoErrCode,
+ /*
+ error code from NLSMeter if
+ storeMeterInfoErrCode == PM_LICREQ_NLSMETERERROR.
+ NULL input is okay
+ */
+ long *NLSMeterErrCode
+);
+
+ypedef long(*PMUR)(char*, long, char*, char, char*, long, long*, long*,
+ long*);
+
+/* infoType */
+/* indicates that the info in the userInfo param is an NDS user */
+#define PM_USERINFO_TYPE_NDS 1
+/* indicates that the info in the userInfo param is NOT an NDS user */
+#define PM_USERINFO_TYPE_ADDRESS 2
+
+/* Flags */
+
+/*
+ Tells the service that it should not check to see if the NDS user
+ contained in the userInfo param has a NetWare User License - just
+ record metering information; this is ignored if infoType !=
+ PM_USERINFO_TYPE_NDS
+*/
+
+#define PM_FLAGS_METER_ONLY 0x0000001
+
+/*
+ Indicates that the values in the userInfo and serviceID parameters
+ are unicode strings, so that the metering service bypasses
+ converting these to unicode (again)
+*/
+#define PM_LICREQ_ALREADY_UNICODE 0x0000002
+/*
+ Useful only if infoType is PM_USERINFO_TYPE_NDS - indicates a "no
+ stop" policy of the calling service
+*/
+#define PM_LICREQ_ALWAYS_METER 0x0000004
+
+
+/*
+ net Address Types - system-defined types of net addresses that can
+ be used in the tranAddrType field
+*/
+
+#define NLS_TRAN_TYPE_IPX 0x00000001 /* An IPX address */
+#define NLS_TRAN_TYPE_IP 0x00000008 /* An IP address */
+#define NLS_ADDR_TYPE_MAC 0x000000F1 /* a MAC address */
+
+/*
+ Net Address Sizes - lengths that correspond to the tranAddrType
+ field (just fyi)
+*/
+#define NLS_IPX_ADDR_SIZE 10 /* the size of an IPX address */
+#define NLS_IP_ADDR_SIZE 4 /* the size of an IP address */
+#define NLS_MAC_ADDR_SIZE 6 /* the size of a MAC address */
+
+
+void netware_reg_user(const char *ip, const char *user,
+ const char *application)
+{
+ PMUR usage_request;
+ long licRequestErrCode = 0;
+ long storeMeterInfoErrCode = 0;
+ long nlsMeterErrCode = 0;
+
+ /* import the symbol */
+ usage_request= ((PMUR)ImportPublicObject(getnlmhandle(),
+ "PMMeteredUsageRequest"));
+ if (usage_request != NULL)
+ {
+ unsigned long iaddr;
+ char addr[NLS_IPX_ADDR_SIZE];
+
+ /* create address */
+ iaddr = htonl(inet_addr(ip));
+ bzero(addr, NLS_IPX_ADDR_SIZE);
+ memcpy(addr, &iaddr, NLS_IP_ADDR_SIZE);
+
+ /* call to NLS */
+ usage_request(user,
+ PM_USERINFO_TYPE_ADDRESS,
+ application,
+ NLS_TRAN_TYPE_IP,
+ addr,
+ PM_FLAGS_METER_ONLY,
+ &licRequestErrCode,
+ &storeMeterInfoErrCode,
+ &nlsMeterErrCode);
+ /* release symbol */
+ UnImportPublicObject(getnlmhandle(), "PMMeteredUsageRequest");
+ }
+}
+#endif /* __NETWARE__ */
diff --git a/mysys/my_os2cond.c b/mysys/my_os2cond.c
index d930aadb2d1..e23afb89e66 100644
--- a/mysys/my_os2cond.c
+++ b/mysys/my_os2cond.c
@@ -26,7 +26,6 @@
#include "mysys_priv.h"
#if defined(THREAD) && defined(OS2)
#include <m_string.h>
-//#undef getpid
#include <process.h>
#include <sys/timeb.h>
diff --git a/mysys/my_os2dirsrch.c b/mysys/my_os2dirsrch.c
index 773d6800d1e..8d1f6ddd947 100644
--- a/mysys/my_os2dirsrch.c
+++ b/mysys/my_os2dirsrch.c
@@ -1,4 +1,4 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
+/* Copyright (C) Yuri Dario & 2000-2003 MySQL AB
All the above parties has a full, independent copyright to
the following code, including the right to use the code in
any manner without any demands from the other parties.
@@ -18,77 +18,79 @@
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
+
/* Win32 directory search emulation */
#if defined(OS2)
-//#define _DEBUG
-
long _findfirst( char* path, struct _finddata_t* dos_file)
{
- HDIR hdir = HDIR_CREATE;
- APIRET rc;
- FILEFINDBUF3 buf3;
- ULONG entries = 1;
+ HDIR hdir = HDIR_CREATE;
+ APIRET rc;
+ FILEFINDBUF3 buf3;
+ ULONG entries = 1;
#ifdef _DEBUG
- printf( "_findfirst path %s\n", path);
+ printf( "_findfirst path %s\n", path);
#endif
- memset( &buf3, 0, sizeof( buf3));
- rc = DosFindFirst(
- path, /* Address of the ASCIIZ path name of the file or subdirectory to be found. */
- &hdir, /* Address of the handle associated with this DosFindFirst request. */
- FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
- &buf3, /* Result buffer. */
- sizeof( buf3), /* The length, in bytes, of pfindbuf. */
- &entries, /* Pointer to the number of entries: */
- FIL_STANDARD); /* The level of file information required. */
+ memset( &buf3, 0, sizeof( buf3));
+ rc = DosFindFirst(
+ path, /* The ASCIIZ path name of the file or subdirectory to be found. */
+ &hdir, /* The handle associated with this DosFindFirst request. */
+ FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
+ &buf3, /* Result buffer. */
+ sizeof( buf3), /* The length, in bytes, of pfindbuf. */
+ &entries, /* Pointer to the number of entries: */
+ FIL_STANDARD); /* The level of file information required. */
#ifdef _DEBUG
- printf( "_findfirst rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries, buf3.achName);
+ printf( "_findfirst rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries,
+ buf3.achName);
#endif
- if (rc /* && entries == 0 */)
- return -1;
-
- if (dos_file) {
- memset( dos_file, 0, sizeof( struct _finddata_t));
- strcpy( dos_file->name, buf3.achName);
- dos_file->size = buf3.cbFile;
- dos_file->attrib = buf3.attrFile;
- }
- return (ULONG) hdir;
+ if (rc /* && entries == 0 */)
+ return -1;
+
+ if (dos_file)
+ {
+ memset( dos_file, 0, sizeof( struct _finddata_t));
+ strcpy( dos_file->name, buf3.achName);
+ dos_file->size = buf3.cbFile;
+ dos_file->attrib = buf3.attrFile;
+ }
+ return (ULONG) hdir;
}
long _findnext( long hdir, struct _finddata_t* dos_file)
{
- APIRET rc;
- FILEFINDBUF3 buf3;
- ULONG entries = 1;
+ APIRET rc;
+ FILEFINDBUF3 buf3;
+ ULONG entries = 1;
- memset( &buf3, 0, sizeof( buf3));
- rc = DosFindNext(
- hdir,
- &buf3, /* Result buffer. */
- sizeof( buf3), /* The length, in bytes, of pfindbuf. */
- &entries); /* Pointer to the number of entries: */
+ memset( &buf3, 0, sizeof( buf3));
+ rc = DosFindNext(hdir,
+ &buf3, /* Result buffer. */
+ sizeof( buf3), /* Length, in bytes, of pfindbuf. */
+ &entries); /* Pointer to the number of entries */
#ifdef _DEBUG
- printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries, buf3.achName);
+ printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries,
+ buf3.achName);
#endif
- if (rc /* && entries == 0 */)
- return -1;
-
- if (dos_file) {
- memset( dos_file, 0, sizeof( struct _finddata_t));
- strcpy( dos_file->name, buf3.achName);
- dos_file->size = buf3.cbFile;
- dos_file->attrib = buf3.attrFile;
- }
- return 0;
+ if (rc /* && entries == 0 */)
+ return -1;
+
+ if (dos_file)
+ {
+ memset( dos_file, 0, sizeof( struct _finddata_t));
+ strcpy( dos_file->name, buf3.achName);
+ dos_file->size = buf3.cbFile;
+ dos_file->attrib = buf3.attrFile;
+ }
+ return 0;
}
void _findclose( long hdir)
@@ -101,82 +103,82 @@ void _findclose( long hdir)
#endif
}
-DIR* opendir( char* path)
+DIR* opendir(char* path)
{
- DIR* dir = (DIR*) calloc( 1, sizeof( DIR));
- char buffer[260];
- APIRET rc;
- ULONG entries = 1;
+ DIR* dir = (DIR*) calloc(1, sizeof( DIR));
+ char buffer[260];
+ APIRET rc;
+ ULONG entries = 1;
- strcpy( buffer, path);
- strcat( buffer, "*.*");
+ strmov(strmov(buffer, path), "*.*");
#ifdef _DEBUG
- printf( "_findfirst path %s\n", buffer);
+ printf( "_findfirst path %s\n", buffer);
#endif
- dir->hdir = HDIR_CREATE;
- memset( &dir->buf3, 0, sizeof( dir->buf3));
- rc = DosFindFirst(
- buffer, /* Address of the ASCIIZ path name of the file or subdirectory to be found. */
- &dir->hdir, /* Address of the handle associated with this DosFindFirst request. */
- FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
- &dir->buf3, /* Result buffer. */
- sizeof( dir->buf3), /* The length, in bytes, of pfindbuf. */
- &entries, /* Pointer to the number of entries: */
- FIL_STANDARD); /* The level of file information required. */
+ dir->hdir = HDIR_CREATE;
+ memset( &dir->buf3, 0, sizeof( dir->buf3));
+ rc = DosFindFirst(
+ buffer, /* Address of the ASCIIZ path name of the file or subdirectory to be found. */
+ &dir->hdir, /* Address of the handle associated with this DosFindFirst request. */
+ FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
+ &dir->buf3, /* Result buffer. */
+ sizeof( dir->buf3), /* The length, in bytes, of pfindbuf. */
+ &entries, /* Pointer to the number of entries: */
+ FIL_STANDARD); /* The level of file information required. */
#ifdef _DEBUG
- printf( "opendir rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries, dir->buf3.achName);
+ printf( "opendir rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries, dir->buf3.achName);
#endif
- if (rc /* && entries == 0 */)
- return NULL;
+ if (rc /* && entries == 0 */)
+ return NULL;
- return dir;
+ return dir;
}
+
struct dirent* readdir( DIR* dir)
{
- APIRET rc;
- //FILEFINDBUF3 buf3;
- ULONG entries = 1;
+ APIRET rc;
+ ULONG entries = 1;
- if (!dir->buf3.achName[0]) // file not found on previous query
- return NULL;
+ if (!dir->buf3.achName[0]) /* file not found on previous query */
+ return NULL;
- // copy last file name
- strcpy( dir->ent.d_name, dir->buf3.achName);
+ /* copy last file name */
+ strcpy( dir->ent.d_name, dir->buf3.achName);
- // query next file
- memset( &dir->buf3, 0, sizeof( dir->buf3));
- rc = DosFindNext(
- dir->hdir,
- &dir->buf3, /* Result buffer. */
- sizeof( dir->buf3), /* The length, in bytes, of pfindbuf. */
- &entries); /* Pointer to the number of entries: */
+ /* query next file */
+ memset( &dir->buf3, 0, sizeof( dir->buf3));
+ rc= DosFindNext(
+ dir->hdir,
+ &dir->buf3, /* Result buffer. */
+ sizeof(dir->buf3), /* Length, in bytes, of pfindbuf. */
+ &entries); /* Pointer to the number of entries */
#ifdef _DEBUG
- printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries, dir->buf3.achName);
+ printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries,
+ dir->buf3.achName);
#endif
- if (rc /* && entries == 0 */)
- strcpy( dir->buf3.achName, ""); // reset name for next query
+ if (rc /* && entries == 0 */)
+ *dir->buf3.achName= 0; /* reset name for next query */
- return &dir->ent;
+ return &dir->ent;
}
+
int closedir (DIR *dir)
{
- APIRET rc;
+ APIRET rc;
- rc = DosFindClose( dir->hdir);
+ rc = DosFindClose( dir->hdir);
#ifdef _DEBUG
- printf( "_findclose rc=%d hdir=%d\n", rc, dir->hdir);
+ printf( "_findclose rc=%d hdir=%d\n", rc, dir->hdir);
#endif
- free(dir);
- return 0;
+ free(dir);
+ return 0;
}
-
-#endif // OS2
+#endif /* OS2 */
diff --git a/mysys/my_os2dirsrch.h b/mysys/my_os2dirsrch.h
index e894d27b576..3889f628bad 100644
--- a/mysys/my_os2dirsrch.h
+++ b/mysys/my_os2dirsrch.h
@@ -29,26 +29,35 @@ extern "C" {
struct _finddata_t
{
- unsigned attrib;
- //unsigned long time_create; /* -1 for FAT file systems */
- //unsigned long time_access; /* -1 for FAT file systems */
- //unsigned long time_write;
- unsigned long size;
- char name[260];
- //uint16 wr_date;
- //uint16 wr_time;
+ unsigned attrib;
+#ifdef NOT_USED
+ unsigned long time_create; /* -1 for FAT file systems */
+ unsigned long time_access; /* -1 for FAT file systems */
+ unsigned long time_write;
+#endif
+ unsigned long size;
+ char name[260];
+#ifdef NOT_USED
+ uint16 wr_date;
+ uint16 wr_time;
+#endif
};
+
struct dirent
{
- //unsigned attrib;
- //unsigned long time_create; /* -1 for FAT file systems */
- //unsigned long time_access; /* -1 for FAT file systems */
- //unsigned long time_write;
- //unsigned long size;
- char d_name[260];
- //uint16 wr_date;
- //uint16 wr_time;
+#ifdef NOT_USED
+ unsigned attrib;
+ unsigned long time_create; /* -1 for FAT file systems */
+ unsigned long time_access; /* -1 for FAT file systems */
+ unsigned long time_write;
+ unsigned long size;
+#endif
+ char d_name[260];
+#ifdef NOT_USED
+ uint16 wr_date;
+ uint16 wr_time;
+#endif
};
struct DIR
@@ -62,16 +71,18 @@ DIR *opendir ( char *);
struct dirent *readdir (DIR *);
int closedir (DIR *);
-//#define _A_NORMAL FILE_NORMAL
-//#define _A_SUBDIR FILE_DIRECTORY
-//#define _A_RDONLY FILE_READONLY
+#ifdef NOT_USED
+#define _A_NORMAL FILE_NORMAL
+#define _A_SUBDIR FILE_DIRECTORY
+#define _A_RDONLY FILE_READONLY
-//long _findfirst( char*, struct _finddata_t*);
-//long _findnext( long, struct _finddata_t*);
-//void _findclose( long);
+long _findfirst( char*, struct _finddata_t*);
+long _findnext( long, struct _finddata_t*);
+void _findclose( long);
+#endif
#ifdef __cplusplus_00
}
#endif
-#endif // __MY_OS2DIRSRCH2_H__
+#endif /* __MY_OS2DIRSRCH2_H__ */
diff --git a/mysys/my_os2file64.c b/mysys/my_os2file64.c
index bc24c92b87f..786e083adc4 100644
--- a/mysys/my_os2file64.c
+++ b/mysys/my_os2file64.c
@@ -24,10 +24,11 @@ int _lock64( int fd, int locktype, my_off_t start,
my_off_t length, myf MyFlags);
int _sopen64( const char *name, int oflag, int shflag, int mask);
-//
-// this class is used to define a global c++ variable, that
-// is initialized before main() gets called.
-//
+/*
+ This class is used to define a global c++ variable, that
+ is initialized before main() gets called.
+*/
+
class File64bit
{
public:
@@ -150,7 +151,7 @@ static unsigned char const errno_tab[] =
_DosSetFilePtrL = NULL;
return;
}
- // notify success
+ /* notify success */
#ifdef MYSQL_SERVER
printf( "WSeB 64bit file API loaded.\n");
#endif
@@ -164,230 +165,230 @@ void _OS2errno( APIRET rc)
errno = errno_tab[rc];
}
-longlong _lseek64( int fd, longlong offset, int seektype)
-{
- APIRET rc;
- longlong actual;
-
- if (_DosSetFilePtrL)
- rc = _DosSetFilePtrL( fd, offset, seektype, &actual);
- else {
- ULONG ulActual;
- rc = DosSetFilePtr( fd, (long) offset, seektype, &ulActual);
- actual = ulActual;
- }
-
- if (!rc)
- return( actual);/* NO_ERROR */
-
- // set errno
- _OS2errno( rc);
- // seek failed
- return(-1);
-}
-inline _SetFileLocksL(HFILE hFile,
- PFILELOCKL pflUnlock,
- PFILELOCKL pflLock,
- ULONG timeout,
- ULONG flags)
+longlong _lseek64( int fd, longlong offset, int seektype)
{
- if (_DosSetFileLocksL) {
- APIRET rc;
- rc = _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags);
+ APIRET rc;
+ longlong actual;
- // on FAT/HPFS/LAN a INVALID_PARAMETER is returned, seems that
- // only JFS can handle >2GB ranges.
- if (rc != 87)
- return rc;
+ if (_DosSetFilePtrL)
+ rc = _DosSetFilePtrL( fd, offset, seektype, &actual);
+ else
+ {
+ ULONG ulActual;
+ rc = DosSetFilePtr( fd, (long) offset, seektype, &ulActual);
+ actual = ulActual;
+ }
- // got INVALID_PARAMETER, fallback to standard call
- }
+ if (!rc)
+ return( actual); /* NO_ERROR */
- FILELOCK flUnlock = { pflUnlock->lOffset, pflUnlock->lRange };
- FILELOCK flLock = { pflLock->lOffset, pflLock->lRange };
- return DosSetFileLocks( hFile, &flUnlock, &flLock, timeout, flags);
+ _OS2errno( rc); /* set errno */
+ return(-1); /* seek failed */
}
-int _lock64( int fd, int locktype, my_off_t start,
- my_off_t length, myf MyFlags)
-{
- FILELOCKL LockArea = {0,0}, UnlockArea = {0,0};
- ULONG readonly = 0;
- APIRET rc = -1;
-
- switch( locktype) {
- case F_UNLCK:
- UnlockArea.lOffset = start;
- UnlockArea.lRange = length ? length : LONGLONG_MAX;
- break;
-
- case F_RDLCK:
- case F_WRLCK:
- LockArea.lOffset = start;
- LockArea.lRange = length ? length : LONGLONG_MAX;
- readonly = (locktype == F_RDLCK ? 1 : 0);
- break;
-
- default:
- errno = EINVAL;
- rc = -1;
- break;
- }
-
- if (MyFlags & MY_DONT_WAIT) {
-
- rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly);
- //printf( "fd %d, locktype %d, rc %d (dont_wait)\n", fd, locktype, rc);
- if (rc == 33) { /* Lock Violation */
-
- DBUG_PRINT("info",("Was locked, trying with timeout"));
- rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 1 * 1000, readonly);
- //printf( "fd %d, locktype %d, rc %d (dont_wait with timeout)\n", fd, locktype, rc);
- }
-
- } else {
-
- while( rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly) && (rc == 33)) {
- printf(".");
- DosSleep(1 * 1000);
- }
- //printf( "fd %d, locktype %d, rc %d (wait2)\n", fd, locktype, rc);
- }
-
- if (!rc)
- return( 0);/* NO_ERROR */
- // set errno
- _OS2errno( rc);
- // lock failed
- return(-1);
+inline APIRET _SetFileLocksL(HFILE hFile,
+ PFILELOCKL pflUnlock,
+ PFILELOCKL pflLock,
+ ULONG timeout,
+ ULONG flags)
+{
+ if (_DosSetFileLocksL)
+ {
+ APIRET rc;
+ rc = _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags);
+
+ /*
+ on FAT/HPFS/LAN a INVALID_PARAMETER is returned, seems that
+ only JFS can handle >2GB ranges.
+ */
+ if (rc != 87)
+ return rc;
+ /* got INVALID_PARAMETER, fallback to standard call */
+ }
+
+ FILELOCK flUnlock = { pflUnlock->lOffset, pflUnlock->lRange };
+ FILELOCK flLock = { pflLock->lOffset, pflLock->lRange };
+ return DosSetFileLocks( hFile, &flUnlock, &flLock, timeout, flags);
}
-int sopen( const char *name, int oflag, int shflag, int mask)
+
+int _lock64( int fd, int locktype, my_off_t start,
+ my_off_t length, myf MyFlags)
{
- int fail_errno;
- APIRET rc = 0;
- HFILE hf = 0;
- ULONG ulAction = 0;
- LONGLONG cbFile = 0;
- ULONG ulAttribute = FILE_NORMAL;
- ULONG fsOpenFlags = 0;
- ULONG fsOpenMode = 0;
-
- /* Extract the access mode and sharing mode bits. */
- fsOpenMode = (shflag & 0xFF) | (oflag & 0x03);
-
- /* Translate ERROR_OPEN_FAILED to ENOENT unless O_EXCL is set (see
- below). */
- fail_errno = ENOENT;
-
- /* Compute `open_flag' depending on `flags'. Note that _SO_CREAT is
- set for O_CREAT. */
-
- if (oflag & O_CREAT)
- {
- if (oflag & O_EXCL)
- {
- fsOpenFlags = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
- fail_errno = EEXIST;
- }
- else if (oflag & O_TRUNC)
- fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
- else
- fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
-
- if (mask & S_IWRITE)
- ulAttribute = FILE_NORMAL;
- else
- ulAttribute = FILE_READONLY;
+ FILELOCKL LockArea = {0,0}, UnlockArea = {0,0};
+ ULONG readonly = 0;
+ APIRET rc = -1;
+
+ switch (locktype) {
+ case F_UNLCK:
+ UnlockArea.lOffset = start;
+ UnlockArea.lRange = length ? length : LONGLONG_MAX;
+ break;
+
+ case F_RDLCK:
+ case F_WRLCK:
+ LockArea.lOffset = start;
+ LockArea.lRange = length ? length : LONGLONG_MAX;
+ readonly = (locktype == F_RDLCK ? 1 : 0);
+ break;
+
+ default:
+ errno = EINVAL;
+ rc = -1;
+ break;
+ }
+
+ if (MyFlags & MY_DONT_WAIT)
+ {
+ rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly);
+ /* printf("fd %d, locktype %d, rc %d (dont_wait)\n", fd, locktype, rc); */
+ if (rc == 33) { /* Lock Violation */
+
+ DBUG_PRINT("info",("Was locked, trying with timeout"));
+ rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 1 * 1000, readonly);
+ /* printf( "fd %d, locktype %d, rc %d (dont_wait with timeout)\n", fd, locktype, rc); */
+ }
+ }
+ else
+ {
+ while (rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly) &&
+ (rc == 33))
+ {
+ printf(".");
+ DosSleep(1 * 1000);
+ }
+ /* printf( "fd %d, locktype %d, rc %d (wait2)\n", fd, locktype, rc); */
+ }
+ if (!rc)
+ return(0); /* NO_ERROR */
+ _OS2errno( rc); /* set errno */
+ return(-1); /* lock failed */
+}
- }
- else if (oflag & O_TRUNC)
- fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
- else
- fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
-
- /* Try to open the file and handle errors. */
- if (_DosOpenL)
- rc = _DosOpenL( name, &hf, &ulAction, cbFile,
- ulAttribute, fsOpenFlags, fsOpenMode, NULL);
- else
- rc = DosOpen( name, &hf, &ulAction, (LONG) cbFile,
- ulAttribute, fsOpenFlags, fsOpenMode, NULL);
-
- if (rc == ERROR_OPEN_FAILED)
- {
- errno = fail_errno;
- return -1;
- }
- if (rc != 0)
- {
- // set errno
- _OS2errno( rc);
- return -1;
- }
- if (oflag & O_APPEND)
- _lseek64( hf, 0L, SEEK_END);
+int sopen(const char *name, int oflag, int shflag, int mask)
+{
+ int fail_errno;
+ APIRET rc = 0;
+ HFILE hf = 0;
+ ULONG ulAction = 0;
+ LONGLONG cbFile = 0;
+ ULONG ulAttribute = FILE_NORMAL;
+ ULONG fsOpenFlags = 0;
+ ULONG fsOpenMode = 0;
+
+ /* Extract the access mode and sharing mode bits. */
+ fsOpenMode = (shflag & 0xFF) | (oflag & 0x03);
+
+ /*
+ Translate ERROR_OPEN_FAILED to ENOENT unless O_EXCL is set (see
+ below).
+ */
+ fail_errno = ENOENT;
+
+ /*
+ Compute `open_flag' depending on `flags'. Note that _SO_CREAT is
+ set for O_CREAT.
+ */
+
+ if (oflag & O_CREAT)
+ {
+ if (oflag & O_EXCL)
+ {
+ fsOpenFlags = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
+ fail_errno = EEXIST;
+ }
+ else if (oflag & O_TRUNC)
+ fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
+ else
+ fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
+
+ if (mask & S_IWRITE)
+ ulAttribute = FILE_NORMAL;
+ else
+ ulAttribute = FILE_READONLY;
+
+ }
+ else if (oflag & O_TRUNC)
+ fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
+ else
+ fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
- return hf;
+ /* Try to open the file and handle errors. */
+ if (_DosOpenL)
+ rc = _DosOpenL( name, &hf, &ulAction, cbFile,
+ ulAttribute, fsOpenFlags, fsOpenMode, NULL);
+ else
+ rc = DosOpen( name, &hf, &ulAction, (LONG) cbFile,
+ ulAttribute, fsOpenFlags, fsOpenMode, NULL);
+
+ if (rc == ERROR_OPEN_FAILED)
+ {
+ errno = fail_errno;
+ return -1;
+ }
+ if (rc != 0)
+ {
+ _OS2errno( rc); /* set errno */
+ return -1;
+ }
+ if (oflag & O_APPEND)
+ _lseek64( hf, 0L, SEEK_END);
+ return hf;
}
-int read( int fd, void *buffer, unsigned int count)
-{
- APIRET rc;
- ULONG actual;
- rc = DosRead( fd, (PVOID) buffer, count, &actual);
+int read(int fd, void *buffer, unsigned int count)
+{
+ APIRET rc;
+ ULONG actual;
- if (!rc)
- return( actual);/* NO_ERROR */
+ rc= DosRead( fd, (PVOID) buffer, count, &actual);
- // set errno
- _OS2errno( rc);
- // write failed
- return(-1);
+ if (!rc)
+ return( actual); /* NO_ERROR */
+ _OS2errno( rc); /* set errno */
+ return(-1); /* read failed */
}
-int write( int fd, const void *buffer, unsigned int count)
-{
- APIRET rc;
- ULONG actual;
- rc = DosWrite( fd, (PVOID) buffer, count, &actual);
+int write(int fd, const void *buffer, unsigned int count)
+{
+ APIRET rc;
+ ULONG actual;
- if (!rc)
- return( actual);/* NO_ERROR */
+ rc = DosWrite( fd, (PVOID) buffer, count, &actual);
- // set errno
- _OS2errno( rc);
- // write failed
- return(-1);
+ if (!rc)
+ return( actual); /* NO_ERROR */
+ _OS2errno( rc); /* set errno */
+ return(-1); /* write failed */
}
-int close( int fd)
-{
- APIRET rc;
- ULONG actual;
- rc = DosClose( fd);
+int close( int fd)
+{
+ APIRET rc;
+ ULONG actual;
- if (!rc)
- return( 0);/* NO_ERROR */
+ rc = DosClose( fd);
- // set errno
- _OS2errno( rc);
- // write failed
- return(-1);
+ if (!rc)
+ return( 0); /* NO_ERROR */
+ _OS2errno( rc); /* set errno */
+ return(-1); /* close failed */
}
-inline int open( const char *name, int oflag)
+
+int open( const char *name, int oflag)
{
return sopen( name, oflag, OPEN_SHARE_DENYNONE, S_IREAD | S_IWRITE);
}
-inline int open( const char *name, int oflag, int mask)
+
+int open( const char *name, int oflag, int mask)
{
return sopen( name, oflag, OPEN_SHARE_DENYNONE, mask);
}
diff --git a/mysys/my_os2mutex.c b/mysys/my_os2mutex.c
index 718aa9f2932..5010d6e8dd5 100644
--- a/mysys/my_os2mutex.c
+++ b/mysys/my_os2mutex.c
@@ -36,63 +36,48 @@
#include <stdlib.h>
#include <errno.h>
#ifdef _THREAD_SAFE
-//#include <pthread.h>
-//#include "pthread_private.h"
int
pthread_mutex_init(pthread_mutex_t * mutex,
const pthread_mutexattr_t * mutex_attr)
{
- APIRET rc = 0;
-
- rc = DosCreateMutexSem(NULL,mutex,0,0);
-
- /* Return the completion status: */
- return (0);
+ (void) DosCreateMutexSem(NULL,mutex,0,0);
+ return (0); /* Return the completion status: */
}
+
int
pthread_mutex_destroy(pthread_mutex_t * mutex)
{
- APIRET rc = 0;
-
+ APIRET rc;
- do {
- rc = DosCloseMutexSem(*mutex);
- if (rc == 301) DosReleaseMutexSem(*mutex);
- } while (rc == 301);
+ do
+ {
+ rc = DosCloseMutexSem(*mutex);
+ if (rc == 301) DosReleaseMutexSem(*mutex);
+ } while (rc == 301);
- *mutex = 0;
-
- /* Return the completion status: */
- return (0);
+ *mutex = 0;
+ return (0); /* Return the completion status: */
}
int
pthread_mutex_lock(pthread_mutex_t * mutex)
{
- int ret = 0;
- int status = 0;
- APIRET rc = 0;
+ APIRET rc;
- rc = DosRequestMutexSem(*mutex,SEM_INDEFINITE_WAIT);
- if (rc)
- return(EINVAL);
- /* Return the completion status: */
- return (0);
+ rc = DosRequestMutexSem(*mutex,SEM_INDEFINITE_WAIT);
+ if (rc)
+ return(EINVAL);
+ return (0); /* Return the completion status: */
}
+
int
pthread_mutex_unlock(pthread_mutex_t * mutex)
{
- int ret = 0;
- APIRET rc = 0;
- int status;
-
- rc = DosReleaseMutexSem(*mutex);
-
- /* Return the completion status: */
- return (0);
+ (void) DosReleaseMutexSem(*mutex);
+ return (0); /* Return the completion status: */
}
#endif
diff --git a/mysys/my_os2thread.c b/mysys/my_os2thread.c
index 6f196f43d75..0696f480a91 100644
--- a/mysys/my_os2thread.c
+++ b/mysys/my_os2thread.c
@@ -61,10 +61,9 @@ static pthread_handler_decl(pthread_start,param)
win_pthread_self=((struct pthread_map *) param)->pthreadself;
pthread_mutex_unlock(&THR_LOCK_thread);
free((char*) param); /* Free param from create */
- //pthread_exit((void*) (*func)(func_param));
+ /* pthread_exit((void*) (*func)(func_param)); */
(*func)(func_param);
DBUG_RETURN(0);
- //return 0; /* Safety */
}
diff --git a/mysys/my_os2tls.c b/mysys/my_os2tls.c
index 1598fa34e2b..f7cf3b09283 100644
--- a/mysys/my_os2tls.c
+++ b/mysys/my_os2tls.c
@@ -30,115 +30,122 @@ PULONG tls_storage; /* TLS local storage */
DWORD tls_bits[2]; /* TLS in-use bits */
pthread_mutex_t tls_mutex; /* TLS mutex for in-use bits */
+
DWORD TlsAlloc( void)
{
- DWORD index = -1;
- DWORD mask, tibidx;
- int i;
-
- if (tls_storage == NULL) {
-
- APIRET rc;
-
- // allocate memory for TLS storage
- rc = DosAllocThreadLocalMemory( 1, &tls_storage);
- if (rc) {
- fprintf( stderr, "DosAllocThreadLocalMemory error: return code = %u\n", rc);
- }
-
- // create a mutex
- if (pthread_mutex_init( &tls_mutex, NULL))
- fprintf( stderr, "Failed to init TLS mutex\n");
- }
-
- pthread_mutex_lock( &tls_mutex);
-
- tibidx = 0;
- if (tls_bits[0] == 0xFFFFFFFF) {
- if (tls_bits[1] == 0xFFFFFFFF) {
- fprintf( stderr, "tid#%d, no more TLS bits available\n", _threadid);
- pthread_mutex_unlock( &tls_mutex);
- return -1;
- }
- tibidx = 1;
- }
- for( i=0; i<32; i++) {
- mask = (1 << i);
- if ((tls_bits[ tibidx] & mask) == 0) {
- tls_bits[ tibidx] |= mask;
- index = (tibidx*32) + i;
- break;
- }
- }
- tls_storage[index] = 0;
-
- pthread_mutex_unlock( &tls_mutex);
-
- //fprintf( stderr, "tid#%d, TlsAlloc index %d\n", _threadid, index);
-
- return index;
+ DWORD index = -1;
+ DWORD mask, tibidx;
+ int i;
+
+ if (tls_storage == NULL)
+ {
+
+ APIRET rc;
+
+ /* allocate memory for TLS storage */
+ rc = DosAllocThreadLocalMemory( 1, &tls_storage);
+ if (rc)
+ fprintf( stderr, "DosAllocThreadLocalMemory error: return code = %u\n",
+ rc);
+ /* create a mutex */
+ if (pthread_mutex_init( &tls_mutex, NULL))
+ fprintf( stderr, "Failed to init TLS mutex\n");
+ }
+
+ pthread_mutex_lock( &tls_mutex);
+
+ tibidx = 0;
+ if (tls_bits[0] == 0xFFFFFFFF)
+ {
+ if (tls_bits[1] == 0xFFFFFFFF)
+ {
+ fprintf( stderr, "tid#%d, no more TLS bits available\n", _threadid);
+ pthread_mutex_unlock( &tls_mutex);
+ return -1;
+ }
+ tibidx = 1;
+ }
+
+ for (i=0; i<32; i++)
+ {
+ mask = (1 << i);
+ if ((tls_bits[ tibidx] & mask) == 0)
+ {
+ tls_bits[ tibidx] |= mask;
+ index = (tibidx*32) + i;
+ break;
+ }
+ }
+ tls_storage[index] = 0;
+
+ pthread_mutex_unlock( &tls_mutex);
+ /* fprintf( stderr, "tid#%d, TlsAlloc index %d\n", _threadid, index); */
+ return index;
}
-BOOL TlsFree( DWORD index)
+BOOL TlsFree( DWORD index)
{
- int tlsidx;
- DWORD mask;
-
- if (index >= TLS_MINIMUM_AVAILABLE)
- return NULL;
-
- pthread_mutex_lock( &tls_mutex);
-
- tlsidx = 0;
- if (index > 32) {
- tlsidx++;
- }
- mask = (1 << index);
- if (tls_bits[ tlsidx] & mask) {
- tls_bits[tlsidx] &= ~mask;
- tls_storage[index] = 0;
- pthread_mutex_unlock( &tls_mutex);
- return TRUE;
- }
+ int tlsidx;
+ DWORD mask;
- pthread_mutex_unlock( &tls_mutex);
- return FALSE;
-}
+ if (index >= TLS_MINIMUM_AVAILABLE)
+ return NULL;
+ pthread_mutex_lock( &tls_mutex);
-PVOID TlsGetValue( DWORD index)
-{
- if (index >= TLS_MINIMUM_AVAILABLE)
- return NULL;
-
- // verify if memory has been allocated for this thread
- if (*tls_storage == NULL) {
- // allocate memory for indexes
- *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
- //fprintf( stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage);
- }
-
- ULONG* tls_array = (ULONG*) *tls_storage;
- return (PVOID) tls_array[ index];
+ tlsidx = 0;
+ if (index > 32)
+ tlsidx++;
+
+ mask = (1 << index);
+ if (tls_bits[ tlsidx] & mask)
+ {
+ tls_bits[tlsidx] &= ~mask;
+ tls_storage[index] = 0;
+ pthread_mutex_unlock( &tls_mutex);
+ return TRUE;
+ }
+
+ pthread_mutex_unlock( &tls_mutex);
+ return FALSE;
}
-BOOL TlsSetValue( DWORD index, PVOID val)
-{
- // verify if memory has been allocated for this thread
- if (*tls_storage == NULL) {
- // allocate memory for indexes
- *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
- //fprintf( stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage);
- }
+PVOID TlsGetValue( DWORD index)
+{
+ if (index >= TLS_MINIMUM_AVAILABLE)
+ return NULL;
+
+ /* verify if memory has been allocated for this thread */
+ if (*tls_storage == NULL)
+ {
+ /* allocate memory for indexes */
+ *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
+ /* fprintf(stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage); */
+ }
+
+ ULONG* tls_array = (ULONG*) *tls_storage;
+ return (PVOID) tls_array[index];
+}
- if (index >= TLS_MINIMUM_AVAILABLE)
- return FALSE;
- ULONG* tls_array = (ULONG*) *tls_storage;
- //fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x (old)\n", _threadid, tls_array, index, tls_array[ index]);
- tls_array[ index] = (ULONG) val;
- //fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x\n", _threadid, tls_array, index, val);
+BOOL TlsSetValue( DWORD index, PVOID val)
+{
- return TRUE;
+ /* verify if memory has been allocated for this thread */
+ if (*tls_storage == NULL)
+ {
+ /* allocate memory for indexes */
+ *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
+ /* fprintf(stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage); */
+ }
+
+ if (index >= TLS_MINIMUM_AVAILABLE)
+ return FALSE;
+
+ ULONG* tls_array = (ULONG*) *tls_storage;
+ /* fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x (old)\n", _threadid, tls_array, index, tls_array[ index]); */
+ tls_array[ index] = (ULONG) val;
+ /* fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x\n", _threadid, tls_array, index, val); */
+ return TRUE;
}
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index 07e8ecec6ac..0de7041fae7 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -425,6 +425,19 @@ int my_pthread_cond_init(pthread_cond_t *mp, const pthread_condattr_t *attr)
#endif
+#ifdef __NETWARE__
+/* NetWare does not re-acquire the lock if the condition fails */
+int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+ struct timespec *abstime)
+{
+ int err= pthread_cond_timedwait(cond, mutex, abstime);
+ if (err)
+ pthread_mutex_lock(mutex);
+ return err;
+}
+#endif /* __NETWARE__ */
+
+
/*****************************************************************************
Patches for HPUX
We need these because the pthread_mutex.. code returns -1 on error,
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index b5a79d9454b..9ba03cd9526 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -90,7 +90,7 @@ int my_copystat(const char *from, const char *to, int MyFlags)
return 1;
VOID(chmod(to, statbuf.st_mode & 07777)); /* Copy modes */
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING)
{
if (MyFlags & MY_LINK_WARNING)
diff --git a/mysys/mf_sleep.c b/mysys/my_sleep.c
index 49db465e7c5..3de2d2abd13 100644
--- a/mysys/mf_sleep.c
+++ b/mysys/my_sleep.c
@@ -14,22 +14,25 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Wait a given time (On systems that dont have sleep !!; MSDOS) */
+/* Wait a given number of microseconds */
#include "mysys_priv.h"
#include <m_string.h>
-#ifdef _MSC_VER
-
-void sleep(sec)
-int sec;
+void my_sleep(ulong m_seconds)
{
- ulong start;
- DBUG_ENTER("sleep");
-
- start=(ulong) time((time_t*) 0);
+#ifdef __NETWARE__
+ delay(m_seconds/1000+1);
+#elif defined(OS2)
+ DosSleep(m_seconds/1000+1);
+#elif defined(HAVE_SELECT)
+ struct timeval t;
+ t.tv_sec= m_seconds / 1000000L;
+ t.tv_usec= m_seconds % 1000000L;
+ select(0,0,0,0,&t); /* sleep */
+#else
+ uint sec= (uint) (m_seconds / 1000000L);
+ ulong start= (ulong) time((time_t*) 0);
while ((ulong) time((time_t*) 0) < start+sec);
- DBUG_VOID_RETURN;
-} /* sleep */
-
-#endif /* MSDOS */
+#endif
+}
diff --git a/mysys/my_tempnam.c b/mysys/my_tempnam.c
index 4fa2dd2abc4..a652fae3574 100644
--- a/mysys/my_tempnam.c
+++ b/mysys/my_tempnam.c
@@ -38,7 +38,7 @@
#endif
#ifdef HAVE_TEMPNAM
-#if !defined( MSDOS) && !defined(OS2)
+#if !defined( MSDOS) && !defined(OS2) && !defined(__NETWARE__)
extern char **environ;
#endif
#endif
@@ -104,14 +104,14 @@ my_string my_tempnam(const char *dir, const char *pfx,
dir=temp;
}
#ifdef OS2
- // changing environ variable doesn't work with VACPP
+ /* changing environ variable doesn't work with VACPP */
char buffer[256];
sprintf( buffer, "TMP=%s", dir);
- // remove ending backslash
+ /* remove ending backslash */
if (buffer[strlen(buffer)-1] == '\\')
buffer[strlen(buffer)-1] = '\0';
putenv( buffer);
-#else
+#elif !defined(__NETWARE__)
old_env=(char**)environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
@@ -120,7 +120,7 @@ my_string my_tempnam(const char *dir, const char *pfx,
}
#endif
res=tempnam((char*) dir,(my_string) pfx); /* Use stand. dir with prefix */
-#ifndef OS2
+#if !defined(OS2) && !defined(__NETWARE__)
((char**) environ)=(char**) old_env;
#endif
if (!res)
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 45c10e5a7b6..59466083b28 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -94,6 +94,18 @@ void my_thread_global_end(void)
#ifdef PPTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
pthread_mutexattr_destroy(&my_errchk_mutexattr);
#endif
+ pthread_mutex_destroy(&THR_LOCK_malloc);
+ pthread_mutex_destroy(&THR_LOCK_open);
+ pthread_mutex_destroy(&THR_LOCK_keycache);
+ pthread_mutex_destroy(&THR_LOCK_lock);
+ pthread_mutex_destroy(&THR_LOCK_isam);
+ pthread_mutex_destroy(&THR_LOCK_myisam);
+ pthread_mutex_destroy(&THR_LOCK_heap);
+ pthread_mutex_destroy(&THR_LOCK_net);
+ pthread_mutex_destroy(&THR_LOCK_charset);
+#ifndef HAVE_LOCALTIME_R
+ pthread_mutex_destroy(&LOCK_localtime_r);
+#endif
#ifndef HAVE_GETHOSTBYNAME_R
pthread_mutex_destroy(&LOCK_gethostbyname_r);
#endif
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 75d77ed9987..f79431a0b0b 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -23,9 +23,9 @@
#ifdef THREAD
#include <my_pthread.h>
-extern pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
- THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_net,THR_LOCK_charset;
-extern pthread_mutex_t LOCK_bitmap;
+extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
+extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net;
+extern pthread_mutex_t THR_LOCK_charset;
#else
#include <my_no_pthread.h>
#endif
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index 89079fba31c..9cbb178edb4 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -239,8 +239,8 @@ gptr _myrealloc (register gptr pPtr, register uint uSize,
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY)
{
- fprintf (stderr, "Reallocating unallocated data at line %d, '%s'\n",
- uLine, sFile);
+ fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n",
+ uLine, sFile);
DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
uLine, sFile));
(void) fflush(stderr);
@@ -295,8 +295,8 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY)
{
- fprintf (stderr, "Freeing unallocated data at line %d, '%s'\n",
- uLine, sFile);
+ fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n",
+ uLine, sFile);
DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile));
(void) fflush(stderr);
DBUG_VOID_RETURN;
@@ -336,8 +336,8 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
{
if (!ptr)
{
- fprintf (stderr, "%s NULL pointer at line %d, '%s'\n",
- where,uLine, sFile);
+ fprintf(stderr, "Error: %s NULL pointer at line %d, '%s'\n",
+ where,uLine, sFile);
DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile));
(void) fflush(stderr);
return 1;
@@ -345,8 +345,8 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
#ifndef _MSC_VER
if ((long) ptr & (ALIGN_SIZE(1)-1))
{
- fprintf (stderr, "%s wrong aligned pointer at line %d, '%s'\n",
- where,uLine, sFile);
+ fprintf(stderr, "Error: %s wrong aligned pointer at line %d, '%s'\n",
+ where,uLine, sFile);
DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'",
uLine,sFile));
(void) fflush(stderr);
@@ -355,8 +355,8 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
#endif
if (ptr < sf_min_adress || ptr > sf_max_adress)
{
- fprintf (stderr, "%s pointer out of range at line %d, '%s'\n",
- where,uLine, sFile);
+ fprintf(stderr, "Error: %s pointer out of range at line %d, '%s'\n",
+ where,uLine, sFile);
DBUG_PRINT("safe",("Pointer out of range at line %d '%s'",
uLine,sFile));
(void) fflush(stderr);
@@ -388,7 +388,7 @@ void TERMINATE (FILE *file)
{
if (file)
{
- fprintf (file, "cNewCount: %d\n", cNewCount);
+ fprintf(file, "Warning: Not freed memory segments: %d\n", cNewCount);
(void) fflush(file);
}
DBUG_PRINT("safe",("cNewCount: %d",cNewCount));
@@ -403,7 +403,7 @@ void TERMINATE (FILE *file)
{
if (file)
{
- fprintf(file, "Memory that was not free'ed (%ld bytes):\n",lCurMemory);
+ fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n",lCurMemory);
(void) fflush(file);
}
DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",lCurMemory));
@@ -411,11 +411,11 @@ void TERMINATE (FILE *file)
{
if (file)
{
- fprintf (file,
- "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
- pPtr -> uDataSize,
- (ulong) &(pPtr -> aData[sf_malloc_prehunc]),
- pPtr -> uLineNum, pPtr -> sFileName);
+ fprintf(file,
+ "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
+ pPtr -> uDataSize,
+ (ulong) &(pPtr -> aData[sf_malloc_prehunc]),
+ pPtr -> uLineNum, pPtr -> sFileName);
fprintf(file, "\n");
(void) fflush(file);
}
@@ -429,8 +429,8 @@ void TERMINATE (FILE *file)
/* Report the memory usage statistics */
if (file)
{
- fprintf (file, "Maximum memory usage: %ld bytes (%ldk)\n",
- lMaxMemory, (lMaxMemory + 1023L) / 1024L);
+ fprintf(file, "Maximum memory usage: %ld bytes (%ldk)\n",
+ lMaxMemory, (lMaxMemory + 1023L) / 1024L);
(void) fflush(file);
}
DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)",
@@ -453,9 +453,9 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY)
{
- fprintf (stderr, "Memory allocated at %s:%d was underrun,",
- pRec -> sFileName, pRec -> uLineNum);
- fprintf (stderr, " discovered at %s:%d\n", sFile, uLine);
+ fprintf(stderr, "Error: Memory allocated at %s:%d was underrun,",
+ pRec -> sFileName, pRec -> uLineNum);
+ fprintf(stderr, " discovered at %s:%d\n", sFile, uLine);
(void) fflush(stderr);
DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]),
@@ -472,9 +472,9 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
*magicp++ != MAGICEND2 ||
*magicp++ != MAGICEND3)
{
- fprintf (stderr, "Memory allocated at %s:%d was overrun,",
- pRec -> sFileName, pRec -> uLineNum);
- fprintf (stderr, " discovered at '%s:%d'\n", sFile, uLine);
+ fprintf(stderr, "Error: Memory allocated at %s:%d was overrun,",
+ pRec -> sFileName, pRec -> uLineNum);
+ fprintf(stderr, " discovered at '%s:%d'\n", sFile, uLine);
(void) fflush(stderr);
DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]),
@@ -505,9 +505,9 @@ int _sanity (const char *sFile, uint uLine)
pthread_mutex_unlock(&THR_LOCK_malloc);
if (count || pTmp)
{
- const char *format="Safemalloc link list destroyed, discovered at '%s:%d'";
- fprintf (stderr, format, sFile, uLine); fputc('\n',stderr);
- fprintf (stderr, "root=%p,count=%d,pTmp=%p\n", pRememberRoot,count,pTmp);
+ const char *format="Error: Safemalloc link list destroyed, discovered at '%s:%d'";
+ fprintf(stderr, format, sFile, uLine); fputc('\n',stderr);
+ fprintf(stderr, "root=%p,count=%d,pTmp=%p\n", pRememberRoot,count,pTmp);
(void) fflush(stderr);
DBUG_PRINT("safe",(format, sFile, uLine));
flag=1;
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index ed468b5ef50..6697b9d3360 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -229,8 +229,13 @@ void thr_end_alarm(thr_alarm_t *alarmed)
(long) *alarmed));
}
if (alarm_aborted && !alarm_queue.elements)
+ {
delete_queue(&alarm_queue);
- pthread_mutex_unlock(&LOCK_alarm);
+ pthread_mutex_unlock(&LOCK_alarm);
+ pthread_mutex_destroy(&LOCK_alarm);
+ }
+ else
+ pthread_mutex_unlock(&LOCK_alarm);
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
DBUG_VOID_RETURN;
}
@@ -367,19 +372,25 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
void end_thr_alarm(void)
{
DBUG_ENTER("end_thr_alarm");
- pthread_mutex_lock(&LOCK_alarm);
if (!alarm_aborted)
- {
+ {
+ my_bool deleted=0;
+ pthread_mutex_lock(&LOCK_alarm);
DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements));
alarm_aborted=1; /* mark aborted */
if (!alarm_queue.elements)
+ {
+ deleted= 1;
delete_queue(&alarm_queue);
+ }
if (pthread_equal(pthread_self(),alarm_thread))
alarm(1); /* Shut down everything soon */
else
reschedule_alarms();
+ pthread_mutex_unlock(&LOCK_alarm);
+ if (deleted)
+ pthread_mutex_destroy(&LOCK_alarm);
}
- pthread_mutex_unlock(&LOCK_alarm);
DBUG_VOID_RETURN;
}
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index 6de96f0a24a..2aabe2f500a 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000-2003 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
@@ -20,13 +20,15 @@
#if defined(HAVE_LINUXTHREADS) && !defined (__USE_UNIX98)
#define __USE_UNIX98 /* To get rw locks under Linux */
#endif
-#include <m_string.h>
#if defined(THREAD) && defined(SAFE_MUTEX)
#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
-#include <my_pthread.h>
+#include "mysys_priv.h"
+#include "my_static.h"
+#include <m_string.h>
#ifndef DO_NOT_REMOVE_THREAD_WRAPPERS
/* Remove wrappers */
+#undef pthread_mutex_t
#undef pthread_mutex_init
#undef pthread_mutex_lock
#undef pthread_mutex_unlock
@@ -38,15 +40,55 @@
#endif
#endif /* DO_NOT_REMOVE_THREAD_WRAPPERS */
+static pthread_mutex_t THR_LOCK_mutex;
+static ulong safe_mutex_count= 0; /* Number of mutexes created */
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+static struct st_safe_mutex_info_t *safe_mutex_root= NULL;
+#endif
+
+void safe_mutex_global_init(void)
+{
+ pthread_mutex_init(&THR_LOCK_mutex,MY_MUTEX_INIT_FAST);
+}
+
+
int safe_mutex_init(safe_mutex_t *mp,
- const pthread_mutexattr_t *attr __attribute__((unused)))
+ const pthread_mutexattr_t *attr __attribute__((unused)),
+ const char *file __attribute__((unused)),
+ uint line __attribute__((unused)))
{
bzero((char*) mp,sizeof(*mp));
pthread_mutex_init(&mp->global,MY_MUTEX_INIT_ERRCHK);
pthread_mutex_init(&mp->mutex,attr);
+
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+ /*
+ Monitor the freeing of mutexes. This code depends on single thread init
+ and destroy
+ */
+ if ((mp->info= (safe_mutex_info_t *) malloc(sizeof(safe_mutex_info_t))))
+ {
+ struct st_safe_mutex_info_t *info =mp->info;
+
+ info->init_file= (char *) file;
+ info->init_line= line;
+ info->prev= NULL;
+ info->next= NULL;
+
+ pthread_mutex_lock(&THR_LOCK_mutex);
+ if ((info->next= safe_mutex_root))
+ safe_mutex_root->prev= info;
+ safe_mutex_root= info;
+ safe_mutex_count++;
+ pthread_mutex_unlock(&THR_LOCK_mutex);
+ }
+#else
+ thread_safe_increment(safe_mutex_count, &THR_LOCK_mutex);
+#endif /* SAFE_MUTEX_DETECT_DESTROY */
return 0;
}
+
int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
{
int error;
@@ -199,6 +241,11 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
fflush(stderr);
abort();
}
+#ifdef __NETWARE__
+ /* NetWare doesn't re-acquire the mutex on an error */
+ if (error && pthread_mutex_lock(&mp->mutex))
+ mp->count--;
+#endif /* __NETWARE__ */
mp->thread=pthread_self();
mp->file= (char*) file;
mp->line=line;
@@ -206,6 +253,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
return error;
}
+
int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
{
int error=0;
@@ -225,7 +273,70 @@ int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
if (pthread_mutex_destroy(&mp->mutex))
error=1;
#endif
+
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+ if (mp->info)
+ {
+ struct st_safe_mutex_info_t *info= mp->info;
+ pthread_mutex_lock(&THR_LOCK_mutex);
+
+ if (info->prev)
+ info->prev->next = info->next;
+ else
+ safe_mutex_root = info->next;
+ if (info->next)
+ info->next->prev = info->prev;
+ safe_mutex_count--;
+
+ pthread_mutex_unlock(&THR_LOCK_mutex);
+ free(info);
+ mp->info= NULL; /* Get crash if double free */
+ }
+#else
+ thread_safe_sub(safe_mutex_count, 1, &THR_LOCK_mutex);
+#endif /* SAFE_MUTEX_DETECT_DESTROY */
return error;
}
+
+/*
+ Free global resources and check that all mutex has been destroyed
+
+ SYNOPSIS
+ safe_mutex_end()
+ file Print errors on this file
+
+ NOTES
+ We can't use DBUG_PRINT() here as we have in my_end() disabled
+ DBUG handling before calling this function.
+
+ In MySQL one may get one warning for a mutex created in my_thr_init.c
+ This is ok, as this thread may not yet have been exited.
+*/
+
+void safe_mutex_end(FILE *file __attribute__((unused)))
+{
+ if (!safe_mutex_count) /* safetly */
+ pthread_mutex_destroy(&THR_LOCK_mutex);
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+ if (!file)
+ return;
+
+ if (safe_mutex_count)
+ {
+ fprintf(file, "Warning: Not destroyed mutex: %lu\n", safe_mutex_count);
+ (void) fflush(file);
+ }
+ {
+ struct st_safe_mutex_info_t *ptr;
+ for (ptr= safe_mutex_root ; ptr ; ptr= ptr->next)
+ {
+ fprintf(file, "\tMutex initiated at line %4u in '%s'\n",
+ ptr->init_line, ptr->init_file);
+ (void) fflush(file);
+ }
+ }
+#endif /* SAFE_MUTEX_DETECT_DESTROY */
+}
+
#endif /* THREAD && SAFE_MUTEX */