////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001-2026 Alexey Kuryakin daqgroup@mail.ru under MIT license //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// This file is part of the CRW-DAQ project by DaqGroup - component CRWLIB.   //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Purpose:                                                                   //
// POSIX error codes (errno).                                                 //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// History:                                                                   //
// 20260325 - Created by A.K.                                                 //
////////////////////////////////////////////////////////////////////////////////

unit _crw_errno; //  UNIX error codes (errno).

{$I _crw_sysdef.inc}

{$I _crw_sysmode.inc}

interface

uses
 //////////////////////////////////////////////////////
 {$I _crw_uses_first.inc} // NB: MUST BE FIRST USES !!!
 //////////////////////////////////////////////////////
 sysutils, classes, math,
 _crw_alloc, _crw_ef, _crw_hl, _crw_str, _crw_fio;

const
 {$I _crw_errno.inc}

type
 TErrnoCodes = EFAIL..EHWPOISON;

function ErrnoToString(n:Integer; Def:LongString=''):LongString;
function ErrnoToComment(n:Integer; Def:LongString=''):LongString;
function StringToErrno(const S:LongString; Def:Integer=-1):Integer;
function ErrnoNamesValues(const Delim:LongString=EOL):LongString;
function ErrnoNames(const Delim:LongString=EOL):LongString;
function FormatErrno(n:Integer):LongString;
function ErrnoSelfTest:Boolean;

implementation

 /////////////////////////////////////////////////////
 // Private Dictionary for fast string identification.
 /////////////////////////////////////////////////////
type
 TStringIdentifier = (
  sid_Unknown,
  sid_EFAIL,
  sid_EOK,
  sid_EPERM,
  sid_ENOENT,
  sid_ESRCH,
  sid_EINTR,
  sid_EIO,
  sid_ENXIO,
  sid_E2BIG,
  sid_ENOEXEC,
  sid_EBADF,
  sid_ECHILD,
  sid_EAGAIN,
  sid_ENOMEM,
  sid_EACCES,
  sid_EFAULT,
  sid_ENOTBLK,
  sid_EBUSY,
  sid_EEXIST,
  sid_EXDEV,
  sid_ENODEV,
  sid_ENOTDIR,
  sid_EISDIR,
  sid_EINVAL,
  sid_ENFILE,
  sid_EMFILE,
  sid_ENOTTY,
  sid_ETXTBSY,
  sid_EFBIG,
  sid_ENOSPC,
  sid_ESPIPE,
  sid_EROFS,
  sid_EMLINK,
  sid_EPIPE,
  sid_EDOM,
  sid_ERANGE,
  sid_EDEADLK,
  sid_ENAMETOOLONG,
  sid_ENOLCK,
  sid_ENOSYS,
  sid_ENOTEMPTY,
  sid_ELOOP,
  sid_EWOULDBLOCK,
  sid_ENOMSG,
  sid_EIDRM,
  sid_ECHRNG,
  sid_EL2NSYNC,
  sid_EL3HLT,
  sid_EL3RST,
  sid_ELNRNG,
  sid_EUNATCH,
  sid_ENOCSI,
  sid_EL2HLT,
  sid_EBADE,
  sid_EBADR,
  sid_EXFULL,
  sid_ENOANO,
  sid_EBADRQC,
  sid_EBADSLT,
  sid_EDEADLOCK,
  sid_EBFONT,
  sid_ENOSTR,
  sid_ENODATA,
  sid_ETIME,
  sid_ENOSR,
  sid_ENONET,
  sid_ENOPKG,
  sid_EREMOTE,
  sid_ENOLINK,
  sid_EADV,
  sid_ESRMNT,
  sid_ECOMM,
  sid_EPROTO,
  sid_EMULTIHOP,
  sid_EDOTDOT,
  sid_EBADMSG,
  sid_EOVERFLOW,
  sid_ENOTUNIQ,
  sid_EBADFD,
  sid_EREMCHG,
  sid_ELIBACC,
  sid_ELIBBAD,
  sid_ELIBSCN,
  sid_ELIBMAX,
  sid_ELIBEXEC,
  sid_EILSEQ,
  sid_ERESTART,
  sid_ESTRPIPE,
  sid_EUSERS,
  sid_ENOTSOCK,
  sid_EDESTADDRREQ,
  sid_EMSGSIZE,
  sid_EPROTOTYPE,
  sid_ENOPROTOOPT,
  sid_EPROTONOSUPPORT,
  sid_ESOCKTNOSUPPORT,
  sid_EOPNOTSUPP,
  sid_EPFNOSUPPORT,
  sid_EAFNOSUPPORT,
  sid_EADDRINUSE,
  sid_EADDRNOTAVAIL,
  sid_ENETDOWN,
  sid_ENETUNREACH,
  sid_ENETRESET,
  sid_ECONNABORTED,
  sid_ECONNRESET,
  sid_ENOBUFS,
  sid_EISCONN,
  sid_ENOTCONN,
  sid_ESHUTDOWN,
  sid_ETOOMANYREFS,
  sid_ETIMEDOUT,
  sid_ECONNREFUSED,
  sid_EHOSTDOWN,
  sid_EHOSTUNREACH,
  sid_EALREADY,
  sid_EINPROGRESS,
  sid_ESTALE,
  sid_EUCLEAN,
  sid_ENOTNAM,
  sid_ENAVAIL,
  sid_EISNAM,
  sid_EREMOTEIO,
  sid_EDQUOT,
  sid_ENOMEDIUM,
  sid_EMEDIUMTYPE,
  sid_ECANCELED,
  sid_ENOKEY,
  sid_EKEYEXPIRED,
  sid_EKEYREVOKED,
  sid_EKEYREJECTED,
  sid_EOWNERDEAD,
  sid_ENOTRECOVERABLE,
  sid_ERFKILL,
  sid_EHWPOISON,
  sid_ENOTSUP,
  //////////////////////
  sid_Asterisk,
  sid_Question,
  sid_Unused
 );

