Fixed per-thread data handling.

Made terminate and unexpected function pointer per-thread.
Added set_se_translator.
This commit is contained in:
Alexandre Julliard 2002-07-19 03:24:50 +00:00
parent 8a191ff5b8
commit 44b4235af2
12 changed files with 125 additions and 107 deletions

View file

@ -20,7 +20,7 @@
#include "msvcrt.h" #include "msvcrt.h"
#include "msvcrt/eh.h" #include "msvcrt/eh.h"
#include "msvcrt/malloc.h" #include "msvcrt/stdlib.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -177,18 +177,16 @@ const char * MSVCRT_what_exception(exception * _this)
} }
static terminate_function func_terminate=NULL;
static unexpected_function func_unexpected=NULL;
/****************************************************************** /******************************************************************
* ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
*/ */
terminate_function MSVCRT_set_terminate(terminate_function func) terminate_function MSVCRT_set_terminate(terminate_function func)
{ {
terminate_function previous=func_terminate; MSVCRT_thread_data *data = msvcrt_get_thread_data();
TRACE("(%p) returning %p\n",func,previous); terminate_function previous = data->terminate_handler;
func_terminate=func; TRACE("(%p) returning %p\n",func,previous);
return previous; data->terminate_handler = func;
return previous;
} }
/****************************************************************** /******************************************************************
@ -196,26 +194,43 @@ terminate_function MSVCRT_set_terminate(terminate_function func)
*/ */
unexpected_function MSVCRT_set_unexpected(unexpected_function func) unexpected_function MSVCRT_set_unexpected(unexpected_function func)
{ {
unexpected_function previous=func_unexpected; MSVCRT_thread_data *data = msvcrt_get_thread_data();
TRACE("(%p) returning %p\n",func,previous); unexpected_function previous = data->unexpected_handler;
func_unexpected=func; TRACE("(%p) returning %p\n",func,previous);
return previous; data->unexpected_handler = func;
return previous;
}
/******************************************************************
* ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@)
*/
_se_translator_function MSVCRT__set_se_translator(_se_translator_function func)
{
MSVCRT_thread_data *data = msvcrt_get_thread_data();
_se_translator_function previous = data->se_translator;
TRACE("(%p) returning %p\n",func,previous);
data->se_translator = func;
return previous;
} }
/****************************************************************** /******************************************************************
* ?terminate@@YAXXZ (MSVCRT.@) * ?terminate@@YAXXZ (MSVCRT.@)
*/ */
void MSVCRT_terminate() void MSVCRT_terminate(void)
{ {
(*func_terminate)(); MSVCRT_thread_data *data = msvcrt_get_thread_data();
if (data->terminate_handler) data->terminate_handler();
MSVCRT_abort();
} }
/****************************************************************** /******************************************************************
* ?unexpected@@YAXXZ (MSVCRT.@) * ?unexpected@@YAXXZ (MSVCRT.@)
*/ */
void MSVCRT_unexpected() void MSVCRT_unexpected(void)
{ {
(*func_unexpected)(); MSVCRT_thread_data *data = msvcrt_get_thread_data();
if (data->unexpected_handler) data->unexpected_handler();
MSVCRT_terminate();
} }
@ -523,4 +538,3 @@ void msvcrt_init_vtables(void)
type_info_vtable[0] = MSVCRT_type_info_dtor; type_info_vtable[0] = MSVCRT_type_info_dtor;
} }

View file

