1 /* 2 * msvcrt.dll errno functions 3 * 4 * Copyright 2000 Jon Griffiths 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <precomp.h> 22 23 char __syserr00[] = "No Error"; 24 char __syserr01[] = "Operation not permitted (EPERM)"; 25 char __syserr02[] = "No such file or directory (ENOENT)"; 26 char __syserr03[] = "No such process (ESRCH)"; 27 char __syserr04[] = "Interrupted system call (EINTR)"; 28 char __syserr05[] = "Input or output error (EIO)"; 29 char __syserr06[] = "No such device or address (ENXIO)"; 30 char __syserr07[] = "Argument list too long (E2BIG)"; 31 char __syserr08[] = "Unable to execute file (ENOEXEC)"; 32 char __syserr09[] = "Bad file descriptor (EBADF)"; 33 char __syserr10[] = "No child processes (ECHILD)"; 34 char __syserr11[] = "Resource temporarily unavailable (EAGAIN)"; 35 char __syserr12[] = "Not enough memory (ENOMEM)"; 36 char __syserr13[] = "Permission denied (EACCES)"; 37 char __syserr14[] = "Bad address (EFAULT)"; 38 char __syserr15[] = "Unknown Error: 15"; 39 char __syserr16[] = "Resource busy (EBUSY)"; 40 char __syserr17[] = "File exists (EEXIST)"; 41 char __syserr18[] = "Improper link (EXDEV)"; 42 char __syserr19[] = "No such device (ENODEV)"; 43 char __syserr20[] = "Not a directory (ENOTDIR)"; 44 char __syserr21[] = "Is a directory (EISDIR)"; 45 char __syserr22[] = "Invalid argument (EINVAL)"; 46 char __syserr23[] = "Too many open files in system (ENFILE)"; 47 char __syserr24[] = "Too many open files (EMFILE)"; 48 char __syserr25[] = "Inappropriate I/O control operation (ENOTTY)"; 49 char __syserr26[] = "Unknown error: 26"; 50 char __syserr27[] = "File too large (EFBIG)"; 51 char __syserr28[] = "No space left on drive (ENOSPC)"; 52 char __syserr29[] = "Invalid seek (ESPIPE)"; 53 char __syserr30[] = "Read-only file system (EROFS)"; 54 char __syserr31[] = "Too many links (EMLINK)"; 55 char __syserr32[] = "Broken pipe (EPIPE)"; 56 char __syserr33[] = "Input to function out of range (EDOM)"; 57 char __syserr34[] = "Output of function out of range (ERANGE)"; 58 char __syserr35[] = "Unknown error: 35"; 59 char __syserr36[] = "Resource deadlock avoided (EDEADLK)"; 60 char __syserr37[] = "Unknown error: 37"; 61 char __syserr38[] = "File name too long (ENAMETOOLONG)"; 62 char __syserr39[] = "No locks available (ENOLCK)"; 63 char __syserr40[] = "Function not implemented (ENOSYS)"; 64 char __syserr41[] = "Directory not empty (ENOTEMPTY)"; 65 char __syserr42[] = "Illegal byte sequence (EILSEQ)"; 66 67 char *_sys_errlist[] = { 68 __syserr00, __syserr01, __syserr02, __syserr03, __syserr04, 69 __syserr05, __syserr06, __syserr07, __syserr08, __syserr09, 70 __syserr10, __syserr11, __syserr12, __syserr13, __syserr14, 71 __syserr15, __syserr16, __syserr17, __syserr18, __syserr19, 72 __syserr20, __syserr21, __syserr22, __syserr23, __syserr24, 73 __syserr25, __syserr26, __syserr27, __syserr28, __syserr29, 74 __syserr30, __syserr31, __syserr32, __syserr33, __syserr34, 75 __syserr35, __syserr36, __syserr37, __syserr38, __syserr39, 76 __syserr40, __syserr41, __syserr42 77 }; 78 79 int _sys_nerr = sizeof(_sys_errlist) / sizeof(_sys_errlist[0]) - 1; 80 81 /********************************************************************* 82 * strerror (MSVCRT.@) 83 */ 84 char* CDECL strerror(int err) 85 { 86 thread_data_t *data = msvcrt_get_thread_data(); 87 88 if (!data->strerror_buffer) 89 if (!(data->strerror_buffer = malloc(256))) return NULL; 90 91 if (err < 0 || err > _sys_nerr) err = _sys_nerr; 92 strcpy( data->strerror_buffer, _sys_errlist[err] ); 93 return data->strerror_buffer; 94 } 95 96 /********************************************************************** 97 * strerror_s (MSVCRT.@) 98 */ 99 int CDECL strerror_s(char *buffer, size_t numberOfElements, int errnum) 100 { 101 char *ptr; 102 103 if (!buffer || !numberOfElements) 104 { 105 *_errno() = EINVAL; 106 return EINVAL; 107 } 108 109 if (errnum < 0 || errnum > _sys_nerr) 110 errnum = _sys_nerr; 111 112 ptr = _sys_errlist[errnum]; 113 while (*ptr && numberOfElements > 1) 114 { 115 *buffer++ = *ptr++; 116 numberOfElements--; 117 } 118 119 *buffer = '\0'; 120 return 0; 121 } 122 123 /********************************************************************** 124 * _strerror (MSVCRT.@) 125 */ 126 char* CDECL _strerror(const char* str) 127 { 128 thread_data_t *data = msvcrt_get_thread_data(); 129 int err; 130 131 if (!data->strerror_buffer) 132 if (!(data->strerror_buffer = malloc(256))) return NULL; 133 134 err = data->thread_errno; 135 if (err < 0 || err > _sys_nerr) err = _sys_nerr; 136 137 if (str && *str) 138 sprintf( data->strerror_buffer, "%s: %s\n", str, _sys_errlist[err] ); 139 else 140 sprintf( data->strerror_buffer, "%s\n", _sys_errlist[err] ); 141 142 return data->strerror_buffer; 143 } 144 145 /********************************************************************* 146 * perror (MSVCRT.@) 147 */ 148 void CDECL perror(const char* str) 149 { 150 int err = *_errno(); 151 if (err < 0 || err > _sys_nerr) err = _sys_nerr; 152 153 if (str && *str) 154 { 155 _write( 2, str, strlen(str) ); 156 _write( 2, ": ", 2 ); 157 } 158 _write( 2, _sys_errlist[err], strlen(_sys_errlist[err]) ); 159 _write( 2, "\n", 1 ); 160 } 161 162 /********************************************************************* 163 * _wcserror_s (MSVCRT.@) 164 */ 165 int CDECL _wcserror_s(wchar_t* buffer, size_t nc, int err) 166 { 167 if (!MSVCRT_CHECK_PMT(buffer != NULL) || !MSVCRT_CHECK_PMT(nc > 0)) 168 { 169 _set_errno(EINVAL); 170 return EINVAL; 171 } 172 if (err < 0 || err > _sys_nerr) err = _sys_nerr; 173 MultiByteToWideChar(CP_ACP, 0, _sys_errlist[err], -1, buffer, nc); 174 return 0; 175 } 176 177 /********************************************************************* 178 * _wcserror (MSVCRT.@) 179 */ 180 wchar_t* CDECL _wcserror(int err) 181 { 182 thread_data_t *data = msvcrt_get_thread_data(); 183 184 if (!data->wcserror_buffer) 185 if (!(data->wcserror_buffer = malloc(256 * sizeof(wchar_t)))) return NULL; 186 _wcserror_s(data->wcserror_buffer, 256, err); 187 return data->wcserror_buffer; 188 } 189 190 /********************************************************************** 191 * __wcserror_s (MSVCRT.@) 192 */ 193 int CDECL __wcserror_s(wchar_t* buffer, size_t nc, const wchar_t* str) 194 { 195 int err; 196 static const WCHAR colonW[] = {':', ' ', '\0'}; 197 static const WCHAR nlW[] = {'\n', '\0'}; 198 size_t len; 199 200 err = *_errno(); 201 if (err < 0 || err > _sys_nerr) err = _sys_nerr; 202 203 len = MultiByteToWideChar(CP_ACP, 0, _sys_errlist[err], -1, NULL, 0) + 1 /* \n */; 204 if (str && *str) len += lstrlenW(str) + 2 /* ': ' */; 205 if (len > nc) 206 { 207 MSVCRT_INVALID_PMT("buffer[nc] is too small", ERANGE); 208 return ERANGE; 209 } 210 if (str && *str) 211 { 212 lstrcpyW(buffer, str); 213 lstrcatW(buffer, colonW); 214 } 215 else buffer[0] = '\0'; 216 len = lstrlenW(buffer); 217 MultiByteToWideChar(CP_ACP, 0, _sys_errlist[err], -1, buffer + len, 256 - len); 218 lstrcatW(buffer, nlW); 219 220 return 0; 221 } 222 223 /********************************************************************** 224 * __wcserror (MSVCRT.@) 225 */ 226 wchar_t* CDECL __wcserror(const wchar_t* str) 227 { 228 thread_data_t *data = msvcrt_get_thread_data(); 229 int err; 230 231 if (!data->wcserror_buffer) 232 if (!(data->wcserror_buffer = malloc(256 * sizeof(wchar_t)))) return NULL; 233 234 err = __wcserror_s(data->wcserror_buffer, 256, str); 235 if (err) FIXME("bad wcserror call (%d)\n", err); 236 237 return data->wcserror_buffer; 238 } 239