diff options
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/Makefile.am | 28 | ||||
-rw-r--r-- | mysys/charset.c | 4 | ||||
-rw-r--r-- | mysys/default.c | 4 | ||||
-rw-r--r-- | mysys/mf_iocache.c | 66 | ||||
-rw-r--r-- | mysys/mf_tempfile.c | 6 | ||||
-rw-r--r-- | mysys/my_clock.c | 4 | ||||
-rw-r--r-- | mysys/my_copy.c | 2 | ||||
-rw-r--r-- | mysys/my_getopt.c | 6 | ||||
-rw-r--r-- | mysys/my_getwd.c | 2 | ||||
-rw-r--r-- | mysys/my_init.c | 107 | ||||
-rw-r--r-- | mysys/my_lock.c | 54 | ||||
-rw-r--r-- | mysys/my_messnc.c | 4 | ||||
-rw-r--r-- | mysys/my_netware.c | 150 | ||||
-rw-r--r-- | mysys/my_os2cond.c | 1 | ||||
-rw-r--r-- | mysys/my_os2dirsrch.c | 192 | ||||
-rw-r--r-- | mysys/my_os2dirsrch.h | 57 | ||||
-rw-r--r-- | mysys/my_os2file64.c | 389 | ||||
-rw-r--r-- | mysys/my_os2mutex.c | 53 | ||||
-rw-r--r-- | mysys/my_os2thread.c | 3 | ||||
-rw-r--r-- | mysys/my_os2tls.c | 201 | ||||
-rw-r--r-- | mysys/my_pthread.c | 13 | ||||
-rw-r--r-- | mysys/my_redel.c | 2 | ||||
-rw-r--r-- | mysys/my_sleep.c (renamed from mysys/mf_sleep.c) | 29 | ||||
-rw-r--r-- | mysys/my_tempnam.c | 10 | ||||
-rw-r--r-- | mysys/my_thr_init.c | 12 | ||||
-rw-r--r-- | mysys/mysys_priv.h | 6 | ||||
-rw-r--r-- | mysys/safemalloc.c | 56 | ||||
-rw-r--r-- | mysys/thr_alarm.c | 19 | ||||
-rw-r--r-- | mysys/thr_mutex.c | 119 |
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 */ |