@ -118,7 +118,7 @@ int _chdrive(int newdrive)
{ {
MSVCRT__set_errno(GetLastError()); MSVCRT__set_errno(GetLastError());
if (newdrive <= 0) if (newdrive <= 0)
SET_THREAD_VAR(errno,MSVCRT_EACCES); *MSVCRT__errno() = MSVCRT_EACCES;
return -1; return -1;
} }
return 0; return 0;
@ -185,7 +185,7 @@ int _findnext(long hand, struct _finddata_t * ft)
if (!FindNextFileA(hand, &find_data)) if (!FindNextFileA(hand, &find_data))
{ {
SET_THREAD_VAR(errno,MSVCRT_ENOENT); *MSVCRT__errno() = MSVCRT_ENOENT;
return -1; return -1;
} }
@ -202,7 +202,7 @@ int _wfindnext(long hand, struct _wfinddata_t * ft)
if (!FindNextFileW(hand, &find_data)) if (!FindNextFileW(hand, &find_data))
{ {
SET_THREAD_VAR(errno,MSVCRT_ENOENT); *MSVCRT__errno() = MSVCRT_ENOENT;
return -1; return -1;
} }
@ -229,7 +229,7 @@ char* _getcwd(char * buf, int size)
} }
if (dir_len >= size) if (dir_len >= size)
{ {
SET_THREAD_VAR(errno,MSVCRT_ERANGE); *MSVCRT__errno() = MSVCRT_ERANGE;
return NULL; /* buf too small */ return NULL; /* buf too small */
} }
strcpy(buf,dir); strcpy(buf,dir);
@ -255,7 +255,7 @@ WCHAR* _wgetcwd(WCHAR * buf, int size)
} }
if (dir_len >= size) if (dir_len >= size)
{ {
SET_THREAD_VAR(errno,MSVCRT_ERANGE); *MSVCRT__errno() = MSVCRT_ERANGE;
return NULL; /* buf too small */ return NULL; /* buf too small */
} }
strcpyW(buf,dir); strcpyW(buf,dir);
@ -293,14 +293,14 @@ char* _getdcwd(int drive, char * buf, int size)
drivespec[0] += drive - 1; drivespec[0] += drive - 1;
if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE) if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
{ {
SET_THREAD_VAR(errno,MSVCRT_EACCES); *MSVCRT__errno() = MSVCRT_EACCES;
return NULL; return NULL;
} }
dir_len = GetFullPathNameA(drivespec,MAX_PATH,dir,&dummy); dir_len = GetFullPathNameA(drivespec,MAX_PATH,dir,&dummy);
if (dir_len >= size || dir_len < 1) if (dir_len >= size || dir_len < 1)
{ {
SET_THREAD_VAR(errno,MSVCRT_ERANGE); *MSVCRT__errno() = MSVCRT_ERANGE;
return NULL; /* buf too small */ return NULL; /* buf too small */
} }
@ -333,14 +333,14 @@ WCHAR* _wgetdcwd(int drive, WCHAR * buf, int size)
drivespec[0] += drive - 1; drivespec[0] += drive - 1;
if (GetDriveTypeW(drivespec) < DRIVE_REMOVABLE) if (GetDriveTypeW(drivespec) < DRIVE_REMOVABLE)
{ {
SET_THREAD_VAR(errno,MSVCRT_EACCES); *MSVCRT__errno() = MSVCRT_EACCES;
return NULL; return NULL;
} }
dir_len = GetFullPathNameW(drivespec,MAX_PATH,dir,&dummy); dir_len = GetFullPathNameW(drivespec,MAX_PATH,dir,&dummy);
if (dir_len >= size || dir_len < 1) if (dir_len >= size || dir_len < 1)
{ {
SET_THREAD_VAR(errno,MSVCRT_ERANGE); *MSVCRT__errno() = MSVCRT_ERANGE;
return NULL; /* buf too small */ return NULL; /* buf too small */
} }
@ -629,7 +629,7 @@ char *_fullpath(char * absPath, const char* relPath, unsigned int size)
if (size < 4) if (size < 4)
{ {
SET_THREAD_VAR(errno,MSVCRT_ERANGE); *MSVCRT__errno() = MSVCRT_ERANGE;
return NULL; return NULL;
} }
@ -818,4 +818,3 @@ void _searchenv(const char* file, const char* env, char *buf)
penv = *end ? end + 1 : end; penv = *end ? end + 1 : end;
} while(1); } while(1);
} }

View file