const
 Dictionary:THashList=nil;

procedure FreeDictionary;
begin
 Kill(Dictionary);
end;

procedure InitDictionary;
 procedure AddSid(const key:LongString; sid:TStringIdentifier);
 begin
  Dictionary.KeyedLinks[key]:=Ord(sid);
  Dictionary.KeyedParams[key]:=key;
 end;
begin
 if (Dictionary<>nil) then Exit;
 Dictionary:=NewHashList(false,HashList_DefaultHasher);
 Dictionary.Master:=@Dictionary;
 Dictionary.OwnsObjects:=false;
 /////////////////////////////////////////////
 // Dictionary for fast strings identification
 /////////////////////////////////////////////
 AddSid('EFAIL'           , sid_EFAIL);
 AddSid('EOK'             , sid_EOK);
 AddSid('EPERM'           , sid_EPERM);
 AddSid('ENOENT'          , sid_ENOENT);
 AddSid('ESRCH'           , sid_ESRCH);
 AddSid('EINTR'           , sid_EINTR);
 AddSid('EIO'             , sid_EIO);
 AddSid('ENXIO'           , sid_ENXIO);
 AddSid('E2BIG'           , sid_E2BIG);
 AddSid('ENOEXEC'         , sid_ENOEXEC);
 AddSid('EBADF'           , sid_EBADF);
 AddSid('ECHILD'          , sid_ECHILD);
 AddSid('EAGAIN'          , sid_EAGAIN);
 AddSid('ENOMEM'          , sid_ENOMEM);
 AddSid('EACCES'          , sid_EACCES);
 AddSid('EFAULT'          , sid_EFAULT);
 AddSid('ENOTBLK'         , sid_ENOTBLK);
 AddSid('EBUSY'           , sid_EBUSY);
 AddSid('EEXIST'          , sid_EEXIST);
 AddSid('EXDEV'           , sid_EXDEV);
 AddSid('ENODEV'          , sid_ENODEV);
 AddSid('ENOTDIR'         , sid_ENOTDIR);
 AddSid('EISDIR'          , sid_EISDIR);
 AddSid('EINVAL'          , sid_EINVAL);
 AddSid('ENFILE'          , sid_ENFILE);
 AddSid('EMFILE'          , sid_EMFILE);
 AddSid('ENOTTY'          , sid_ENOTTY);
 AddSid('ETXTBSY'         , sid_ETXTBSY);
 AddSid('EFBIG'           , sid_EFBIG);
 AddSid('ENOSPC'          , sid_ENOSPC);
 AddSid('ESPIPE'          , sid_ESPIPE);
 AddSid('EROFS'           , sid_EROFS);
 AddSid('EMLINK'          , sid_EMLINK);
 AddSid('EPIPE'           , sid_EPIPE);
 AddSid('EDOM'            , sid_EDOM);
 AddSid('ERANGE'          , sid_ERANGE);
 AddSid('EDEADLK'         , sid_EDEADLK);
 AddSid('ENAMETOOLONG'    , sid_ENAMETOOLONG);
 AddSid('ENOLCK'          , sid_ENOLCK);
 AddSid('ENOSYS'          , sid_ENOSYS);
 AddSid('ENOTEMPTY'       , sid_ENOTEMPTY);
 AddSid('ELOOP'           , sid_ELOOP);
 AddSid('EWOULDBLOCK'     , sid_EWOULDBLOCK);
 AddSid('ENOMSG'          , sid_ENOMSG);
 AddSid('EIDRM'           , sid_EIDRM);
 AddSid('ECHRNG'          , sid_ECHRNG);
 AddSid('EL2NSYNC'        , sid_EL2NSYNC);
 AddSid('EL3HLT'          , sid_EL3HLT);
 AddSid('EL3RST'          , sid_EL3RST);
 AddSid('ELNRNG'          , sid_ELNRNG);
 AddSid('EUNATCH'         , sid_EUNATCH);
 AddSid('ENOCSI'          , sid_ENOCSI);
 AddSid('EL2HLT'          , sid_EL2HLT);
 AddSid('EBADE'           , sid_EBADE);
 AddSid('EBADR'           , sid_EBADR);
 AddSid('EXFULL'          , sid_EXFULL);
 AddSid('ENOANO'          , sid_ENOANO);
 AddSid('EBADRQC'         , sid_EBADRQC);
 AddSid('EBADSLT'         , sid_EBADSLT);
 AddSid('EDEADLOCK'       , sid_EDEADLOCK);
 AddSid('EBFONT'          , sid_EBFONT);
 AddSid('ENOSTR'          , sid_ENOSTR);
 AddSid('ENODATA'         , sid_ENODATA);
 AddSid('ETIME'           , sid_ETIME);
 AddSid('ENOSR'           , sid_ENOSR);
 AddSid('ENONET'          , sid_ENONET);
 AddSid('ENOPKG'          , sid_ENOPKG);
 AddSid('EREMOTE'         , sid_EREMOTE);
 AddSid('ENOLINK'         , sid_ENOLINK);
 AddSid('EADV'            , sid_EADV);
 AddSid('ESRMNT'          , sid_ESRMNT);
 AddSid('ECOMM'           , sid_ECOMM);
 AddSid('EPROTO'          , sid_EPROTO);
 AddSid('EMULTIHOP'       , sid_EMULTIHOP);
 AddSid('EDOTDOT'         , sid_EDOTDOT);
 AddSid('EBADMSG'         , sid_EBADMSG);
 AddSid('EOVERFLOW'       , sid_EOVERFLOW);
 AddSid('ENOTUNIQ'        , sid_ENOTUNIQ);
 AddSid('EBADFD'          , sid_EBADFD);
 AddSid('EREMCHG'         , sid_EREMCHG);
 AddSid('ELIBACC'         , sid_ELIBACC);
 AddSid('ELIBBAD'         , sid_ELIBBAD);
 AddSid('ELIBSCN'         , sid_ELIBSCN);
 AddSid('ELIBMAX'         , sid_ELIBMAX);
 AddSid('ELIBEXEC'        , sid_ELIBEXEC);
 AddSid('EILSEQ'          , sid_EILSEQ);
 AddSid('ERESTART'        , sid_ERESTART);
 AddSid('ESTRPIPE'        , sid_ESTRPIPE);
 AddSid('EUSERS'          , sid_EUSERS);
 AddSid('ENOTSOCK'        , sid_ENOTSOCK);
 AddSid('EDESTADDRREQ'    , sid_EDESTADDRREQ);
 AddSid('EMSGSIZE'        , sid_EMSGSIZE);
 AddSid('EPROTOTYPE'      , sid_EPROTOTYPE);
 AddSid('ENOPROTOOPT'     , sid_ENOPROTOOPT);
 AddSid('EPROTONOSUPPORT' , sid_EPROTONOSUPPORT);
 AddSid('ESOCKTNOSUPPORT' , sid_ESOCKTNOSUPPORT);
 AddSid('EOPNOTSUPP'      , sid_EOPNOTSUPP);
 AddSid('EPFNOSUPPORT'    , sid_EPFNOSUPPORT);
 AddSid('EAFNOSUPPORT'    , sid_EAFNOSUPPORT);
 AddSid('EADDRINUSE'      , sid_EADDRINUSE);
 AddSid('EADDRNOTAVAIL'   , sid_EADDRNOTAVAIL);
 AddSid('ENETDOWN'        , sid_ENETDOWN);
 AddSid('ENETUNREACH'     , sid_ENETUNREACH);
 AddSid('ENETRESET'       , sid_ENETRESET);
 AddSid('ECONNABORTED'    , sid_ECONNABORTED);
 AddSid('ECONNRESET'      , sid_ECONNRESET);
 AddSid('ENOBUFS'         , sid_ENOBUFS);
 AddSid('EISCONN'         , sid_EISCONN);
 AddSid('ENOTCONN'        , sid_ENOTCONN);
 AddSid('ESHUTDOWN'       , sid_ESHUTDOWN);
 AddSid('ETOOMANYREFS'    , sid_ETOOMANYREFS);
 AddSid('ETIMEDOUT'       , sid_ETIMEDOUT);
 AddSid('ECONNREFUSED'    , sid_ECONNREFUSED);
 AddSid('EHOSTDOWN'       , sid_EHOSTDOWN);
 AddSid('EHOSTUNREACH'    , sid_EHOSTUNREACH);
 AddSid('EALREADY'        , sid_EALREADY);
 AddSid('EINPROGRESS'     , sid_EINPROGRESS);
 AddSid('ESTALE'          , sid_ESTALE);
 AddSid('EUCLEAN'         , sid_EUCLEAN);
 AddSid('ENOTNAM'         , sid_ENOTNAM);
 AddSid('ENAVAIL'         , sid_ENAVAIL);
 AddSid('EISNAM'          , sid_EISNAM);
 AddSid('EREMOTEIO'       , sid_EREMOTEIO);
 AddSid('EDQUOT'          , sid_EDQUOT);
 AddSid('ENOMEDIUM'       , sid_ENOMEDIUM);
 AddSid('EMEDIUMTYPE'     , sid_EMEDIUMTYPE);
 AddSid('ECANCELED'       , sid_ECANCELED);
 AddSid('ENOKEY'          , sid_ENOKEY);
 AddSid('EKEYEXPIRED'     , sid_EKEYEXPIRED);
 AddSid('EKEYREVOKED'     , sid_EKEYREVOKED);
 AddSid('EKEYREJECTED'    , sid_EKEYREJECTED);
 AddSid('EOWNERDEAD'      , sid_EOWNERDEAD);
 AddSid('ENOTRECOVERABLE' , sid_ENOTRECOVERABLE);
 AddSid('ERFKILL'         , sid_ERFKILL);
 AddSid('EHWPOISON'       , sid_EHWPOISON);
 AddSid('ENOTSUP'         , sid_ENOTSUP);
 AddSid( '*'              , sid_Asterisk);
 AddSid( '?'              , sid_Question);
