xref: /reactos/sdk/lib/crt/stdlib/errno.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS system libraries
4  * FILE:        lib/sdk/crt/stdlib/errno.c
5  * PURPOSE:     Unknown
6  * PROGRAMER:   Unknown
7  *
8  */
9 #include <precomp.h>
10 #include "doserrmap.h"
11 #include <errno.h>
12 #include <internal/wine/msvcrt.h>
13 
14 static _invalid_parameter_handler invalid_parameter_handler = NULL;
15 
16 /*********************************************************************
17  *		_errno (MSVCRT.@)
18  */
19 int* CDECL _errno(void)
20 {
21     return &(msvcrt_get_thread_data()->thread_errno);
22 }
23 
24 /*********************************************************************
25  *		__doserrno (MSVCRT.@)
26  */
27 unsigned long* CDECL __doserrno(void)
28 {
29     return &(msvcrt_get_thread_data()->thread_doserrno);
30 }
31 
32 /*********************************************************************
33  *		_get_errno (MSVCRT.@)
34  */
35 errno_t CDECL _get_errno(int *pValue)
36 {
37     if (!pValue)
38         return EINVAL;
39 
40     *pValue = *_errno();
41     return 0;
42 }
43 
44 /*********************************************************************
45  *		_get_doserrno (MSVCRT.@)
46  */
47 errno_t CDECL _get_doserrno(unsigned long *pValue)
48 {
49     if (!pValue)
50         return EINVAL;
51 
52     *pValue = *__doserrno();
53     return 0;
54 }
55 
56 /*********************************************************************
57  *		_set_errno (MSVCRT.@)
58  */
59 errno_t CDECL _set_errno(int value)
60 {
61     *_errno() = value;
62     return 0;
63 }
64 
65 /*********************************************************************
66  *		_set_doserrno (MSVCRT.@)
67  */
68 errno_t CDECL _set_doserrno(unsigned long value)
69 {
70     *__doserrno() = value;
71     return 0;
72 }
73 
74 /*
75  * This function sets both doserrno to the passed in OS error code
76  * and also maps this to an appropriate errno code.  The mapping
77  * has been deduced automagically by running this functions, which
78  * exists in MSVCRT but is undocumented, on all the error codes in
79  * winerror.h.
80  */
81 void CDECL _dosmaperr(unsigned long oserror)
82 {
83 	int pos, base, lim;
84 
85 	_set_doserrno(oserror);
86 
87 	/* Use binary chop to find the corresponding errno code */
88 	for (base=0, lim=sizeof(doserrmap)/sizeof(doserrmap[0]); lim; lim >>= 1) {
89 		pos = base+(lim >> 1);
90 		if (doserrmap[pos].winerr == oserror) {
91 			_set_errno(doserrmap[pos].en);
92 			return;
93 		} else if (doserrmap[pos].winerr < oserror) {
94 			base = pos + 1;
95 			--lim;
96 		}
97 	}
98 	/* EINVAL appears to be the default */
99 	_set_errno(EINVAL);
100 }
101 
102 /******************************************************************************
103 *              _set_error_mode (MSVCRT.@)
104 *
105 * Set the error mode, which describes where the C run-time writes error
106 * messages.
107 *
108 * PARAMS
109 *   mode - the new error mode
110 *
111 * RETURNS
112 *   The old error mode.
113 *
114 */
115 int msvcrt_error_mode = MSVCRT__OUT_TO_DEFAULT;
116 
117 int CDECL _set_error_mode(int mode)
118 {
119     const int old = msvcrt_error_mode;
120     if ( MSVCRT__REPORT_ERRMODE != mode ) {
121         msvcrt_error_mode = mode;
122     }
123     return old;
124 }
125 
126 /******************************************************************************
127  *		_seterrormode (MSVCRT.@)
128  */
129 void CDECL _seterrormode(int mode)
130 {
131     SetErrorMode( mode );
132 }
133 
134 /******************************************************************************
135  *		_invalid_parameter (MSVCRT.@)
136  */
137 void __cdecl _invalid_parameter(const wchar_t *expr, const wchar_t *func,
138                                 const wchar_t *file, unsigned int line, uintptr_t arg)
139 {
140     if (invalid_parameter_handler) invalid_parameter_handler( expr, func, file, line, arg );
141     else
142     {
143         ERR( "%s:%u %s: %s %lx\n", debugstr_w(file), line, debugstr_w(func), debugstr_w(expr), arg );
144 #if _MSVCR_VER > 0 // FIXME: possible improvement: use a global variable in the DLL
145         RaiseException( STATUS_INVALID_CRUNTIME_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, NULL );
146 #endif
147     }
148 }
149 
150 /* _get_invalid_parameter_handler - not exported in native msvcrt, added in msvcr80 */
151 _invalid_parameter_handler CDECL _get_invalid_parameter_handler(void)
152 {
153     TRACE("\n");
154     return invalid_parameter_handler;
155 }
156 
157 /* _set_invalid_parameter_handler - not exproted in native msvcrt, added in msvcr80 */
158 _invalid_parameter_handler CDECL _set_invalid_parameter_handler(
159         _invalid_parameter_handler handler)
160 {
161     _invalid_parameter_handler old = invalid_parameter_handler;
162 
163     TRACE("(%p)\n", handler);
164 
165     invalid_parameter_handler = handler;
166     return old;
167 }
168