@ -37,8 +37,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* INTERNAL: Set the crt and dos errno's from the OS error given. */ /* INTERNAL: Set the crt and dos errno's from the OS error given. */
void MSVCRT__set_errno(int err) void MSVCRT__set_errno(int err)
{ {
int *errno = GET_THREAD_VAR_PTR(errno); int *errno = MSVCRT__errno();
unsigned long *doserrno = GET_THREAD_VAR_PTR(doserrno); unsigned long *doserrno = __doserrno();
*doserrno = err; *doserrno = err;
@ -99,7 +99,7 @@ void MSVCRT__set_errno(int err)
*/ */
int* MSVCRT__errno(void) int* MSVCRT__errno(void)
{ {
return GET_THREAD_VAR_PTR(errno); return &msvcrt_get_thread_data()->errno;
} }
/********************************************************************* /*********************************************************************
@ -107,7 +107,7 @@ int* MSVCRT__errno(void)
*/ */
unsigned long* __doserrno(void) unsigned long* __doserrno(void)
{ {
return GET_THREAD_VAR_PTR(doserrno); return &msvcrt_get_thread_data()->doserrno;
} }
/********************************************************************* /*********************************************************************
@ -124,7 +124,7 @@ char* MSVCRT_strerror(int err)
char* _strerror(const char* err) char* _strerror(const char* err)
{ {
static char strerrbuff[256]; /* FIXME: Per thread, nprintf */ static char strerrbuff[256]; /* FIXME: Per thread, nprintf */
sprintf(strerrbuff,"%s: %s\n",err,MSVCRT_strerror(GET_THREAD_VAR(errno))); sprintf(strerrbuff,"%s: %s\n",err,MSVCRT_strerror(msvcrt_get_thread_data()->errno));
return strerrbuff; return strerrbuff;
} }
@ -133,5 +133,5 @@ char* _strerror(const char* err)
*/ */
void MSVCRT_perror(const char* str) void MSVCRT_perror(const char* str)
{ {
_cprintf("%s: %s\n",str,MSVCRT_strerror(GET_THREAD_VAR(errno))); _cprintf("%s: %s\n",str,MSVCRT_strerror(msvcrt_get_thread_data()->errno));
} }

View file

@ -102,8 +102,8 @@ static HANDLE msvcrt_fdtoh(int fd)
MSVCRT_handles[fd] == INVALID_HANDLE_VALUE) MSVCRT_handles[fd] == INVALID_HANDLE_VALUE)
{ {
WARN(":fd (%d) - no handle!\n",fd); WARN(":fd (%d) - no handle!\n",fd);
SET_THREAD_VAR(doserrno,0); *__doserrno() = 0;
SET_THREAD_VAR(errno,MSVCRT_EBADF); *MSVCRT__errno() = MSVCRT_EBADF;
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
return MSVCRT_handles[fd]; return MSVCRT_handles[fd];
@ -160,8 +160,8 @@ static MSVCRT_FILE* msvcrt_alloc_fp(int fd)
MSVCRT_handles[fd] == INVALID_HANDLE_VALUE) MSVCRT_handles[fd] == INVALID_HANDLE_VALUE)
{ {
WARN(":invalid fd %d\n",fd); WARN(":invalid fd %d\n",fd);
SET_THREAD_VAR(doserrno,0); *__doserrno() = 0;
SET_THREAD_VAR(errno,MSVCRT_EBADF); *MSVCRT__errno() = MSVCRT_EBADF;
return NULL; return NULL;
} }
if (!MSVCRT_files[fd]) if (!MSVCRT_files[fd])
@ -490,7 +490,7 @@ LONG _lseek(int fd, LONG offset, int whence)
if (whence < 0 || whence > 2) if (whence < 0 || whence > 2)
{ {
SET_THREAD_VAR(errno,MSVCRT_EINVAL); *MSVCRT__errno() = MSVCRT_EINVAL;
return -1; return -1;
} }
@ -538,7 +538,7 @@ int _locking(int fd, int mode, LONG nbytes)
if (mode < 0 || mode > 4) if (mode < 0 || mode > 4)
{ {
SET_THREAD_VAR(errno,MSVCRT_EINVAL); *MSVCRT__errno() = MSVCRT_EINVAL;
return -1; return -1;
} }
@ -553,7 +553,7 @@ int _locking(int fd, int mode, LONG nbytes)
if ((cur_locn = SetFilePointer(hand, 0L, NULL, SEEK_CUR)) == 0xffffffff) if ((cur_locn = SetFilePointer(hand, 0L, NULL, SEEK_CUR)) == 0xffffffff)
{ {
FIXME ("Seek failed\n"); FIXME ("Seek failed\n");
SET_THREAD_VAR(errno,MSVCRT_EINVAL); /* FIXME */ *MSVCRT__errno() = MSVCRT_EINVAL; /* FIXME */
return -1; return -1;
} }
if (mode == _LK_LOCK || mode == _LK_RLCK) if (mode == _LK_LOCK || mode == _LK_RLCK)