end;

function Identify(const key:LongString):TStringIdentifier;
var sid:Integer;
begin
 if (Dictionary=nil) then InitDictionary;
 sid:=Dictionary.KeyedLinks[key];
 if (sid>=Ord(Low(TStringIdentifier))) and (sid<=Ord(High(TStringIdentifier)))
 then Result:=TStringIdentifier(sid)
 else Result:=sid_Unknown;
end;

/////////////////////////////
// Service function for errno
/////////////////////////////

function ErrnoToString(n:Integer; Def:LongString=''):LongString;
begin
 Result:=Def;
 case n of
  EFAIL:            Result:='EFAIL';
  EOK:              Result:='EOK';
  EPERM:            Result:='EPERM';
  ENOENT:           Result:='ENOENT';
  ESRCH:            Result:='ESRCH';
  EINTR:            Result:='EINTR';
  EIO:              Result:='EIO';
  ENXIO:            Result:='ENXIO';
  E2BIG:            Result:='E2BIG';
  ENOEXEC:          Result:='ENOEXEC';
  EBADF:            Result:='EBADF';
  ECHILD:           Result:='ECHILD';
  EAGAIN:           Result:='EAGAIN';
  ENOMEM:           Result:='ENOMEM';
  EACCES:           Result:='EACCES';
  EFAULT:           Result:='EFAULT';
  ENOTBLK:          Result:='ENOTBLK';
  EBUSY:            Result:='EBUSY';
  EEXIST:           Result:='EEXIST';
  EXDEV:            Result:='EXDEV';
  ENODEV:           Result:='ENODEV';
  ENOTDIR:          Result:='ENOTDIR';
  EISDIR:           Result:='EISDIR';
  EINVAL:           Result:='EINVAL';
  ENFILE:           Result:='ENFILE';
  EMFILE:           Result:='EMFILE';
  ENOTTY:           Result:='ENOTTY';
  ETXTBSY:          Result:='ETXTBSY';
  EFBIG:            Result:='EFBIG';
  ENOSPC:           Result:='ENOSPC';
  ESPIPE:           Result:='ESPIPE';
  EROFS:            Result:='EROFS';
  EMLINK:           Result:='EMLINK';
  EPIPE:            Result:='EPIPE';
  EDOM:             Result:='EDOM';
  ERANGE:           Result:='ERANGE';
  EDEADLK:          Result:='EDEADLK';
  ENAMETOOLONG:     Result:='ENAMETOOLONG';
  ENOLCK:           Result:='ENOLCK';
  ENOSYS:           Result:='ENOSYS';
  ENOTEMPTY:        Result:='ENOTEMPTY';
  ELOOP:            Result:='ELOOP';
