Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  Implementation of strerror() function.
  28. *
  29. ****************************************************************************/
  30.  
  31.  
  32. #include "variety.h"
  33. #include "widechar.h"
  34. #include <string.h>
  35. #include <errno.h>
  36. #include "rtdata.h"
  37. #if defined(__NT__)
  38.     #include <windows.h>
  39. #endif
  40. #include "errstr.h"
  41.  
  42.  
  43. #ifndef __WIDECHAR__
  44.  
  45. #ifdef __LINUX__
  46. char *_sys_errlist[] = {
  47.     /*  0   EOK             */ "No error",
  48.     /*  1   EPERM           */ "Operation not permitted",
  49.     /*  2   ENOENT          */ "No such file or directory",
  50.     /*  3   ESRCH           */ "No such process",
  51.     /*  4   EINTR           */ "Interrupted system call",
  52.     /*  5   EIO             */ "I/O error",
  53.     /*  6   ENXIO           */ "No such device or address",
  54.     /*  7   E2BIG           */ "Arg list too long",
  55.     /*  8   ENOEXEC         */ "Exec format error",
  56.     /*  9   EBADF           */ "Bad file number",
  57.     /* 10   ECHILD          */ "No child processes",
  58.     /* 11   EAGAIN          */ "Try again",
  59.     /* 12   ENOMEM          */ "Out of memory",
  60.     /* 13   EACCES          */ "Permission denied",
  61.     /* 14   EFAULT          */ "Bad address",
  62.     /* 15   ENOTBLK         */ "Block device required",
  63.     /* 16   EBUSY           */ "Device or resource busy",
  64.     /* 17   EEXIST          */ "File exists",
  65.     /* 18   EXDEV           */ "Cross-device link",
  66.     /* 19   ENODEV          */ "No such device",
  67.     /* 20   ENOTDIR         */ "Not a directory",
  68.     /* 21   EISDIR          */ "Is a directory",
  69.     /* 22   EINVAL          */ "Invalid argument",
  70.     /* 23   ENFILE          */ "File table overflow",
  71.     /* 24   EMFILE          */ "Too many open files",
  72.     /* 25   ENOTTY          */ "Not a typewriter",
  73.     /* 26   ETXTBSY         */ "Text file busy",
  74.     /* 27   EFBIG           */ "File too large",
  75.     /* 28   ENOSPC          */ "No space left on device",
  76.     /* 29   ESPIPE          */ "Illegal seek",
  77.     /* 30   EROFS           */ "Read-only file system",
  78.     /* 31   EMLINK          */ "Too many links",
  79.     /* 32   EPIPE           */ "Broken pipe",
  80.     /* 33   EDOM            */ "Math argument out of domain of func",
  81.     /* 34   ERANGE          */ "Math result not representable",
  82.     /* 35   EDEADLK         */ "Resource deadlock would occur",
  83.     /* 36   ENAMETOOLONG    */ "File name too long",
  84.     /* 37   ENOLCK          */ "No record locks available",
  85.     /* 38   ENOSYS          */ "Function not implemented",
  86.     /* 39   ENOTEMPTY       */ "Directory not empty",
  87.     /* 40   ELOOP           */ "Too many symbolic links encountered",
  88.     /* 41                   */ "",
  89.     /* 42   ENOMSG          */ "No message of desired type",
  90.     /* 43   EIDRM           */ "Identifier removed",
  91.     /* 44   ECHRNG          */ "Channel number out of range",
  92.     /* 45   EL2NSYNC        */ "Level 2 not synchronized",
  93.     /* 46   EL3HLT          */ "Level 3 halted",
  94.     /* 47   EL3RST          */ "Level 3 reset",
  95.     /* 48   ELNRNG          */ "Link number out of range",
  96.     /* 49   EUNATCH         */ "Protocol driver not attached",
  97.     /* 50   ENOCSI          */ "No CSI structure available",
  98.     /* 51   EL2HLT          */ "Level 2 halted",
  99.     /* 52   EBADE           */ "Invalid exchange",
  100.     /* 53   EBADR           */ "Invalid request descriptor",
  101.     /* 54   EXFULL          */ "Exchange full",
  102.     /* 55   ENOANO          */ "No anode",
  103.     /* 56   EBADRQC         */ "Invalid request code",
  104.     /* 57   EBADSLT         */ "Invalid slot",
  105.     /* 58                   */ "",
  106.     /* 59   EBFONT          */ "Bad font file format",
  107.     /* 60   ENOSTR          */ "Device not a stream",
  108.     /* 61   ENODATA         */ "No data available",
  109.     /* 62   ETIME           */ "Timer expired",
  110.     /* 63   ENOSR           */ "Out of streams resources",
  111.     /* 64   ENONET          */ "Machine is not on the network",
  112.     /* 65   ENOPKG          */ "Package not installed",
  113.     /* 66   EREMOTE         */ "Object is remote",
  114.     /* 67   ENOLINK         */ "Link has been severed",
  115.     /* 68   EADV            */ "Advertise error",
  116.     /* 69   ESRMNT          */ "Srmount error",
  117.     /* 70   ECOMM           */ "Communication error on send",
  118.     /* 71   EPROTO          */ "Protocol error",
  119.     /* 72   EMULTIHOP       */ "Multihop attempted",
  120.     /* 73   EDOTDOT         */ "RFS specific error",
  121.     /* 74   EBADMSG         */ "Not a data message",
  122.     /* 75   EOVERFLOW       */ "Value too large for defined data type",
  123.     /* 76   ENOTUNIQ        */ "Name not unique on network",
  124.     /* 77   EBADFD          */ "File descriptor in bad state",
  125.     /* 78   EREMCHG         */ "Remote address changed",
  126.     /* 79   ELIBACC         */ "Can not access a needed shared library",
  127.     /* 80   ELIBBAD         */ "Accessing a corrupted shared library",
  128.     /* 81   ELIBSCN         */ ".lib section in a.out corrupted",
  129.     /* 82   ELIBMAX         */ "Attempting to link in too many shared libraries",
  130.     /* 83   ELIBEXEC        */ "Cannot exec a shared library directly",
  131.     /* 84   EILSEQ          */ "Illegal byte sequence",
  132.     /* 85   ERESTART        */ "Interrupted system call should be restarted",
  133.     /* 86   ESTRPIPE        */ "Streams pipe error",
  134.     /* 87   EUSERS          */ "Too many users",
  135.     /* 88   ENOTSOCK        */ "Socket operation on non-socket",
  136.     /* 89   EDESTADDRREQ    */ "Destination address required",
  137.     /* 90   EMSGSIZE        */ "Message too long",
  138.     /* 91   EPROTOTYPE      */ "Protocol wrong type for socket",
  139.     /* 92   ENOPROTOOPT     */ "Protocol not available",
  140.     /* 93   EPROTONOSUPPORT */ "Protocol not supported",
  141.     /* 94   ESOCKTNOSUPPORT */ "Socket type not supported",
  142.     /* 95   EOPNOTSUPP      */ "Operation not supported on transport endpoint",
  143.     /* 96   EPFNOSUPPORT    */ "Protocol family not supported",
  144.     /* 97   EAFNOSUPPORT    */ "Address family not supported by protocol",
  145.     /* 98   EADDRINUSE      */ "Address already in use",
  146.     /* 99   EADDRNOTAVAIL   */ "Cannot assign requested address",
  147.     /* 100  ENETDOWN        */ "Network is down",
  148.     /* 101  ENETUNREACH     */ "Network is unreachable",
  149.     /* 102  ENETRESET       */ "Network dropped connection because of reset",
  150.     /* 103  ECONNABORTED    */ "Software caused connection abort",
  151.     /* 104  ECONNRESET      */ "Connection reset by peer",
  152.     /* 105  ENOBUFS         */ "No buffer space available",
  153.     /* 106  EISCONN         */ "Transport endpoint is already connected",
  154.     /* 107  ENOTCONN        */ "Transport endpoint is not connected",
  155.     /* 108  ESHUTDOWN       */ "Cannot send after transport endpoint shutdown",
  156.     /* 109  ETOOMANYREFS    */ "Too many references: cannot splice",
  157.     /* 110  ETIMEDOUT       */ "Connection timed out",
  158.     /* 111  ECONNREFUSED    */ "Connection refused",
  159.     /* 112  EHOSTDOWN       */ "Host is down",
  160.     /* 113  EHOSTUNREACH    */ "No route to host",
  161.     /* 114  EALREADY        */ "Operation already in progress",
  162.     /* 115  EINPROGRESS     */ "Operation now in progress",
  163.     /* 116  ESTALE          */ "Stale NFS file handle",
  164.     /* 117  EUCLEAN         */ "Structure needs cleaning",
  165.     /* 118  ENOTNAM         */ "Not a XENIX named type file",
  166.     /* 119  ENAVAIL         */ "No XENIX semaphores available",
  167.     /* 120  EISNAM          */ "Is a named type file",
  168.     /* 121  EREMOTEIO       */ "Remote I/O error",
  169.     /* 122  EDQUOT          */ "Quota exceeded",
  170.     /* 121                  */ "",
  171.     /* 123  ENOMEDIUM       */ "No medium found",
  172.     /* 124  EMEDIUMTYPE     */ "Wrong medium type"
  173.     /* if more are added, be sure to update _sys_nerr accordingly */
  174. };
  175. #else
  176. char *_sys_errlist[] = {
  177.     /* 0    EZERO           */  "No error",
  178.     /* 1    ENOENT          */  "No such file or directory",
  179.     /* 2    E2BIG           */  "Arg list too big",
  180.     /* 3    ENOEXEC         */  "Exec format error",
  181.     /* 4    EBADF           */  "Bad file number",
  182.     /* 5    ENOMEM          */  "Not enough memory",
  183.     /* 6    EACCES          */  "Permission denied",
  184.     /* 7    EEXIST          */  "File exists",
  185.     /* 8    EXDEV           */  "Cross-device link",
  186.     /* 9    EINVAL          */  "Invalid argument",
  187.     /* 10   ENFILE          */  "File table overflow",
  188.     /* 11   EMFILE          */  "Too many open files",
  189.     /* 12   ENOSPC          */  "No space left on device",
  190.     /* 13   EDOM            */  "Argument too large",
  191.     /* 14   ERANGE          */  "Result too large",
  192.     /* 15   EDEADLK         */  "Resource deadlock would occur",
  193.     /* 16   EINTR           */  "System call interrupted",
  194.     /* 17   ECHILD          */  "Child does not exist",
  195.     /* 18   EAGAIN          */  "Resource unavailable, try again",
  196.     /* 19   EBUSY           */  "Device or resource busy",
  197.     /* 20   EFBIG           */  "File too large",
  198.     /* 21   EIO             */  "I/O error",
  199.     /* 22   EISDIR          */  "Is a directory",
  200.     /* 23   ENOTDIR         */  "Not a directory",
  201.     /* 24   EMLINK          */  "Too many links",
  202.     /* 25   ENOTBLK         */  "Block device required",
  203.     /* 26   ENOTTY          */  "Not a character device",
  204.     /* 27   ENXIO           */  "No such device or address",
  205.     /* 28   EPERM           */  "Not owner",
  206.     /* 29   EPIPE           */  "Broken pipe",
  207.     /* 30   EROFS           */  "Read-only file system",
  208.     /* 31   ESPIPE          */  "Illegal seek",
  209.     /* 32   ESRCH           */  "No such process",
  210.     /* 33   ETXTBSY         */  "Text file busy",
  211.     /* 34   EFAULT          */  "Bad address",
  212.     /* 35   ENAMETOOLONG    */  "Filename too long",
  213.     /* 36   ENODEV          */  "No such device",
  214.     /* 37   ENOLCK          */  "No locks available in system",
  215.     /* 38   ENOSYS          */  "Unknown system call",
  216.     /* 39   ENOTEMPTY       */  "Directory not empty",
  217.     /* 40   EILSEQ          */  "Illegal multibyte sequence"
  218.     /* if more are added, be sure to update _sys_nerr accordingly */
  219. };
  220. #endif
  221.  
  222. int _WCNEAR _sys_nerr = ( sizeof( _sys_errlist ) / sizeof( *_sys_errlist ) );
  223.  
  224. #endif
  225.  
  226. _WCRTLINK CHAR_TYPE *__F_NAME(strerror,wcserror)( int errnum )
  227. {
  228. #ifdef __WIDECHAR__
  229.     static wchar_t  Wide_Error_String[40];
  230. #endif
  231.     char            *msg;
  232.  
  233.     if( errnum < 0 || errnum >= _sys_nerr ) {
  234.         msg = UNKNOWN_ERROR;
  235.     } else {
  236.         msg = _sys_errlist[ errnum ];
  237.     }
  238.     return( _AToUni( Wide_Error_String, msg ) );
  239. }
  240.  
  241. // Note: Windows FORMAT_MESSAGE_MAX_WIDTH_MASK is 255
  242.  
  243. #if !defined(FORMAT_MESSAGE_MAX_WIDTH_MASK)
  244.     #define FORMAT_MESSAGE_MAX_WIDTH_MASK 255
  245. #endif
  246.  
  247. #ifdef __WIDECHAR__
  248. static  wchar_t Wide_Error_String[FORMAT_MESSAGE_MAX_WIDTH_MASK+1];
  249. #else
  250. static  char    Error_String[FORMAT_MESSAGE_MAX_WIDTH_MASK+1];
  251. #endif
  252.  
  253.  
  254. /*
  255.     char *_strerror( const char *strErrMsg );
  256.  
  257.     Description from the MSDN:
  258.  
  259.     If strErrMsg is passed as NULL, _strerror returns a pointer to a
  260.     string containing the system error message for the last library call
  261.     that produced an error. The error-message string is terminated by
  262.     the newline character ('\n'). If strErrMsg is not equal to NULL,
  263.     then _strerror returns a pointer to a string containing (in order)
  264.     your string message, a colon, a space, the system error message for
  265.     the last library call producing an error, and a newline character.
  266.     Your string message can be, at most, 94 bytes long.
  267.  
  268.     The actual error number for _strerror is stored in the variable
  269.     errno. The system error messages are accessed through the variable
  270.     _sys_errlist, which is an array of messages ordered by error number.
  271.     _strerror accesses the appropriate error message by using the errno
  272.     value as an index to the variable _sys_errlist. The value of the
  273.     variable _sys_nerr is defined as the maximum number of elements in
  274.     the _sys_errlist array. To produce accurate results, call _strerror
  275.     immediately after a library routine returns with an error.
  276.     Otherwise, subsequent calls to strerror or _strerror can overwrite
  277.     the errno value.
  278.  
  279.     _strerror is not part of the ANSI definition but is instead a
  280.     Microsoft extension to it. Do not use it where portability is
  281.     desired; for ANSI compatibility, use strerror instead.
  282.  
  283.  */
  284.  
  285. _WCRTLINK CHAR_TYPE *__F_NAME(_strerror,_wcserror)( const CHAR_TYPE *strErrMsg )
  286. {
  287.     int errnum;
  288.  
  289.     errnum = _RWD_errno;
  290. #ifdef __WIDECHAR__
  291.     Wide_Error_String[0] = L'\0';
  292.     if( strErrMsg != NULL ) {
  293.         wcsncpy( Wide_Error_String, strErrMsg, 94 );
  294.         Wide_Error_String[94] = L'\0';    // just in case more than 94
  295.         wcscat( Wide_Error_String, L": " );
  296.     }
  297.     wcscat( Wide_Error_String, wcserror( errnum ) );
  298.     wcscat( Wide_Error_String, L"\n" );
  299.     return( Wide_Error_String );
  300. #else
  301.     Error_String[0] = '\0';
  302.     if( strErrMsg != NULL ) {
  303.         strncpy( Error_String, strErrMsg, 94 );
  304.         Error_String[94] = '\0';    // just in case more than 94
  305.         strcat( Error_String, ": " );
  306.     }
  307.     strcat( Error_String, strerror( errnum ) );
  308.     strcat( Error_String, "\n" );
  309.     return( Error_String );
  310. #endif
  311. }
  312.  
  313. #if defined(__NT__)
  314.  
  315. _WCRTLINK CHAR_TYPE *__F_NAME(_doserror,_wdoserror)( int errnum )
  316. {
  317. #ifdef __WIDECHAR__
  318.     Wide_Error_String[0] = L'\0';
  319.     FormatMessageW( FORMAT_MESSAGE_IGNORE_INSERTS |
  320.                     FORMAT_MESSAGE_FROM_SYSTEM |
  321.                     FORMAT_MESSAGE_MAX_WIDTH_MASK,
  322.                     NULL,
  323.                     errnum,
  324.                     0,
  325.                     Wide_Error_String,
  326.                     FORMAT_MESSAGE_MAX_WIDTH_MASK,
  327.                     NULL );
  328.     return( Wide_Error_String );
  329. #else
  330.     Error_String[0] = '\0';
  331.     FormatMessageA( FORMAT_MESSAGE_IGNORE_INSERTS |
  332.                     FORMAT_MESSAGE_FROM_SYSTEM |
  333.                     FORMAT_MESSAGE_MAX_WIDTH_MASK,
  334.                     NULL,
  335.                     errnum,
  336.                     0,
  337.                     Error_String,
  338.                     FORMAT_MESSAGE_MAX_WIDTH_MASK,
  339.                     NULL );
  340.     return( Error_String );
  341. #endif
  342. }
  343.  
  344. #endif
  345.