View file

@ -25,6 +25,7 @@
#include "ms_errno.h" #include "ms_errno.h"
#include "msvcrt/malloc.h" #include "msvcrt/malloc.h"
#include "msvcrt/stdlib.h"
#include "mtdll.h" #include "mtdll.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -230,7 +231,7 @@ int _heapset(unsigned int value)
int _heapadd(void* mem, MSVCRT_size_t size) int _heapadd(void* mem, MSVCRT_size_t size)
{ {
TRACE("(%p,%d) unsupported in Win32\n", mem,size); TRACE("(%p,%d) unsupported in Win32\n", mem,size);
SET_THREAD_VAR(errno,MSVCRT_ENOSYS); *MSVCRT__errno() = MSVCRT_ENOSYS;
return -1; return -1;
} }

View file

@ -60,18 +60,8 @@ BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
msvcrt_init_args(); msvcrt_init_args();
MSVCRT_setlocale(0, "C"); MSVCRT_setlocale(0, "C");
TRACE("finished process init\n"); TRACE("finished process init\n");
/* FALL THROUGH for Initial TLS allocation!! */ break;
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
TRACE("starting thread init\n");
/* Create TLS */
tls = (MSVCRT_thread_data*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(MSVCRT_thread_data));
if (!tls || !TlsSetValue(MSVCRT_tls_index, tls))
{
ERR("TLS init failed! error = %ld\n", GetLastError());
return FALSE;
}
TRACE("finished thread init\n");
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
msvcrt_free_mt_locks(); msvcrt_free_mt_locks();
@ -85,13 +75,7 @@ BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
/* Free TLS */ /* Free TLS */
tls = TlsGetValue(MSVCRT_tls_index); tls = TlsGetValue(MSVCRT_tls_index);
if (tls) HeapFree(GetProcessHeap(), 0, tls);
if (!tls)
{
ERR("TLS free failed! error = %ld\n", GetLastError());
return FALSE;
}
HeapFree(GetProcessHeap(), 0, tls);
TRACE("finished thread free\n"); TRACE("finished thread free\n");
break; break;
} }

View file