//EWOULDBLOCK:      Result:='EWOULDBLOCK';
  ENOMSG:           Result:='ENOMSG';
  EIDRM:            Result:='EIDRM';
  ECHRNG:           Result:='ECHRNG';
  EL2NSYNC:         Result:='EL2NSYNC';
  EL3HLT:           Result:='EL3HLT';
  EL3RST:           Result:='EL3RST';
  ELNRNG:           Result:='ELNRNG';
  EUNATCH:          Result:='EUNATCH';
  ENOCSI:           Result:='ENOCSI';
  EL2HLT:           Result:='EL2HLT';
  EBADE:            Result:='EBADE';
  EBADR:            Result:='EBADR';
  EXFULL:           Result:='EXFULL';
  ENOANO:           Result:='ENOANO';
  EBADRQC:          Result:='EBADRQC';
  EBADSLT:          Result:='EBADSLT';
//EDEADLOCK:        Result:='EDEADLOCK';
  EBFONT:           Result:='EBFONT';
  ENOSTR:           Result:='ENOSTR';
  ENODATA:          Result:='ENODATA';
  ETIME:            Result:='ETIME';
  ENOSR:            Result:='ENOSR';
  ENONET:           Result:='ENONET';
  ENOPKG:           Result:='ENOPKG';
  EREMOTE:          Result:='EREMOTE';
  ENOLINK:          Result:='ENOLINK';
  EADV:             Result:='EADV';
  ESRMNT:           Result:='ESRMNT';
  ECOMM:            Result:='ECOMM';
  EPROTO:           Result:='EPROTO';
  EMULTIHOP:        Result:='EMULTIHOP';
  EDOTDOT:          Result:='EDOTDOT';
  EBADMSG:          Result:='EBADMSG';
  EOVERFLOW:        Result:='EOVERFLOW';
  ENOTUNIQ:         Result:='ENOTUNIQ';
  EBADFD:           Result:='EBADFD';
  EREMCHG:          Result:='EREMCHG';
  ELIBACC:          Result:='ELIBACC';
  ELIBBAD:          Result:='ELIBBAD';
  ELIBSCN:          Result:='ELIBSCN';
  ELIBMAX:          Result:='ELIBMAX';
  ELIBEXEC:         Result:='ELIBEXEC';
  EILSEQ:           Result:='EILSEQ';
  ERESTART:         Result:='ERESTART';
  ESTRPIPE:         Result:='ESTRPIPE';
  EUSERS:           Result:='EUSERS';
  ENOTSOCK:         Result:='ENOTSOCK';
  EDESTADDRREQ:     Result:='EDESTADDRREQ';
  EMSGSIZE:         Result:='EMSGSIZE';
  EPROTOTYPE:       Result:='EPROTOTYPE';
  ENOPROTOOPT:      Result:='ENOPROTOOPT';
  EPROTONOSUPPORT:  Result:='EPROTONOSUPPORT';
  ESOCKTNOSUPPORT:  Result:='ESOCKTNOSUPPORT';
  EOPNOTSUPP:       Result:='EOPNOTSUPP';
  EPFNOSUPPORT:     Result:='EPFNOSUPPORT';
  EAFNOSUPPORT:     Result:='EAFNOSUPPORT';
  EADDRINUSE:       Result:='EADDRINUSE';
  EADDRNOTAVAIL:    Result:='EADDRNOTAVAIL';
  ENETDOWN:         Result:='ENETDOWN';
  ENETUNREACH:      Result:='ENETUNREACH';
  ENETRESET:        Result:='ENETRESET';
  ECONNABORTED:     Result:='ECONNABORTED';
  ECONNRESET:       Result:='ECONNRESET';
  ENOBUFS:          Result:='ENOBUFS';
  EISCONN:          Result:='EISCONN';
  ENOTCONN:         Result:='ENOTCONN';
  ESHUTDOWN:        Result:='ESHUTDOWN';
  ETOOMANYREFS:     Result:='ETOOMANYREFS';
  ETIMEDOUT:        Result:='ETIMEDOUT';
  ECONNREFUSED:     Result:='ECONNREFUSED';
  EHOSTDOWN:        Result:='EHOSTDOWN';
  EHOSTUNREACH:     Result:='EHOSTUNREACH';
  EALREADY:         Result:='EALREADY';
  EINPROGRESS:      Result:='EINPROGRESS';
  ESTALE:           Result:='ESTALE';
  EUCLEAN:          Result:='EUCLEAN';
  ENOTNAM:          Result:='ENOTNAM';
  ENAVAIL:          Result:='ENAVAIL';
  EISNAM:           Result:='EISNAM';
  EREMOTEIO:        Result:='EREMOTEIO';
  EDQUOT:           Result:='EDQUOT';
  ENOMEDIUM:        Result:='ENOMEDIUM';
  EMEDIUMTYPE:      Result:='EMEDIUMTYPE';
  ECANCELED:        Result:='ECANCELED';
  ENOKEY:           Result:='ENOKEY';
  EKEYEXPIRED:      Result:='EKEYEXPIRED';
  EKEYREVOKED:      Result:='EKEYREVOKED';
  EKEYREJECTED:     Result:='EKEYREJECTED';
  EOWNERDEAD:       Result:='EOWNERDEAD';
  ENOTRECOVERABLE:  Result:='ENOTRECOVERABLE';
  ERFKILL:          Result:='ERFKILL';
  EHWPOISON:        Result:='EHWPOISON';
