1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1999,2008 Oracle. All rights reserved. 5 * 6 * $Id: os_errno.c,v 12.15 2008/01/08 20:58:46 bostic Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12 13/* 14 * __os_get_errno_ret_zero -- 15 * Return the last system error, including an error of zero. 16 */ 17int 18__os_get_errno_ret_zero() 19{ 20 /* This routine must be able to return the same value repeatedly. */ 21 return (errno); 22} 23 24/* 25 * We've seen cases where system calls failed but errno was never set. For 26 * that reason, __os_get_errno() and __os_get_syserr set errno to EAGAIN if 27 * it's not already set, to work around the problem. For obvious reasons, 28 * we can only call this function if we know an error has occurred, that 29 * is, we can't test the return for a non-zero value after the get call. 30 * 31 * __os_get_errno -- 32 * Return the last ANSI C "errno" value or EAGAIN if the last error 33 * is zero. 34 */ 35int 36__os_get_errno() 37{ 38 /* This routine must be able to return the same value repeatedly. */ 39 if (errno == 0) 40 __os_set_errno(EAGAIN); 41 return (errno); 42} 43 44#ifdef HAVE_REPLICATION_THREADS 45/* 46 * __os_get_neterr -- 47 * Return the last networking error or EAGAIN if the last error is zero. 48 * 49 * PUBLIC: #ifdef HAVE_REPLICATION_THREADS 50 * PUBLIC: int __os_get_neterr __P((void)); 51 * PUBLIC: #endif 52 */ 53int 54__os_get_neterr() 55{ 56 int err; 57 58 /* This routine must be able to return the same value repeatedly. */ 59 err = WSAGetLastError(); 60 if (err == 0) 61 WSASetLastError(err = ERROR_RETRY); 62 return (err); 63} 64#endif 65 66/* 67 * __os_get_syserr -- 68 * Return the last system error or EAGAIN if the last error is zero. 69 */ 70int 71__os_get_syserr() 72{ 73 int err; 74 75 /* This routine must be able to return the same value repeatedly. */ 76 err = GetLastError(); 77 if (err == 0) 78 SetLastError(err = ERROR_RETRY); 79 return (err); 80} 81 82/* 83 * __os_set_errno -- 84 * Set the value of errno. 85 */ 86void 87__os_set_errno(evalue) 88 int evalue; 89{ 90 /* 91 * This routine is called by the compatibility interfaces (DB 1.85, 92 * dbm and hsearch). Force values > 0, that is, not one of DB 2.X 93 * and later's public error returns. If something bad has happened, 94 * default to EFAULT -- a nasty return. Otherwise, default to EINVAL. 95 * As the compatibility APIs aren't included on Windows, the Windows 96 * version of this routine doesn't need this behavior. 97 */ 98 errno = 99 evalue >= 0 ? evalue : (evalue == DB_RUNRECOVERY ? EFAULT : EINVAL); 100} 101 102/* 103 * __os_strerror -- 104 * Return a string associated with the system error. 105 */ 106char * 107__os_strerror(error, buf, len) 108 int error; 109 char *buf; 110 size_t len; 111{ 112#ifdef DB_WINCE 113#define MAX_TMPBUF_LEN 512 114 _TCHAR tbuf[MAX_TMPBUF_LEN]; 115 size_t maxlen; 116 117 DB_ASSERT(NULL, error != 0); 118 119 memset(tbuf, 0, sizeof(_TCHAR)*MAX_TMPBUF_LEN); 120 maxlen = (len > MAX_TMPBUF_LEN ? MAX_TMPBUF_LEN : len); 121 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, (DWORD)error, 122 0, tbuf, maxlen-1, NULL); 123 124 if (WideCharToMultiByte(CP_UTF8, 0, tbuf, -1, 125 buf, len, 0, NULL) == 0) 126 strncpy(buf, "Error message translation failed.", len); 127#else 128 DB_ASSERT(NULL, error != 0); 129 /* 130 * Explicitly call FormatMessageA, since we want to receive a char 131 * string back, not a tchar string. 132 */ 133 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 134 0, (DWORD)error, 0, buf, (DWORD)(len - 1), NULL); 135 buf[len - 1] = '\0'; 136#endif 137 138 return (buf); 139} 140 141/* 142 * __os_posix_err -- 143 * Convert a system error to a POSIX error. 144 */ 145int 146__os_posix_err(error) 147 int error; 148{ 149 /* Handle calls on successful returns. */ 150 if (error == 0) 151 return (0); 152 153 /* 154 * Translate the Windows error codes we care about. 155 */ 156 switch (error) { 157 case ERROR_INVALID_PARAMETER: 158 return (EINVAL); 159 160 case ERROR_FILE_NOT_FOUND: 161 case ERROR_INVALID_DRIVE: 162 case ERROR_PATH_NOT_FOUND: 163 return (ENOENT); 164 165 case ERROR_NO_MORE_FILES: 166 case ERROR_TOO_MANY_OPEN_FILES: 167 return (EMFILE); 168 169 case ERROR_ACCESS_DENIED: 170 return (EPERM); 171 172 case ERROR_INVALID_HANDLE: 173 return (EBADF); 174 175 case ERROR_NOT_ENOUGH_MEMORY: 176 return (ENOMEM); 177 178 case ERROR_DISK_FULL: 179 return (ENOSPC); 180 181 case ERROR_ARENA_TRASHED: 182 case ERROR_BAD_COMMAND: 183 case ERROR_BAD_ENVIRONMENT: 184 case ERROR_BAD_FORMAT: 185 case ERROR_GEN_FAILURE: 186 case ERROR_INVALID_ACCESS: 187 case ERROR_INVALID_BLOCK: 188 case ERROR_INVALID_DATA: 189 case ERROR_READ_FAULT: 190 case ERROR_WRITE_FAULT: 191 return (EFAULT); 192 193 case ERROR_ALREADY_EXISTS: 194 case ERROR_FILE_EXISTS: 195 return (EEXIST); 196 197 case ERROR_NOT_SAME_DEVICE: 198 return (EXDEV); 199 200 case ERROR_WRITE_PROTECT: 201 return (EACCES); 202 203 case ERROR_LOCK_FAILED: 204 case ERROR_LOCK_VIOLATION: 205 case ERROR_NOT_READY: 206 case ERROR_SHARING_VIOLATION: 207 return (EBUSY); 208 209 case ERROR_RETRY: 210 return (EINTR); 211 } 212 213 /* 214 * Translate the Windows socket error codes. 215 */ 216 switch (error) { 217 case WSAEADDRINUSE: 218#ifdef EADDRINUSE 219 return (EADDRINUSE); 220#else 221 break; 222#endif 223 case WSAEADDRNOTAVAIL: 224#ifdef EADDRNOTAVAIL 225 return (EADDRNOTAVAIL); 226#else 227 break; 228#endif 229 case WSAEAFNOSUPPORT: 230#ifdef EAFNOSUPPORT 231 return (EAFNOSUPPORT); 232#else 233 break; 234#endif 235 case WSAEALREADY: 236#ifdef EALREADY 237 return (EALREADY); 238#else 239 break; 240#endif 241 case WSAEBADF: 242 return (EBADF); 243 case WSAECONNABORTED: 244#ifdef ECONNABORTED 245 return (ECONNABORTED); 246#else 247 break; 248#endif 249 case WSAECONNREFUSED: 250#ifdef ECONNREFUSED 251 return (ECONNREFUSED); 252#else 253 break; 254#endif 255 case WSAECONNRESET: 256#ifdef ECONNRESET 257 return (ECONNRESET); 258#else 259 break; 260#endif 261 case WSAEDESTADDRREQ: 262#ifdef EDESTADDRREQ 263 return (EDESTADDRREQ); 264#else 265 break; 266#endif 267 case WSAEFAULT: 268 return (EFAULT); 269 case WSAEHOSTDOWN: 270#ifdef EHOSTDOWN 271 return (EHOSTDOWN); 272#else 273 break; 274#endif 275 case WSAEHOSTUNREACH: 276#ifdef EHOSTUNREACH 277 return (EHOSTUNREACH); 278#else 279 break; 280#endif 281 case WSAEINPROGRESS: 282#ifdef EINPROGRESS 283 return (EINPROGRESS); 284#else 285 break; 286#endif 287 case WSAEINTR: 288 return (EINTR); 289 case WSAEINVAL: 290 return (EINVAL); 291 case WSAEISCONN: 292#ifdef EISCONN 293 return (EISCONN); 294#else 295 break; 296#endif 297 case WSAELOOP: 298#ifdef ELOOP 299 return (ELOOP); 300#else 301 break; 302#endif 303 case WSAEMFILE: 304 return (EMFILE); 305 case WSAEMSGSIZE: 306#ifdef EMSGSIZE 307 return (EMSGSIZE); 308#else 309 break; 310#endif 311 case WSAENAMETOOLONG: 312 return (ENAMETOOLONG); 313 case WSAENETDOWN: 314#ifdef ENETDOWN 315 return (ENETDOWN); 316#else 317 break; 318#endif 319 case WSAENETRESET: 320#ifdef ENETRESET 321 return (ENETRESET); 322#else 323 break; 324#endif 325 case WSAENETUNREACH: 326#ifdef ENETUNREACH 327 return (ENETUNREACH); 328#else 329 break; 330#endif 331 case WSAENOBUFS: 332#ifdef ENOBUFS 333 return (ENOBUFS); 334#else 335 break; 336#endif 337 case WSAENOPROTOOPT: 338#ifdef ENOPROTOOPT 339 return (ENOPROTOOPT); 340#else 341 break; 342#endif 343 case WSAENOTCONN: 344#ifdef ENOTCONN 345 return (ENOTCONN); 346#else 347 break; 348#endif 349 case WSANOTINITIALISED: 350 return (EAGAIN); 351 case WSAENOTSOCK: 352#ifdef ENOTSOCK 353 return (ENOTSOCK); 354#else 355 break; 356#endif 357 case WSAEOPNOTSUPP: 358 return (DB_OPNOTSUP); 359 case WSAEPFNOSUPPORT: 360#ifdef EPFNOSUPPORT 361 return (EPFNOSUPPORT); 362#else 363 break; 364#endif 365 case WSAEPROTONOSUPPORT: 366#ifdef EPROTONOSUPPORT 367 return (EPROTONOSUPPORT); 368#else 369 break; 370#endif 371 case WSAEPROTOTYPE: 372#ifdef EPROTOTYPE 373 return (EPROTOTYPE); 374#else 375 break; 376#endif 377 case WSAESHUTDOWN: 378#ifdef ESHUTDOWN 379 return (ESHUTDOWN); 380#else 381 break; 382#endif 383 case WSAESOCKTNOSUPPORT: 384#ifdef ESOCKTNOSUPPORT 385 return (ESOCKTNOSUPPORT); 386#else 387 break; 388#endif 389 case WSAETIMEDOUT: 390#ifdef ETIMEDOUT 391 return (ETIMEDOUT); 392#else 393 break; 394#endif 395 case WSAETOOMANYREFS: 396#ifdef ETOOMANYREFS 397 return (ETOOMANYREFS); 398#else 399 break; 400#endif 401 case WSAEWOULDBLOCK: 402#ifdef EWOULDBLOCK 403 return (EWOULDBLOCK); 404#else 405 return (EAGAIN); 406#endif 407 case WSAHOST_NOT_FOUND: 408#ifdef EHOSTUNREACH 409 return (EHOSTUNREACH); 410#else 411 break; 412#endif 413 case WSASYSNOTREADY: 414 return (EAGAIN); 415 case WSATRY_AGAIN: 416 return (EAGAIN); 417 case WSAVERNOTSUPPORTED: 418 return (DB_OPNOTSUP); 419 case WSAEACCES: 420 return (EACCES); 421 } 422 423 /* 424 * EFAULT is the default if we don't have a translation. 425 */ 426 return (EFAULT); 427} 428