@ -129,7 +129,7 @@ static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL;
double _CIacos(void) double _CIacos(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (x < -1.0 || x > 1.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (x < -1.0 || x > 1.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return acos(x); return acos(x);
} }
@ -139,7 +139,7 @@ double _CIacos(void)
double _CIasin(void) double _CIasin(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (x < -1.0 || x > 1.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (x < -1.0 || x > 1.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return asin(x); return asin(x);
} }
@ -149,7 +149,7 @@ double _CIasin(void)
double _CIatan(void) double _CIatan(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return atan(x); return atan(x);
} }
@ -159,7 +159,7 @@ double _CIatan(void)
double _CIatan2(void) double _CIatan2(void)
{ {
FPU_DOUBLES(x,y); FPU_DOUBLES(x,y);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return atan2(x,y); return atan2(x,y);
} }
@ -169,7 +169,7 @@ double _CIatan2(void)
double _CIcos(void) double _CIcos(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return cos(x); return cos(x);
} }
@ -179,7 +179,7 @@ double _CIcos(void)
double _CIcosh(void) double _CIcosh(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return cosh(x); return cosh(x);
} }
@ -189,7 +189,7 @@ double _CIcosh(void)
double _CIexp(void) double _CIexp(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return exp(x); return exp(x);
} }
@ -199,7 +199,7 @@ double _CIexp(void)
double _CIfmod(void) double _CIfmod(void)
{ {
FPU_DOUBLES(x,y); FPU_DOUBLES(x,y);
if (!finite(x) || !finite(y)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x) || !finite(y)) *MSVCRT__errno() = MSVCRT_EDOM;
return fmod(x,y); return fmod(x,y);
} }
@ -209,8 +209,8 @@ double _CIfmod(void)
double _CIlog(void) double _CIlog(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (x < 0.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
if (x == 0.0) SET_THREAD_VAR(errno,MSVCRT_ERANGE); if (x == 0.0) *MSVCRT__errno() = MSVCRT_ERANGE;
return log(x); return log(x);
} }
@ -220,8 +220,8 @@ double _CIlog(void)
double _CIlog10(void) double _CIlog10(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (x < 0.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
if (x == 0.0) SET_THREAD_VAR(errno,MSVCRT_ERANGE); if (x == 0.0) *MSVCRT__errno() = MSVCRT_ERANGE;
return log10(x); return log10(x);
} }
@ -234,7 +234,7 @@ double _CIpow(void)
FPU_DOUBLES(x,y); FPU_DOUBLES(x,y);
/* FIXME: If x < 0 and y is not integral, set EDOM */ /* FIXME: If x < 0 and y is not integral, set EDOM */
z = pow(x,y); z = pow(x,y);
if (!finite(z)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(z)) *MSVCRT__errno() = MSVCRT_EDOM;
return z; return z;
} }
@ -244,7 +244,7 @@ double _CIpow(void)
double _CIsin(void) double _CIsin(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return sin(x); return sin(x);
} }
@ -254,7 +254,7 @@ double _CIsin(void)
double _CIsinh(void) double _CIsinh(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return sinh(x); return sinh(x);
} }
@ -264,7 +264,7 @@ double _CIsinh(void)
double _CIsqrt(void) double _CIsqrt(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (x < 0.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return sqrt(x); return sqrt(x);
} }
@ -274,7 +274,7 @@ double _CIsqrt(void)
double _CItan(void) double _CItan(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return tan(x); return tan(x);
} }
@ -284,7 +284,7 @@ double _CItan(void)
double _CItanh(void) double _CItanh(void)
{ {
FPU_DOUBLE(x); FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
return tanh(x); return tanh(x);
} }
@ -363,7 +363,7 @@ unsigned int _rotl(unsigned int num, int shift)
*/ */
double _logb(double num) double _logb(double num)
{ {
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
return logb(num); return logb(num);
} }
@ -401,7 +401,7 @@ double _scalb(double num, long power)
{ {
/* Note - Can't forward directly as libc expects y as double */ /* Note - Can't forward directly as libc expects y as double */
double dblpower = (double)power; double dblpower = (double)power;
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
return scalb(num, dblpower); return scalb(num, dblpower);
} }
@ -474,7 +474,7 @@ double MSVCRT_ldexp(double num, long exp)
double z = ldexp(num,exp); double z = ldexp(num,exp);
if (!finite(z)) if (!finite(z))
SET_THREAD_VAR(errno,MSVCRT_ERANGE); *MSVCRT__errno() = MSVCRT_ERANGE;
else if (z == 0 && signbit(z)) else if (z == 0 && signbit(z))
z = 0.0; /* Convert -0 -> +0 */ z = 0.0; /* Convert -0 -> +0 */
return z; return z;
@ -628,11 +628,11 @@ INT _isnan(double num)
double _y0(double num) double _y0(double num)
{ {
double retval; double retval;
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
retval = y0(num); retval = y0(num);
if (_fpclass(retval) == _FPCLASS_NINF) if (_fpclass(retval) == _FPCLASS_NINF)
{ {
SET_THREAD_VAR(errno,MSVCRT_EDOM); *MSVCRT__errno() = MSVCRT_EDOM;
retval = sqrt(-1); retval = sqrt(-1);
} }
return retval; return retval;
@ -644,11 +644,11 @@ double _y0(double num)
double _y1(double num) double _y1(double num)
{ {
double retval; double retval;
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
retval = y1(num); retval = y1(num);
if (_fpclass(retval) == _FPCLASS_NINF) if (_fpclass(retval) == _FPCLASS_NINF)
{ {
SET_THREAD_VAR(errno,MSVCRT_EDOM); *MSVCRT__errno() = MSVCRT_EDOM;
retval = sqrt(-1); retval = sqrt(-1);
} }
return retval; return retval;
@ -660,11 +660,11 @@ double _y1(double num)
double _yn(int order, double num) double _yn(int order, double num)
{ {
double retval; double retval;
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
retval = yn(order,num); retval = yn(order,num);
if (_fpclass(retval) == _FPCLASS_NINF) if (_fpclass(retval) == _FPCLASS_NINF)
{ {
SET_THREAD_VAR(errno,MSVCRT_EDOM); *MSVCRT__errno() = MSVCRT_EDOM;
retval = sqrt(-1); retval = sqrt(-1);
} }
return retval; return retval;
@ -676,7 +676,7 @@ double _yn(int order, double num)
double _nextafter(double num, double next) double _nextafter(double num, double next)
{ {
double retval; double retval;
if (!finite(num) || !finite(next)) SET_THREAD_VAR(errno,MSVCRT_EDOM); if (!finite(num) || !finite(next)) *MSVCRT__errno() = MSVCRT_EDOM;
retval = nextafter(num,next); retval = nextafter(num,next);
return retval; return retval;
} }
@ -995,5 +995,3 @@ void _safe_fprem1(void)
{ {
TRACE("(): stub\n"); TRACE("(): stub\n");
} }

View file

@ -28,23 +28,21 @@
#include "winerror.h" #include "winerror.h"
#include "winnls.h" #include "winnls.h"
#include "msvcrt/eh.h"
/* TLS data */ /* TLS data */
extern DWORD MSVCRT_tls_index; extern DWORD MSVCRT_tls_index;
typedef struct __MSVCRT_thread_data typedef struct __MSVCRT_thread_data
{ {
int errno; int errno;
unsigned long doserrno; unsigned long doserrno;
terminate_function terminate_handler;
unexpected_function unexpected_handler;
_se_translator_function se_translator;
} MSVCRT_thread_data; } MSVCRT_thread_data;
#define GET_THREAD_DATA(x) \ extern MSVCRT_thread_data *msvcrt_get_thread_data(void);
x = TlsGetValue(MSVCRT_tls_index)
#define GET_THREAD_VAR(x) \
((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x
#define GET_THREAD_VAR_PTR(x) \
(&((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x)
#define SET_THREAD_VAR(x,y) \
((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x = y
extern int MSVCRT_current_lc_all_cp; extern int MSVCRT_current_lc_all_cp;
@ -53,6 +51,8 @@ void MSVCRT__set_errno(int);
char* msvcrt_strndup(const char*,unsigned int); char* msvcrt_strndup(const char*,unsigned int);
LPWSTR msvcrt_wstrndup(LPCWSTR, unsigned int); LPWSTR msvcrt_wstrndup(LPCWSTR, unsigned int);
void MSVCRT__amsg_exit(int errnum);
/* FIXME: This should be declared in new.h but it's not an extern "C" so /* FIXME: This should be declared in new.h but it's not an extern "C" so
* it would not be much use anyway. Even for Winelib applications. * it would not be much use anyway. Even for Winelib applications.
*/ */

View file

@ -42,7 +42,7 @@ init MSVCRT_Init
@ cdecl ?_query_new_mode@@YAHXZ() MSVCRT__query_new_mode @ cdecl ?_query_new_mode@@YAHXZ() MSVCRT__query_new_mode
@ cdecl ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z(ptr) MSVCRT__set_new_handler @ cdecl ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z(ptr) MSVCRT__set_new_handler
@ cdecl ?_set_new_mode@@YAHH@Z(long) MSVCRT__set_new_mode @ cdecl ?_set_new_mode@@YAHH@Z(long) MSVCRT__set_new_mode
@ stub ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z @ cdecl ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) MSVCRT__set_se_translator
@ stub ?before@type_info@@QBEHABV1@@Z #(ptr ptr) stdcall @ stub ?before@type_info@@QBEHABV1@@Z #(ptr ptr) stdcall
@ stdcall ?name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_name @ stdcall ?name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_name
@ stdcall ?raw_name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_raw_name @ stdcall ?raw_name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_raw_name

View file

@ -53,7 +53,7 @@ static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env)
if ((unsigned)flags > _P_DETACH) if ((unsigned)flags > _P_DETACH)
{ {
SET_THREAD_VAR(errno,MSVCRT_EINVAL); *MSVCRT__errno() = MSVCRT_EINVAL;
return -1; return -1;
} }
@ -203,8 +203,8 @@ int _cwait(int *status, int pid, int action)
if (doserrno == ERROR_INVALID_HANDLE) if (doserrno == ERROR_INVALID_HANDLE)
{ {
SET_THREAD_VAR(errno, MSVCRT_ECHILD); *MSVCRT__errno() = MSVCRT_ECHILD;
SET_THREAD_VAR(doserrno,doserrno); *__doserrno() = doserrno;
} }
else else
MSVCRT__set_errno(doserrno); MSVCRT__set_errno(doserrno);
@ -456,4 +456,3 @@ int _unloaddll(int dll)
return err; return err;
} }
} }

View file

@ -33,6 +33,27 @@ typedef struct {
void *arglist; void *arglist;
} _beginthread_trampoline_t; } _beginthread_trampoline_t;
/*********************************************************************
* msvcrt_get_thread_data
*
* Return the thread local storage structure.
*/
MSVCRT_thread_data *msvcrt_get_thread_data(void)
{
MSVCRT_thread_data *ptr;
DWORD err = GetLastError(); /* need to preserve last error */
if (!(ptr = TlsGetValue( MSVCRT_tls_index )))
{
if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) )))
MSVCRT__amsg_exit(16);
if (!TlsSetValue( MSVCRT_tls_index, ptr )) MSVCRT__amsg_exit(16);
}
SetLastError( err );
return ptr;
}
/********************************************************************* /*********************************************************************
* _beginthread_trampoline * _beginthread_trampoline
*/ */
@ -114,4 +135,3 @@ void _endthreadex(
/* FIXME */ /* FIXME */
ExitThread(retval); ExitThread(retval);
} }

View file

@ -31,15 +31,18 @@
#define MSVCRT(x) x #define MSVCRT(x) x
#endif #endif
struct _EXCEPTION_POINTERS;
typedef void (*terminate_handler)(); typedef void (*terminate_handler)();
typedef void (*terminate_function)(); typedef void (*terminate_function)();
typedef void (*unexpected_handler)(); typedef void (*unexpected_handler)();
typedef void (*unexpected_function)(); typedef void (*unexpected_function)();
typedef void (*_se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info);
terminate_function MSVCRT(set_terminate)(terminate_function func); terminate_function MSVCRT(set_terminate)(terminate_function func);
unexpected_function MSVCRT(set_unexpected)(unexpected_function func); unexpected_function MSVCRT(set_unexpected)(unexpected_function func);
_se_translator_function MSVCRT(_set_se_translator)(_se_translator_function func);
void MSVCRT(terminate)(); void MSVCRT(terminate)();
void MSVCRT(unexpected)(); void MSVCRT(unexpected)();