//ENOTSUP:          Result:='ENOTSUP';
 end;
end;

function ErrnoToComment(n:Integer; Def:LongString=''):LongString;
begin
 Result:=Def;
 case n of
  EFAIL           : Result:='Operation failed';
  EOK             : Result:='Success';
  EPERM           : Result:='Operation not permitted';
  ENOENT          : Result:='No such file or directory';
  ESRCH           : Result:='No such process';
  EINTR           : Result:='Interrupted system call';
  EIO             : Result:='Input/output error';
  ENXIO           : Result:='No such device or address';
  E2BIG           : Result:='Argument list too long';
  ENOEXEC         : Result:='Exec format error';
  EBADF           : Result:='Bad file descriptor';
  ECHILD          : Result:='No child processes';
  EAGAIN          : Result:='Resource temporarily unavailable';
  ENOMEM          : Result:='Cannot allocate memory';
  EACCES          : Result:='Permission denied';
  EFAULT          : Result:='Bad address';
  ENOTBLK         : Result:='Block device required';
  EBUSY           : Result:='Device or resource busy';
  EEXIST          : Result:='File exists';
  EXDEV           : Result:='Invalid cross-device link';
  ENODEV          : Result:='No such device';
  ENOTDIR         : Result:='Not a directory';
  EISDIR          : Result:='Is a directory';
  EINVAL          : Result:='Invalid argument';
  ENFILE          : Result:='Too many open files in system';
  EMFILE          : Result:='Too many open files';
  ENOTTY          : Result:='Inappropriate ioctl for device';
  ETXTBSY         : Result:='Text file busy';
  EFBIG           : Result:='File too large';
  ENOSPC          : Result:='No space left on device';
  ESPIPE          : Result:='Illegal seek';
  EROFS           : Result:='Read-only file system';
  EMLINK          : Result:='Too many links';
  EPIPE           : Result:='Broken pipe';
  EDOM            : Result:='Numerical argument out of domain';
  ERANGE          : Result:='Numerical result out of range';
  EDEADLK         : Result:='Resource deadlock avoided';
  ENAMETOOLONG    : Result:='File name too long';
  ENOLCK          : Result:='No locks available';
  ENOSYS          : Result:='Function not implemented';
  ENOTEMPTY       : Result:='Directory not empty';
  ELOOP           : Result:='Too many levels of symbolic links';
//EWOULDBLOCK     : Result:='Resource temporarily unavailable';
  ENOMSG          : Result:='No message of desired type';
  EIDRM           : Result:='Identifier removed';
  ECHRNG          : Result:='Channel number out of range';
  EL2NSYNC        : Result:='Level 2 not synchronized';
  EL3HLT          : Result:='Level 3 halted';
  EL3RST          : Result:='Level 3 reset';
  ELNRNG          : Result:='Link number out of range';
  EUNATCH         : Result:='Protocol driver not attached';
  ENOCSI          : Result:='No CSI structure available';
  EL2HLT          : Result:='Level 2 halted';
  EBADE           : Result:='Invalid exchange';
  EBADR           : Result:='Invalid request descriptor';
  EXFULL          : Result:='Exchange full';
  ENOANO          : Result:='No anode';
  EBADRQC         : Result:='Invalid request code';
  EBADSLT         : Result:='Invalid slot';
