mirror of
git://source.winehq.org/git/wine.git
synced 2024-08-30 19:24:07 +00:00
Fixed per-thread data handling.
Made terminate and unexpected function pointer per-thread. Added set_se_translator.
This commit is contained in:
parent
8a191ff5b8
commit
44b4235af2
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "msvcrt.h"
|
||||
#include "msvcrt/eh.h"
|
||||
#include "msvcrt/malloc.h"
|
||||
#include "msvcrt/stdlib.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.@)
|
||||
*/
|
||||
terminate_function MSVCRT_set_terminate(terminate_function func)
|
||||
{
|
||||
terminate_function previous=func_terminate;
|
||||
TRACE("(%p) returning %p\n",func,previous);
|
||||
func_terminate=func;
|
||||
return previous;
|
||||
MSVCRT_thread_data *data = msvcrt_get_thread_data();
|
||||
terminate_function previous = data->terminate_handler;
|
||||
TRACE("(%p) returning %p\n",func,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 previous=func_unexpected;
|
||||
TRACE("(%p) returning %p\n",func,previous);
|
||||
func_unexpected=func;
|
||||
return previous;
|
||||
MSVCRT_thread_data *data = msvcrt_get_thread_data();
|
||||
unexpected_function previous = data->unexpected_handler;
|
||||
TRACE("(%p) returning %p\n",func,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.@)
|
||||
*/
|
||||
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.@)
|
||||
*/
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ int _chdrive(int newdrive)
|
|||
{
|
||||
MSVCRT__set_errno(GetLastError());
|
||||
if (newdrive <= 0)
|
||||
SET_THREAD_VAR(errno,MSVCRT_EACCES);
|
||||
*MSVCRT__errno() = MSVCRT_EACCES;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -185,7 +185,7 @@ int _findnext(long hand, struct _finddata_t * ft)
|
|||
|
||||
if (!FindNextFileA(hand, &find_data))
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_ENOENT);
|
||||
*MSVCRT__errno() = MSVCRT_ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ int _wfindnext(long hand, struct _wfinddata_t * ft)
|
|||
|
||||
if (!FindNextFileW(hand, &find_data))
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_ENOENT);
|
||||
*MSVCRT__errno() = MSVCRT_ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ char* _getcwd(char * buf, int size)
|
|||
}
|
||||
if (dir_len >= size)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
return NULL; /* buf too small */
|
||||
}
|
||||
strcpy(buf,dir);
|
||||
|
@ -255,7 +255,7 @@ WCHAR* _wgetcwd(WCHAR * buf, int size)
|
|||
}
|
||||
if (dir_len >= size)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
return NULL; /* buf too small */
|
||||
}
|
||||
strcpyW(buf,dir);
|
||||
|
@ -293,14 +293,14 @@ char* _getdcwd(int drive, char * buf, int size)
|
|||
drivespec[0] += drive - 1;
|
||||
if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_EACCES);
|
||||
*MSVCRT__errno() = MSVCRT_EACCES;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dir_len = GetFullPathNameA(drivespec,MAX_PATH,dir,&dummy);
|
||||
if (dir_len >= size || dir_len < 1)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
return NULL; /* buf too small */
|
||||
}
|
||||
|
||||
|
@ -333,14 +333,14 @@ WCHAR* _wgetdcwd(int drive, WCHAR * buf, int size)
|
|||
drivespec[0] += drive - 1;
|
||||
if (GetDriveTypeW(drivespec) < DRIVE_REMOVABLE)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_EACCES);
|
||||
*MSVCRT__errno() = MSVCRT_EACCES;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dir_len = GetFullPathNameW(drivespec,MAX_PATH,dir,&dummy);
|
||||
if (dir_len >= size || dir_len < 1)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
return NULL; /* buf too small */
|
||||
}
|
||||
|
||||
|
@ -629,7 +629,7 @@ char *_fullpath(char * absPath, const char* relPath, unsigned int size)
|
|||
|
||||
if (size < 4)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -818,4 +818,3 @@ void _searchenv(const char* file, const char* env, char *buf)
|
|||
penv = *end ? end + 1 : end;
|
||||
} while(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
|
|||
/* INTERNAL: Set the crt and dos errno's from the OS error given. */
|
||||
void MSVCRT__set_errno(int err)
|
||||
{
|
||||
int *errno = GET_THREAD_VAR_PTR(errno);
|
||||
unsigned long *doserrno = GET_THREAD_VAR_PTR(doserrno);
|
||||
int *errno = MSVCRT__errno();
|
||||
unsigned long *doserrno = __doserrno();
|
||||
|
||||
*doserrno = err;
|
||||
|
||||
|
@ -99,7 +99,7 @@ void MSVCRT__set_errno(int err)
|
|||
*/
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -133,5 +133,5 @@ char* _strerror(const char* err)
|
|||
*/
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -102,8 +102,8 @@ static HANDLE msvcrt_fdtoh(int fd)
|
|||
MSVCRT_handles[fd] == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WARN(":fd (%d) - no handle!\n",fd);
|
||||
SET_THREAD_VAR(doserrno,0);
|
||||
SET_THREAD_VAR(errno,MSVCRT_EBADF);
|
||||
*__doserrno() = 0;
|
||||
*MSVCRT__errno() = MSVCRT_EBADF;
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return MSVCRT_handles[fd];
|
||||
|
@ -160,8 +160,8 @@ static MSVCRT_FILE* msvcrt_alloc_fp(int fd)
|
|||
MSVCRT_handles[fd] == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WARN(":invalid fd %d\n",fd);
|
||||
SET_THREAD_VAR(doserrno,0);
|
||||
SET_THREAD_VAR(errno,MSVCRT_EBADF);
|
||||
*__doserrno() = 0;
|
||||
*MSVCRT__errno() = MSVCRT_EBADF;
|
||||
return NULL;
|
||||
}
|
||||
if (!MSVCRT_files[fd])
|
||||
|
@ -490,7 +490,7 @@ LONG _lseek(int fd, LONG offset, int whence)
|
|||
|
||||
if (whence < 0 || whence > 2)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_EINVAL);
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -538,7 +538,7 @@ int _locking(int fd, int mode, LONG nbytes)
|
|||
|
||||
if (mode < 0 || mode > 4)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_EINVAL);
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -553,7 +553,7 @@ int _locking(int fd, int mode, LONG nbytes)
|
|||
if ((cur_locn = SetFilePointer(hand, 0L, NULL, SEEK_CUR)) == 0xffffffff)
|
||||
{
|
||||
FIXME ("Seek failed\n");
|
||||
SET_THREAD_VAR(errno,MSVCRT_EINVAL); /* FIXME */
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL; /* FIXME */
|
||||
return -1;
|
||||
}
|
||||
if (mode == _LK_LOCK || mode == _LK_RLCK)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "ms_errno.h"
|
||||
|
||||
#include "msvcrt/malloc.h"
|
||||
#include "msvcrt/stdlib.h"
|
||||
#include "mtdll.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
@ -230,7 +231,7 @@ int _heapset(unsigned int value)
|
|||
int _heapadd(void* mem, MSVCRT_size_t size)
|
||||
{
|
||||
TRACE("(%p,%d) unsupported in Win32\n", mem,size);
|
||||
SET_THREAD_VAR(errno,MSVCRT_ENOSYS);
|
||||
*MSVCRT__errno() = MSVCRT_ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,18 +60,8 @@ BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
msvcrt_init_args();
|
||||
MSVCRT_setlocale(0, "C");
|
||||
TRACE("finished process init\n");
|
||||
/* FALL THROUGH for Initial TLS allocation!! */
|
||||
break;
|
||||
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;
|
||||
case DLL_PROCESS_DETACH:
|
||||
msvcrt_free_mt_locks();
|
||||
|
@ -85,13 +75,7 @@ BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
case DLL_THREAD_DETACH:
|
||||
/* Free TLS */
|
||||
tls = TlsGetValue(MSVCRT_tls_index);
|
||||
|
||||
if (!tls)
|
||||
{
|
||||
ERR("TLS free failed! error = %ld\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, tls);
|
||||
if (tls) HeapFree(GetProcessHeap(), 0, tls);
|
||||
TRACE("finished thread free\n");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL;
|
|||
double _CIacos(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ double _CIacos(void)
|
|||
double _CIasin(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ double _CIasin(void)
|
|||
double _CIatan(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return atan(x);
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ double _CIatan(void)
|
|||
double _CIatan2(void)
|
||||
{
|
||||
FPU_DOUBLES(x,y);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return atan2(x,y);
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ double _CIatan2(void)
|
|||
double _CIcos(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return cos(x);
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ double _CIcos(void)
|
|||
double _CIcosh(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return cosh(x);
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ double _CIcosh(void)
|
|||
double _CIexp(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return exp(x);
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ double _CIexp(void)
|
|||
double _CIfmod(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -209,8 +209,8 @@ double _CIfmod(void)
|
|||
double _CIlog(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (x == 0.0) SET_THREAD_VAR(errno,MSVCRT_ERANGE);
|
||||
if (x < 0.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
if (x == 0.0) *MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
return log(x);
|
||||
}
|
||||
|
||||
|
@ -220,8 +220,8 @@ double _CIlog(void)
|
|||
double _CIlog10(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (x == 0.0) SET_THREAD_VAR(errno,MSVCRT_ERANGE);
|
||||
if (x < 0.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
if (x == 0.0) *MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
return log10(x);
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ double _CIpow(void)
|
|||
FPU_DOUBLES(x,y);
|
||||
/* FIXME: If x < 0 and y is not integral, set EDOM */
|
||||
z = pow(x,y);
|
||||
if (!finite(z)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(z)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return z;
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ double _CIpow(void)
|
|||
double _CIsin(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return sin(x);
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ double _CIsin(void)
|
|||
double _CIsinh(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return sinh(x);
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ double _CIsinh(void)
|
|||
double _CIsqrt(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -274,7 +274,7 @@ double _CIsqrt(void)
|
|||
double _CItan(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return tan(x);
|
||||
}
|
||||
|
||||
|
@ -284,7 +284,7 @@ double _CItan(void)
|
|||
double _CItanh(void)
|
||||
{
|
||||
FPU_DOUBLE(x);
|
||||
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return tanh(x);
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ unsigned int _rotl(unsigned int num, int shift)
|
|||
*/
|
||||
double _logb(double num)
|
||||
{
|
||||
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return logb(num);
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ double _scalb(double num, long power)
|
|||
{
|
||||
/* Note - Can't forward directly as libc expects y as double */
|
||||
double dblpower = (double)power;
|
||||
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
return scalb(num, dblpower);
|
||||
}
|
||||
|
||||
|
@ -474,7 +474,7 @@ double MSVCRT_ldexp(double num, long exp)
|
|||
double z = ldexp(num,exp);
|
||||
|
||||
if (!finite(z))
|
||||
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
else if (z == 0 && signbit(z))
|
||||
z = 0.0; /* Convert -0 -> +0 */
|
||||
return z;
|
||||
|
@ -628,11 +628,11 @@ INT _isnan(double num)
|
|||
double _y0(double num)
|
||||
{
|
||||
double retval;
|
||||
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
retval = y0(num);
|
||||
if (_fpclass(retval) == _FPCLASS_NINF)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
*MSVCRT__errno() = MSVCRT_EDOM;
|
||||
retval = sqrt(-1);
|
||||
}
|
||||
return retval;
|
||||
|
@ -644,11 +644,11 @@ double _y0(double num)
|
|||
double _y1(double num)
|
||||
{
|
||||
double retval;
|
||||
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
retval = y1(num);
|
||||
if (_fpclass(retval) == _FPCLASS_NINF)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
*MSVCRT__errno() = MSVCRT_EDOM;
|
||||
retval = sqrt(-1);
|
||||
}
|
||||
return retval;
|
||||
|
@ -660,11 +660,11 @@ double _y1(double num)
|
|||
double _yn(int order, double num)
|
||||
{
|
||||
double retval;
|
||||
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM;
|
||||
retval = yn(order,num);
|
||||
if (_fpclass(retval) == _FPCLASS_NINF)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_EDOM);
|
||||
*MSVCRT__errno() = MSVCRT_EDOM;
|
||||
retval = sqrt(-1);
|
||||
}
|
||||
return retval;
|
||||
|
@ -676,7 +676,7 @@ double _yn(int order, double num)
|
|||
double _nextafter(double num, double next)
|
||||
{
|
||||
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);
|
||||
return retval;
|
||||
}
|
||||
|
@ -995,5 +995,3 @@ void _safe_fprem1(void)
|
|||
{
|
||||
TRACE("(): stub\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,23 +28,21 @@
|
|||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
|
||||
#include "msvcrt/eh.h"
|
||||
|
||||
/* TLS data */
|
||||
extern DWORD MSVCRT_tls_index;
|
||||
|
||||
typedef struct __MSVCRT_thread_data
|
||||
{
|
||||
int errno;
|
||||
unsigned long doserrno;
|
||||
int errno;
|
||||
unsigned long doserrno;
|
||||
terminate_function terminate_handler;
|
||||
unexpected_function unexpected_handler;
|
||||
_se_translator_function se_translator;
|
||||
} MSVCRT_thread_data;
|
||||
|
||||
#define GET_THREAD_DATA(x) \
|
||||
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 MSVCRT_thread_data *msvcrt_get_thread_data(void);
|
||||
|
||||
extern int MSVCRT_current_lc_all_cp;
|
||||
|
||||
|
@ -53,6 +51,8 @@ void MSVCRT__set_errno(int);
|
|||
char* msvcrt_strndup(const char*,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
|
||||
* it would not be much use anyway. Even for Winelib applications.
|
||||
*/
|
||||
|
|
|
@ -42,7 +42,7 @@ init MSVCRT_Init
|
|||
@ 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_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
|
||||
@ stdcall ?name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_name
|
||||
@ stdcall ?raw_name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_raw_name
|
||||
|
|
|
@ -53,7 +53,7 @@ static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env)
|
|||
|
||||
if ((unsigned)flags > _P_DETACH)
|
||||
{
|
||||
SET_THREAD_VAR(errno,MSVCRT_EINVAL);
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -203,8 +203,8 @@ int _cwait(int *status, int pid, int action)
|
|||
|
||||
if (doserrno == ERROR_INVALID_HANDLE)
|
||||
{
|
||||
SET_THREAD_VAR(errno, MSVCRT_ECHILD);
|
||||
SET_THREAD_VAR(doserrno,doserrno);
|
||||
*MSVCRT__errno() = MSVCRT_ECHILD;
|
||||
*__doserrno() = doserrno;
|
||||
}
|
||||
else
|
||||
MSVCRT__set_errno(doserrno);
|
||||
|
@ -456,4 +456,3 @@ int _unloaddll(int dll)
|
|||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,27 @@ typedef struct {
|
|||
void *arglist;
|
||||
} _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
|
||||
*/
|
||||
|
@ -114,4 +135,3 @@ void _endthreadex(
|
|||
/* FIXME */
|
||||
ExitThread(retval);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,15 +31,18 @@
|
|||
#define MSVCRT(x) x
|
||||
#endif
|
||||
|
||||
struct _EXCEPTION_POINTERS;
|
||||
|
||||
typedef void (*terminate_handler)();
|
||||
typedef void (*terminate_function)();
|
||||
typedef void (*unexpected_handler)();
|
||||
typedef void (*unexpected_function)();
|
||||
|
||||
typedef void (*_se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info);
|
||||
|
||||
terminate_function MSVCRT(set_terminate)(terminate_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(unexpected)();
|
||||
|
||||
|
|
Loading…
Reference in a new issue