0,0 → 1,344 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Implementation of strerror() function. |
* |
****************************************************************************/ |
|
|
#include "variety.h" |
#include "widechar.h" |
#include <string.h> |
#include <errno.h> |
#include "rtdata.h" |
#if defined(__NT__) |
#include <windows.h> |
#endif |
#include "errstr.h" |
|
|
#ifndef __WIDECHAR__ |
|
#ifdef __LINUX__ |
char *_sys_errlist[] = { |
/* 0 EOK */ "No error", |
/* 1 EPERM */ "Operation not permitted", |
/* 2 ENOENT */ "No such file or directory", |
/* 3 ESRCH */ "No such process", |
/* 4 EINTR */ "Interrupted system call", |
/* 5 EIO */ "I/O error", |
/* 6 ENXIO */ "No such device or address", |
/* 7 E2BIG */ "Arg list too long", |
/* 8 ENOEXEC */ "Exec format error", |
/* 9 EBADF */ "Bad file number", |
/* 10 ECHILD */ "No child processes", |
/* 11 EAGAIN */ "Try again", |
/* 12 ENOMEM */ "Out of memory", |
/* 13 EACCES */ "Permission denied", |
/* 14 EFAULT */ "Bad address", |
/* 15 ENOTBLK */ "Block device required", |
/* 16 EBUSY */ "Device or resource busy", |
/* 17 EEXIST */ "File exists", |
/* 18 EXDEV */ "Cross-device link", |
/* 19 ENODEV */ "No such device", |
/* 20 ENOTDIR */ "Not a directory", |
/* 21 EISDIR */ "Is a directory", |
/* 22 EINVAL */ "Invalid argument", |
/* 23 ENFILE */ "File table overflow", |
/* 24 EMFILE */ "Too many open files", |
/* 25 ENOTTY */ "Not a typewriter", |
/* 26 ETXTBSY */ "Text file busy", |
/* 27 EFBIG */ "File too large", |
/* 28 ENOSPC */ "No space left on device", |
/* 29 ESPIPE */ "Illegal seek", |
/* 30 EROFS */ "Read-only file system", |
/* 31 EMLINK */ "Too many links", |
/* 32 EPIPE */ "Broken pipe", |
/* 33 EDOM */ "Math argument out of domain of func", |
/* 34 ERANGE */ "Math result not representable", |
/* 35 EDEADLK */ "Resource deadlock would occur", |
/* 36 ENAMETOOLONG */ "File name too long", |
/* 37 ENOLCK */ "No record locks available", |
/* 38 ENOSYS */ "Function not implemented", |
/* 39 ENOTEMPTY */ "Directory not empty", |
/* 40 ELOOP */ "Too many symbolic links encountered", |
/* 41 */ "", |
/* 42 ENOMSG */ "No message of desired type", |
/* 43 EIDRM */ "Identifier removed", |
/* 44 ECHRNG */ "Channel number out of range", |
/* 45 EL2NSYNC */ "Level 2 not synchronized", |
/* 46 EL3HLT */ "Level 3 halted", |
/* 47 EL3RST */ "Level 3 reset", |
/* 48 ELNRNG */ "Link number out of range", |
/* 49 EUNATCH */ "Protocol driver not attached", |
/* 50 ENOCSI */ "No CSI structure available", |
/* 51 EL2HLT */ "Level 2 halted", |
/* 52 EBADE */ "Invalid exchange", |
/* 53 EBADR */ "Invalid request descriptor", |
/* 54 EXFULL */ "Exchange full", |
/* 55 ENOANO */ "No anode", |
/* 56 EBADRQC */ "Invalid request code", |
/* 57 EBADSLT */ "Invalid slot", |
/* 58 */ "", |
/* 59 EBFONT */ "Bad font file format", |
/* 60 ENOSTR */ "Device not a stream", |
/* 61 ENODATA */ "No data available", |
/* 62 ETIME */ "Timer expired", |
/* 63 ENOSR */ "Out of streams resources", |
/* 64 ENONET */ "Machine is not on the network", |
/* 65 ENOPKG */ "Package not installed", |
/* 66 EREMOTE */ "Object is remote", |
/* 67 ENOLINK */ "Link has been severed", |
/* 68 EADV */ "Advertise error", |
/* 69 ESRMNT */ "Srmount error", |
/* 70 ECOMM */ "Communication error on send", |
/* 71 EPROTO */ "Protocol error", |
/* 72 EMULTIHOP */ "Multihop attempted", |
/* 73 EDOTDOT */ "RFS specific error", |
/* 74 EBADMSG */ "Not a data message", |
/* 75 EOVERFLOW */ "Value too large for defined data type", |
/* 76 ENOTUNIQ */ "Name not unique on network", |
/* 77 EBADFD */ "File descriptor in bad state", |
/* 78 EREMCHG */ "Remote address changed", |
/* 79 ELIBACC */ "Can not access a needed shared library", |
/* 80 ELIBBAD */ "Accessing a corrupted shared library", |
/* 81 ELIBSCN */ ".lib section in a.out corrupted", |
/* 82 ELIBMAX */ "Attempting to link in too many shared libraries", |
/* 83 ELIBEXEC */ "Cannot exec a shared library directly", |
/* 84 EILSEQ */ "Illegal byte sequence", |
/* 85 ERESTART */ "Interrupted system call should be restarted", |
/* 86 ESTRPIPE */ "Streams pipe error", |
/* 87 EUSERS */ "Too many users", |
/* 88 ENOTSOCK */ "Socket operation on non-socket", |
/* 89 EDESTADDRREQ */ "Destination address required", |
/* 90 EMSGSIZE */ "Message too long", |
/* 91 EPROTOTYPE */ "Protocol wrong type for socket", |
/* 92 ENOPROTOOPT */ "Protocol not available", |
/* 93 EPROTONOSUPPORT */ "Protocol not supported", |
/* 94 ESOCKTNOSUPPORT */ "Socket type not supported", |
/* 95 EOPNOTSUPP */ "Operation not supported on transport endpoint", |
/* 96 EPFNOSUPPORT */ "Protocol family not supported", |
/* 97 EAFNOSUPPORT */ "Address family not supported by protocol", |
/* 98 EADDRINUSE */ "Address already in use", |
/* 99 EADDRNOTAVAIL */ "Cannot assign requested address", |
/* 100 ENETDOWN */ "Network is down", |
/* 101 ENETUNREACH */ "Network is unreachable", |
/* 102 ENETRESET */ "Network dropped connection because of reset", |
/* 103 ECONNABORTED */ "Software caused connection abort", |
/* 104 ECONNRESET */ "Connection reset by peer", |
/* 105 ENOBUFS */ "No buffer space available", |
/* 106 EISCONN */ "Transport endpoint is already connected", |
/* 107 ENOTCONN */ "Transport endpoint is not connected", |
/* 108 ESHUTDOWN */ "Cannot send after transport endpoint shutdown", |
/* 109 ETOOMANYREFS */ "Too many references: cannot splice", |
/* 110 ETIMEDOUT */ "Connection timed out", |
/* 111 ECONNREFUSED */ "Connection refused", |
/* 112 EHOSTDOWN */ "Host is down", |
/* 113 EHOSTUNREACH */ "No route to host", |
/* 114 EALREADY */ "Operation already in progress", |
/* 115 EINPROGRESS */ "Operation now in progress", |
/* 116 ESTALE */ "Stale NFS file handle", |
/* 117 EUCLEAN */ "Structure needs cleaning", |
/* 118 ENOTNAM */ "Not a XENIX named type file", |
/* 119 ENAVAIL */ "No XENIX semaphores available", |
/* 120 EISNAM */ "Is a named type file", |
/* 121 EREMOTEIO */ "Remote I/O error", |
/* 122 EDQUOT */ "Quota exceeded", |
/* 121 */ "", |
/* 123 ENOMEDIUM */ "No medium found", |
/* 124 EMEDIUMTYPE */ "Wrong medium type" |
/* if more are added, be sure to update _sys_nerr accordingly */ |
}; |
#else |
char *_sys_errlist[] = { |
/* 0 EZERO */ "No error", |
/* 1 ENOENT */ "No such file or directory", |
/* 2 E2BIG */ "Arg list too big", |
/* 3 ENOEXEC */ "Exec format error", |
/* 4 EBADF */ "Bad file number", |
/* 5 ENOMEM */ "Not enough memory", |
/* 6 EACCES */ "Permission denied", |
/* 7 EEXIST */ "File exists", |
/* 8 EXDEV */ "Cross-device link", |
/* 9 EINVAL */ "Invalid argument", |
/* 10 ENFILE */ "File table overflow", |
/* 11 EMFILE */ "Too many open files", |
/* 12 ENOSPC */ "No space left on device", |
/* 13 EDOM */ "Argument too large", |
/* 14 ERANGE */ "Result too large", |
/* 15 EDEADLK */ "Resource deadlock would occur", |
/* 16 EINTR */ "System call interrupted", |
/* 17 ECHILD */ "Child does not exist", |
/* 18 EAGAIN */ "Resource unavailable, try again", |
/* 19 EBUSY */ "Device or resource busy", |
/* 20 EFBIG */ "File too large", |
/* 21 EIO */ "I/O error", |
/* 22 EISDIR */ "Is a directory", |
/* 23 ENOTDIR */ "Not a directory", |
/* 24 EMLINK */ "Too many links", |
/* 25 ENOTBLK */ "Block device required", |
/* 26 ENOTTY */ "Not a character device", |
/* 27 ENXIO */ "No such device or address", |
/* 28 EPERM */ "Not owner", |
/* 29 EPIPE */ "Broken pipe", |
/* 30 EROFS */ "Read-only file system", |
/* 31 ESPIPE */ "Illegal seek", |
/* 32 ESRCH */ "No such process", |
/* 33 ETXTBSY */ "Text file busy", |
/* 34 EFAULT */ "Bad address", |
/* 35 ENAMETOOLONG */ "Filename too long", |
/* 36 ENODEV */ "No such device", |
/* 37 ENOLCK */ "No locks available in system", |
/* 38 ENOSYS */ "Unknown system call", |
/* 39 ENOTEMPTY */ "Directory not empty", |
/* 40 EILSEQ */ "Illegal multibyte sequence" |
/* if more are added, be sure to update _sys_nerr accordingly */ |
}; |
#endif |
|
int _WCNEAR _sys_nerr = ( sizeof( _sys_errlist ) / sizeof( *_sys_errlist ) ); |
|
#endif |
|
_WCRTLINK CHAR_TYPE *__F_NAME(strerror,wcserror)( int errnum ) |
{ |
#ifdef __WIDECHAR__ |
static wchar_t Wide_Error_String[40]; |
#endif |
char *msg; |
|
if( errnum < 0 || errnum >= _sys_nerr ) { |
msg = UNKNOWN_ERROR; |
} else { |
msg = _sys_errlist[ errnum ]; |
} |
return( _AToUni( Wide_Error_String, msg ) ); |
} |
|
// Note: Windows FORMAT_MESSAGE_MAX_WIDTH_MASK is 255 |
|
#if !defined(FORMAT_MESSAGE_MAX_WIDTH_MASK) |
#define FORMAT_MESSAGE_MAX_WIDTH_MASK 255 |
#endif |
|
#ifdef __WIDECHAR__ |
static wchar_t Wide_Error_String[FORMAT_MESSAGE_MAX_WIDTH_MASK+1]; |
#else |
static char Error_String[FORMAT_MESSAGE_MAX_WIDTH_MASK+1]; |
#endif |
|
|
/* |
char *_strerror( const char *strErrMsg ); |
|
Description from the MSDN: |
|
If strErrMsg is passed as NULL, _strerror returns a pointer to a |
string containing the system error message for the last library call |
that produced an error. The error-message string is terminated by |
the newline character ('\n'). If strErrMsg is not equal to NULL, |
then _strerror returns a pointer to a string containing (in order) |
your string message, a colon, a space, the system error message for |
the last library call producing an error, and a newline character. |
Your string message can be, at most, 94 bytes long. |
|
The actual error number for _strerror is stored in the variable |
errno. The system error messages are accessed through the variable |
_sys_errlist, which is an array of messages ordered by error number. |
_strerror accesses the appropriate error message by using the errno |
value as an index to the variable _sys_errlist. The value of the |
variable _sys_nerr is defined as the maximum number of elements in |
the _sys_errlist array. To produce accurate results, call _strerror |
immediately after a library routine returns with an error. |
Otherwise, subsequent calls to strerror or _strerror can overwrite |
the errno value. |
|
_strerror is not part of the ANSI definition but is instead a |
Microsoft extension to it. Do not use it where portability is |
desired; for ANSI compatibility, use strerror instead. |
|
*/ |
|
_WCRTLINK CHAR_TYPE *__F_NAME(_strerror,_wcserror)( const CHAR_TYPE *strErrMsg ) |
{ |
int errnum; |
|
errnum = _RWD_errno; |
#ifdef __WIDECHAR__ |
Wide_Error_String[0] = L'\0'; |
if( strErrMsg != NULL ) { |
wcsncpy( Wide_Error_String, strErrMsg, 94 ); |
Wide_Error_String[94] = L'\0'; // just in case more than 94 |
wcscat( Wide_Error_String, L": " ); |
} |
wcscat( Wide_Error_String, wcserror( errnum ) ); |
wcscat( Wide_Error_String, L"\n" ); |
return( Wide_Error_String ); |
#else |
Error_String[0] = '\0'; |
if( strErrMsg != NULL ) { |
strncpy( Error_String, strErrMsg, 94 ); |
Error_String[94] = '\0'; // just in case more than 94 |
strcat( Error_String, ": " ); |
} |
strcat( Error_String, strerror( errnum ) ); |
strcat( Error_String, "\n" ); |
return( Error_String ); |
#endif |
} |
|
#if defined(__NT__) |
|
_WCRTLINK CHAR_TYPE *__F_NAME(_doserror,_wdoserror)( int errnum ) |
{ |
#ifdef __WIDECHAR__ |
Wide_Error_String[0] = L'\0'; |
FormatMessageW( FORMAT_MESSAGE_IGNORE_INSERTS | |
FORMAT_MESSAGE_FROM_SYSTEM | |
FORMAT_MESSAGE_MAX_WIDTH_MASK, |
NULL, |
errnum, |
0, |
Wide_Error_String, |
FORMAT_MESSAGE_MAX_WIDTH_MASK, |
NULL ); |
return( Wide_Error_String ); |
#else |
Error_String[0] = '\0'; |
FormatMessageA( FORMAT_MESSAGE_IGNORE_INSERTS | |
FORMAT_MESSAGE_FROM_SYSTEM | |
FORMAT_MESSAGE_MAX_WIDTH_MASK, |
NULL, |
errnum, |
0, |
Error_String, |
FORMAT_MESSAGE_MAX_WIDTH_MASK, |
NULL ); |
return( Error_String ); |
#endif |
} |
|
#endif |