//EDEADLOCK       : Result:='Resource deadlock avoided';
  EBFONT          : Result:='Bad font file format';
  ENOSTR          : Result:='Device not a stream';
  ENODATA         : Result:='No data available';
  ETIME           : Result:='Timer expired';
  ENOSR           : Result:='Out of streams resources';
  ENONET          : Result:='Machine is not on the network';
  ENOPKG          : Result:='Package not installed';
  EREMOTE         : Result:='Object is remote';
  ENOLINK         : Result:='Link has been severed';
  EADV            : Result:='Advertise error';
  ESRMNT          : Result:='Srmount error';
  ECOMM           : Result:='Communication error on send';
  EPROTO          : Result:='Protocol error';
  EMULTIHOP       : Result:='Multihop attempted';
  EDOTDOT         : Result:='RFS specific error';
  EBADMSG         : Result:='Bad message';
  EOVERFLOW       : Result:='Value too large for defined data type';
  ENOTUNIQ        : Result:='Name not unique on network';
  EBADFD          : Result:='File descriptor in bad state';
  EREMCHG         : Result:='Remote address changed';
  ELIBACC         : Result:='Can not access a needed shared library';
  ELIBBAD         : Result:='Accessing a corrupted shared library';
  ELIBSCN         : Result:='.lib section in a.out corrupted';
  ELIBMAX         : Result:='Attempting to link in too many shared libraries';
  ELIBEXEC        : Result:='Cannot exec a shared library directly';
  EILSEQ          : Result:='Invalid or incomplete multibyte or wide character';
  ERESTART        : Result:='Interrupted system call should be restarted';
  ESTRPIPE        : Result:='Streams pipe error';
  EUSERS          : Result:='Too many users';
  ENOTSOCK        : Result:='Socket operation on non-socket';
  EDESTADDRREQ    : Result:='Destination address required';
  EMSGSIZE        : Result:='Message too long';
  EPROTOTYPE      : Result:='Protocol wrong type for socket';
  ENOPROTOOPT     : Result:='Protocol not available';
  EPROTONOSUPPORT : Result:='Protocol not supported';
  ESOCKTNOSUPPORT : Result:='Socket type not supported';
  EOPNOTSUPP      : Result:='Operation not supported';
  EPFNOSUPPORT    : Result:='Protocol family not supported';
  EAFNOSUPPORT    : Result:='Address family not supported by protocol';
  EADDRINUSE      : Result:='Address already in use';
  EADDRNOTAVAIL   : Result:='Cannot assign requested address';
  ENETDOWN        : Result:='Network is down';
  ENETUNREACH     : Result:='Network is unreachable';
  ENETRESET       : Result:='Network dropped connection on reset';
  ECONNABORTED    : Result:='Software caused connection abort';
  ECONNRESET      : Result:='Connection reset by peer';
  ENOBUFS         : Result:='No buffer space available';
  EISCONN         : Result:='Transport endpoint is already connected';
  ENOTCONN        : Result:='Transport endpoint is not connected';
  ESHUTDOWN       : Result:='Cannot send after transport endpoint shutdown';
  ETOOMANYREFS    : Result:='Too many references: cannot splice';
  ETIMEDOUT       : Result:='Connection timed out';
  ECONNREFUSED    : Result:='Connection refused';
  EHOSTDOWN       : Result:='Host is down';
  EHOSTUNREACH    : Result:='No route to host';
  EALREADY        : Result:='Operation already in progress';
  EINPROGRESS     : Result:='Operation now in progress';
  ESTALE          : Result:='Stale file handle';
  EUCLEAN         : Result:='Structure needs cleaning';
  ENOTNAM         : Result:='Not a XENIX named type file';
  ENAVAIL         : Result:='No XENIX semaphores available';
  EISNAM          : Result:='Is a named type file';
  EREMOTEIO       : Result:='Remote I/O error';
  EDQUOT          : Result:='Disk quota exceeded';
  ENOMEDIUM       : Result:='No medium found';
  EMEDIUMTYPE     : Result:='Wrong medium type';
  ECANCELED       : Result:='Operation canceled';
  ENOKEY          : Result:='Required key not available';
  EKEYEXPIRED     : Result:='Key has expired';
  EKEYREVOKED     : Result:='Key has been revoked';
  EKEYREJECTED    : Result:='Key was rejected by service';
  EOWNERDEAD      : Result:='Owner died';
  ENOTRECOVERABLE : Result:='State not recoverable';
  ERFKILL         : Result:='Operation not possible due to RF-kill';
  EHWPOISON       : Result:='Memory page has hardware error';
//ENOTSUP         : Result:='Operation not supported';
 end;
end;

function StringToErrno(const S:LongString; Def:Integer=-1):Integer;
begin
 Result:=Def;
 case Identify(S) of
  sid_EFAIL:            Result:=EFAIL;
  sid_EOK:              Result:=EOK;
  sid_EPERM:            Result:=EPERM;
  sid_ENOENT:           Result:=ENOENT;
  sid_ESRCH:            Result:=ESRCH;
  sid_EINTR:            Result:=EINTR;
  sid_EIO:              Result:=EIO;
  sid_ENXIO:            Result:=ENXIO;
  sid_E2BIG:            Result:=E2BIG;
  sid_ENOEXEC:          Result:=ENOEXEC;
  sid_EBADF:            Result:=EBADF;
  sid_ECHILD:           Result:=ECHILD;
  sid_EAGAIN:           Result:=EAGAIN;
  sid_ENOMEM:           Result:=ENOMEM;
  sid_EACCES:           Result:=EACCES;
  sid_EFAULT:           Result:=EFAULT;
  sid_ENOTBLK:          Result:=ENOTBLK;
  sid_EBUSY:            Result:=EBUSY;
  sid_EEXIST:           Result:=EEXIST;
  sid_EXDEV:            Result:=EXDEV;
  sid_ENODEV:           Result:=ENODEV;
  sid_ENOTDIR:          Result:=ENOTDIR;
  sid_EISDIR:           Result:=EISDIR;
  sid_EINVAL:           Result:=EINVAL;
  sid_ENFILE:           Result:=ENFILE;
  sid_EMFILE:           Result:=EMFILE;
  sid_ENOTTY:           Result:=ENOTTY;
  sid_ETXTBSY:          Result:=ETXTBSY;
  sid_EFBIG:            Result:=EFBIG;
  sid_ENOSPC:           Result:=ENOSPC;
  sid_ESPIPE:           Result:=ESPIPE;
  sid_EROFS:            Result:=EROFS;
  sid_EMLINK:           Result:=EMLINK;
  sid_EPIPE:            Result:=EPIPE;
  sid_EDOM:             Result:=EDOM;
  sid_ERANGE:           Result:=ERANGE;
  sid_EDEADLK:          Result:=EDEADLK;
  sid_ENAMETOOLONG:     Result:=ENAMETOOLONG;
  sid_ENOLCK:           Result:=ENOLCK;
  sid_ENOSYS:           Result:=ENOSYS;
  sid_ENOTEMPTY:        Result:=ENOTEMPTY;
  sid_ELOOP:            Result:=ELOOP;
  sid_EWOULDBLOCK:      Result:=EWOULDBLOCK;
  sid_ENOMSG:           Result:=ENOMSG;
  sid_EIDRM:            Result:=EIDRM;
  sid_ECHRNG:           Result:=ECHRNG;
  sid_EL2NSYNC:         Result:=EL2NSYNC;
  sid_EL3HLT:           Result:=EL3HLT;
  sid_EL3RST:           Result:=EL3RST;
  sid_ELNRNG:           Result:=ELNRNG;
  sid_EUNATCH:          Result:=EUNATCH;
  sid_ENOCSI:           Result:=ENOCSI;
  sid_EL2HLT:           Result:=EL2HLT;
  sid_EBADE:            Result:=EBADE;
  sid_EBADR:            Result:=EBADR;
  sid_EXFULL:           Result:=EXFULL;
  sid_ENOANO:           Result:=ENOANO;
  sid_EBADRQC:          Result:=EBADRQC;
  sid_EBADSLT:          Result:=EBADSLT;
  sid_EDEADLOCK:        Result:=EDEADLOCK;
  sid_EBFONT:           Result:=EBFONT;
  sid_ENOSTR:           Result:=ENOSTR;
  sid_ENODATA:          Result:=ENODATA;
  sid_ETIME:            Result:=ETIME;
  sid_ENOSR:            Result:=ENOSR;
  sid_ENONET:           Result:=ENONET;
  sid_ENOPKG:           Result:=ENOPKG;
  sid_EREMOTE:          Result:=EREMOTE;
  sid_ENOLINK:          Result:=ENOLINK;
  sid_EADV:             Result:=EADV;
  sid_ESRMNT:           Result:=ESRMNT;
  sid_ECOMM:            Result:=ECOMM;
  sid_EPROTO:           Result:=EPROTO;
  sid_EMULTIHOP:        Result:=EMULTIHOP;
  sid_EDOTDOT:          Result:=EDOTDOT;
  sid_EBADMSG:          Result:=EBADMSG;
  sid_EOVERFLOW:        Result:=EOVERFLOW;
  sid_ENOTUNIQ:         Result:=ENOTUNIQ;
  sid_EBADFD:           Result:=EBADFD;
  sid_EREMCHG:          Result:=EREMCHG;
  sid_ELIBACC:          Result:=ELIBACC;
  sid_ELIBBAD:          Result:=ELIBBAD;
  sid_ELIBSCN:          Result:=ELIBSCN;
  sid_ELIBMAX:          Result:=ELIBMAX;
  sid_ELIBEXEC:         Result:=ELIBEXEC;
  sid_EILSEQ:           Result:=EILSEQ;
  sid_ERESTART:         Result:=ERESTART;
  sid_ESTRPIPE:         Result:=ESTRPIPE;
  sid_EUSERS:           Result:=EUSERS;
  sid_ENOTSOCK:         Result:=ENOTSOCK;
  sid_EDESTADDRREQ:     Result:=EDESTADDRREQ;
  sid_EMSGSIZE:         Result:=EMSGSIZE;
  sid_EPROTOTYPE:       Result:=EPROTOTYPE;
  sid_ENOPROTOOPT:      Result:=ENOPROTOOPT;
  sid_EPROTONOSUPPORT:  Result:=EPROTONOSUPPORT;
  sid_ESOCKTNOSUPPORT:  Result:=ESOCKTNOSUPPORT;
  sid_EOPNOTSUPP:       Result:=EOPNOTSUPP;
  sid_EPFNOSUPPORT:     Result:=EPFNOSUPPORT;
  sid_EAFNOSUPPORT:     Result:=EAFNOSUPPORT;
  sid_EADDRINUSE:       Result:=EADDRINUSE;
  sid_EADDRNOTAVAIL:    Result:=EADDRNOTAVAIL;
  sid_ENETDOWN:         Result:=ENETDOWN;
  sid_ENETUNREACH:      Result:=ENETUNREACH;
  sid_ENETRESET:        Result:=ENETRESET;
  sid_ECONNABORTED:     Result:=ECONNABORTED;
  sid_ECONNRESET:       Result:=ECONNRESET;
  sid_ENOBUFS:          Result:=ENOBUFS;
  sid_EISCONN:          Result:=EISCONN;
  sid_ENOTCONN:         Result:=ENOTCONN;
  sid_ESHUTDOWN:        Result:=ESHUTDOWN;
  sid_ETOOMANYREFS:     Result:=ETOOMANYREFS;
  sid_ETIMEDOUT:        Result:=ETIMEDOUT;
  sid_ECONNREFUSED:     Result:=ECONNREFUSED;
  sid_EHOSTDOWN:        Result:=EHOSTDOWN;
  sid_EHOSTUNREACH:     Result:=EHOSTUNREACH;
  sid_EALREADY:         Result:=EALREADY;
  sid_EINPROGRESS:      Result:=EINPROGRESS;
  sid_ESTALE:           Result:=ESTALE;
  sid_EUCLEAN:          Result:=EUCLEAN;
  sid_ENOTNAM:          Result:=ENOTNAM;
  sid_ENAVAIL:          Result:=ENAVAIL;
  sid_EISNAM:           Result:=EISNAM;
  sid_EREMOTEIO:        Result:=EREMOTEIO;
  sid_EDQUOT:           Result:=EDQUOT;
  sid_ENOMEDIUM:        Result:=ENOMEDIUM;
  sid_EMEDIUMTYPE:      Result:=EMEDIUMTYPE;
  sid_ECANCELED:        Result:=ECANCELED;
  sid_ENOKEY:           Result:=ENOKEY;
  sid_EKEYEXPIRED:      Result:=EKEYEXPIRED;
  sid_EKEYREVOKED:      Result:=EKEYREVOKED;
  sid_EKEYREJECTED:     Result:=EKEYREJECTED;
  sid_EOWNERDEAD:       Result:=EOWNERDEAD;
  sid_ENOTRECOVERABLE:  Result:=ENOTRECOVERABLE;
  sid_ERFKILL:          Result:=ERFKILL;
  sid_EHWPOISON:        Result:=EHWPOISON;
  sid_ENOTSUP:          Result:=ENOTSUP;
 end;
end;

function FormatErrno(n:Integer):LongString;
var s,c:LongString;
begin
 Result:=IntToStr(n);
 if InRange(n,Low(TErrnoCodes),High(TErrnoCodes)) then begin
  s:=ErrnoToString(n,'Unknown');
  c:=ErrnoToComment(n,'Unknown error');
  Result+=Format(' %s "%s"',[s,c]);
 end;
end;

function ErrnoSelfTest:Boolean;
const nw=High(TErrnoCodes)-Low(TErrnoCodes)+1-2; // errno (41,58) is reserved
var wc:Integer;
begin
 if (ErrnoToString(EAGAIN)<>'EAGAIN') then Exit(False);
 if (StringToErrno('EAGAIN')<>EAGAIN) then Exit(False);
 if (ErrnoToComment(EOK)<>'Success') then Exit(False);
 wc:=WordCount(ErrnoNames,ScanSpaces);
 Result:=(wc=nw);
end;

const
 TheErrnoNames:LongString='';

function ErrnoNames(const Delim:LongString=EOL):LongString;
var n:Integer; s:LongString; Lines:TStringList;
begin
 if (TheErrnoNames='') then begin
  Lines:=TStringList.Create;
  try
   for n:=Low(TErrnoCodes) to High(TErrnoCodes) do begin
    s:=ErrnoToString(n); if (s='') then continue;
    Lines.Add(s);
   end;
   TheErrnoNames:=Lines.Text;
  finally
   Kill(Lines);
  end;
 end;
 Result:=TheErrnoNames;
 if (Delim<>EOL) and (Delim<>'')
 then Result:=StringReplace(Trim(Result),EOL,Delim,[rfReplaceAll]);
end;

const
 TheErrnoNamesValues:LongString='';

function ErrnoNamesValues(const Delim:LongString=EOL):LongString;
var n:Integer; s:LongString; Lines:TStringList;
begin
 if (TheErrnoNamesValues='') then begin
  Lines:=TStringList.Create;
  try
   for n:=Low(TErrnoCodes) to High(TErrnoCodes) do begin
    s:=ErrnoToString(n); if (s='') then continue;
    Lines.Add(s+'='+IntToStr(n));
   end;
   TheErrnoNamesValues:=Lines.Text;
  finally
   Kill(Lines);
  end;
 end;
 Result:=TheErrnoNamesValues;
 if (Delim<>EOL) and (Delim<>'')
 then Result:=StringReplace(Trim(Result),EOL,Delim,[rfReplaceAll]);
end;

procedure InitErrnoNames;
begin
 ErrnoNames;
 ErrnoNamesValues;
end;

procedure FreeErrnoNames;
begin
 TheErrnoNames:='';
 TheErrnoNamesValues:='';
end;

///////////////////////////////////////
// Unit initialization and finalization
///////////////////////////////////////

procedure Init_crw_errno;
begin
 InitDictionary;
 InitErrnoNames;
end;

procedure Free_crw_errno;
begin
 FreeDictionary;
 FreeErrnoNames;
end;

initialization

 Init_crw_errno;

finalization

 Free_crw_errno;

end.

//////////////
// END OF FILE
//////////////

