(*
    Tux Commander - ULibc - translated glibc functions for all platforms
    Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
    Check for updates on tuxcmd.sourceforge.net

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*)
unit ULibc;

interface

{$IFDEF FPC}
  {$PACKRECORDS C}
{$ENDIF}

const GLIBC_LIB = 'libc.so.6';
      DL_LIB = 'libdl.so.2';
      PTHREAD_LIB = 'libpthread.so.0';

type
{$IFDEF KYLIX}
   DWORD = Cardinal;
   QWORD = Int64;
   LongWord = LongInt;
{$ENDIF}

   cUShort = Word;
   cInt = LongInt;
   cuInt = LongWord;
   cLongLong = Int64;
   cuLongLong = QWord;
   cuChar = Byte;
{$IFDEF CPU64}
   cLong = Int64;
   cuLong = QWord;
{$ELSE}
   cLong = Longint;
   cuLong = Cardinal;
{$ENDIF}


   sig_atomic_t = Longint;
   size_t = Cardinal;
   ssize_t = Longint;
   error_t = Integer;
   __mode_t = DWORD;
   __dev_t = QWORD;
   __pid_t = Longint;
   __id_t = DWORD;
   __uid_t = DWORD;
   __gid_t = DWORD;
   __off64_t = Int64;
   __off_t = Longint;
   __ino_t = DWORD;
   __ino64_t = QWORD;
   __nlink_t = DWORD;
   __blksize_t = Longint;
   __blkcnt_t = Longint;
   __blkcnt64_t = Int64;


   Pidtype_t = ^idtype_t;
   idtype_t =  (P_ALL,P_PID,P_PGID);

   Psiginfo_t = Pointer;
   Prusage = Pointer;
   PDIR = Pointer;
   PFILE = Pointer;
   Pfpos_t = Pointer;
   Pfpos64_t = Pointer;

   Ttimespec = packed record
{$IFNDEF CPU64}   //  32-bit platform
     tv_sec: longint;
     tv_nsec: longint;
{$ELSE}           //  64-bit platform
     tv_sec: Int64;
     tv_nsec: Int64;
{$ENDIF}
   end;

   Ptm = ^tm;
   tm = record
        tm_sec : longint;
        tm_min : longint;
        tm_hour : longint;
        tm_mday : longint;
        tm_mon : longint;
        tm_year : longint;
        tm_wday : longint;
        tm_yday : longint;
        tm_isdst : longint;
        case boolean of
         false : (tm_gmtoff : longint;tm_zone : Pchar);
         true  : (__tm_gmtoff : longint;__tm_zone : Pchar);
        end;

   Pdirent64 = ^Tdirent64;
   Tdirent64 = packed record
        d_ino : QWORD;
        d_off : Int64;
        d_reclen : word;
        d_type : byte;
        d_name : array[0..255] of char;
     end;

   Pstat64 = ^Tstat64;
   Tstat64 = record
{$IFNDEF CPU64}
{$IFNDEF CPUPOWERPC}  //  i386
        st_dev: cuLongLong;
        __pad0_: array[0..3] of cuChar;
        __st_ino: cuLong;
        st_mode: cuInt;
        st_nlink: cuInt;
        st_uid: cuLong;
        st_gid: cuLong;
        st_rdev: cuLongLong;
        __pad3_: array[0..3] of cuChar;
        st_size: cLongLong;
        st_blksize: cuLong;
        st_blocks: cuLongLong;	//* Number 512-byte blocks allocated. */
        st_atime: cuLong;
        st_atime_nsec: cuLong;
        st_mtime: cuLong;
        st_mtime_nsec: cuInt;
        st_ctime: cuLong;
        st_ctime_nsec: cuLong;
        st_ino: cuLongLong
{$ELSE}           //  PPC32
        st_dev     : cULongLong;
        st_ino     : cULongLong;
        st_mode    : cUInt;
        st_nlink   : cUInt;
        st_uid     : cUInt;
        st_gid     : cUInt;
        st_rdev    : cULongLong;
        __pad2     : cUShort;
        st_size    : cLongLong;
        st_blksize : cInt;
        st_blocks  : cULongLong;
        st_atime,
        st_atime_nsec,
        st_mtime,
        st_mtime_nsec,
        st_ctime,
        st_ctime_nsec,
        __unused4,
        __unused5  : cULong;
{$ENDIF}
{$ELSE}
{$IFNDEF CPUPOWERPC}  //  x86_64
        st_dev: cuLong;
        st_ino: cuLong;
        st_nlink: cuLong;
        st_mode: cuInt;
        st_uid: cuInt;
        st_gid: cuInt;
        __pad1: cuInt;
        st_rdev: cuLong;
        st_size: cLong;
        st_blksize: cLong;
        st_blocks: cLong;	//* Number 512-byte blocks allocated. */
        st_atime: cuLong;
        st_atime_nsec: cuLong;
        st_mtime: cuLong;
        st_mtime_nsec: cuLong;
        st_ctime: cuLong;
        st_ctime_nsec: cuLong;
        __unused2: array[0..2] of cLong;
{$ELSE}         //  PPC64
        st_dev     : cuLong;
        st_ino     : cuLong;     { wrongly defined in RTL? }
        st_nlink   : cuLong;     { wrongly defined in RTL? }
        st_mode    : cuInt;
        st_uid     : cuInt;
        st_gid     : cuInt;
        st_rdev    : cULong;
        st_size    : cLong;
        st_blksize : cULong;
        st_blocks  : cULong;     { Number 512-byte blocks allocated. }
        st_atime : cULong;
        st_atime_nsec : cULong;
        st_mtime : cULong;
        st_mtime_nsec : cULong;
        st_ctime : cULong;
        st_ctime_nsec : cULong;
        __unused : array[0..2] of cULong;
{$ENDIF}
{$ENDIF}
     end;


   fsid_t = packed record
     __val : array[0..1] of longint;
   end;

   Pstatfs64 = ^Tstatfs64;
   Tstatfs64 = packed record
{$IFNDEF CPU64}   //  32-bit platform
        f_type : longint;
        f_bsize : longint;
        f_blocks : QWORD;
        f_bfree : QWORD;
        f_bavail : QWORD;
        f_files : QWORD;
        f_ffree : QWORD;
        f_fsid : fsid_t;
        f_namelen : longint;
        f_spare : array[0..5] of longint;
{$ELSE}           //  64-bit platform
        f_type : Int64;
        f_bsize : Int64;
        f_blocks : QWORD;
        f_bfree : QWORD;
        f_bavail : QWORD;
        f_files : QWORD;
        f_ffree : QWORD;
        f_fsid : fsid_t;
        f_namelen : Int64;
        f_spare : array[0..5] of Int64;
{$ENDIF}
     end;

{$IFNDEF CPU64}
   time_t = longint;
{$ELSE}
   time_t = Int64;
{$ENDIF}
   Ptime_t = ^time_t;

   Putimbuf = ^Tutimbuf;
   Tutimbuf = record
        actime : time_t;
        modtime : time_t;
   end;
   
   Pmntent = ^Tmntent;
   Tmntent = record
        mnt_fsname : PChar;
        mnt_dir : PChar;
        mnt_type : PChar;
        mnt_opts : PChar;
        mnt_freq : Longint;
        mnt_passno : Longint;
     end;

   PPasswd = ^TPasswd;
   TPasswd = record
        pw_name : PChar;
        pw_passwd : PChar;
        pw_uid : __uid_t;
        pw_gid : __gid_t;
        pw_gecos : PChar;
        pw_dir : PChar;
        pw_shell : PChar;
     end;
   PPPasswd = ^PPasswd;

   PGroup = ^TGroup;
   TGroup = record
        gr_name : PChar;
        gr_passwd : PChar;
        gr_gid : __gid_t;
        gr_mem : ^PChar;
     end;
   PPGroup = ^PGroup;

   Psigval = ^sigval;
   sigval = record
       case longint of
          0 : ( sival_int : longint );
          1 : ( sival_ptr : pointer );
       end;
   sigval_t = sigval;
   Psigval_t = ^sigval_t;

const
   _SIGSET_NWORDS = 1024 div (8 * (sizeof(dword)));

type
   __sighandler_t = procedure(SigNum: Integer); cdecl;
   P__sigset_t = ^__sigset_t;
   __sigset_t = record
         __val : array[0..(_SIGSET_NWORDS)-1] of dword;
      end;
   sigset_t = __sigset_t;
   Psigset_t = ^sigset_t;
   P_sigaction = ^_sigaction;
   _sigaction = record // Renamed, avoid conflict with sigaction function
     case integer of
       1: (sa_handler : __sighandler_t;
           sa_mask : __sigset_t;
           sa_flags : longint;
           sa_restorer : procedure ;cdecl;
          );
       // Kylix compatibility
       2: (__sigaction_handler: __sighandler_t);
   end;
   TSigAction = _sigaction;
   PSigAction = ^TSigAction;
   TRestoreHandler = procedure; cdecl;
    __sigaction = _sigaction;
   TSigActionHandler = procedure(Signal: Integer); cdecl;

const
   EPERM = 1;
   ENOENT = 2;
   ESRCH = 3;
   EINTR = 4;
   EIO = 5;
   ENXIO = 6;
   E2BIG = 7;
   ENOEXEC = 8;
   EBADF = 9;
   ECHILD = 10;
   EAGAIN = 11;
   ENOMEM = 12;
   EACCES = 13;
   EFAULT = 14;
   ENOTBLK = 15;
   EBUSY = 16;
   EEXIST = 17;
   EXDEV = 18;
   ENODEV = 19;
   ENOTDIR = 20;
   EISDIR = 21;
   EINVAL = 22;
   ENFILE = 23;
   EMFILE = 24;
   ENOTTY = 25;
   ETXTBSY = 26;
   EFBIG = 27;
   ENOSPC = 28;
   ESPIPE = 29;
   EROFS = 30;
   EMLINK = 31;
   EPIPE = 32;
   EDOM = 33;
   ERANGE = 34;
   EDEADLK = 35;
   ENAMETOOLONG = 36;
   ENOLCK = 37;
   ENOSYS = 38;
   ENOTEMPTY = 39;
   ELOOP = 40;
   EWOULDBLOCK = EAGAIN;
   ENOMSG = 42;
   EIDRM = 43;
   ECHRNG = 44;
   EL2NSYNC = 45;
   EL3HLT = 46;
   EL3RST = 47;
   ELNRNG = 48;
   EUNATCH = 49;
   ENOCSI = 50;
   EL2HLT = 51;
   EBADE = 52;
   EBADR = 53;
   EXFULL = 54;
   ENOANO = 55;
   EBADRQC = 56;
   EBADSLT = 57;
   EDEADLOCK = EDEADLK;
   EBFONT = 59;
   ENOSTR = 60;
   ENODATA = 61;
   ETIME = 62;
   ENOSR = 63;
   ENONET = 64;
   ENOPKG = 65;
   EREMOTE = 66;
   ENOLINK = 67;
   EADV = 68;
   ESRMNT = 69;
   ECOMM = 70;
   EPROTO = 71;
   EMULTIHOP = 72;
   EDOTDOT = 73;
   EBADMSG = 74;
   EOVERFLOW = 75;
   ENOTUNIQ = 76;
   EBADFD = 77;
   EREMCHG = 78;
   ELIBACC = 79;
   ELIBBAD = 80;
   ELIBSCN = 81;
   ELIBMAX = 82;
   ELIBEXEC = 83;
   EILSEQ = 84;
   ERESTART = 85;
   ESTRPIPE = 86;
   EUSERS = 87;
   ENOTSOCK = 88;
   EDESTADDRREQ = 89;
   EMSGSIZE = 90;
   EPROTOTYPE = 91;
   ENOPROTOOPT = 92;
   EPROTONOSUPPORT = 93;
   ESOCKTNOSUPPORT = 94;
   EOPNOTSUPP = 95;
   EPFNOSUPPORT = 96;
   EAFNOSUPPORT = 97;
   EADDRINUSE = 98;
   EADDRNOTAVAIL = 99;
   ENETDOWN = 100;
   ENETUNREACH = 101;
   ENETRESET = 102;
   ECONNABORTED = 103;
   ECONNRESET = 104;
   ENOBUFS = 105;
   EISCONN = 106;
   ENOTCONN = 107;
   ESHUTDOWN = 108;
   ETOOMANYREFS = 109;
   ETIMEDOUT = 110;
   ECONNREFUSED = 111;
   EHOSTDOWN = 112;
   EHOSTUNREACH = 113;
   EALREADY = 114;
   EINPROGRESS = 115;
   ESTALE = 116;
   EUCLEAN = 117;
   ENOTNAM = 118;
   ENAVAIL = 119;
   EISNAM = 120;
   EREMOTEIO = 121;
   EDQUOT = 122;
   ENOMEDIUM = 123;
   EMEDIUMTYPE = 124;
   ENOTSUP = EOPNOTSUPP;
   ECANCELED = 125;

const
   __S_IFMT        = $F000;
   __S_IFDIR       = $4000;
   __S_IFCHR       = $2000;
   __S_IFBLK       = $6000;
   __S_IFREG       = $8000;
   __S_IFIFO       = $1000;
   __S_IFLNK       = $A000;
   __S_IFSOCK      = $C000;

   __S_ISUID       = $800;
   __S_ISGID       = $400;
   __S_ISVTX       = $200;
   __S_IREAD       = $100;
   __S_IWRITE      = $80;
   __S_IEXEC       = $40;

   S_IFMT   = __S_IFMT;
   S_IFDIR  = __S_IFDIR;
   S_IFCHR  = __S_IFCHR;
   S_IFBLK  = __S_IFBLK;
   S_IFREG  = __S_IFREG;
   S_IFIFO  = __S_IFIFO;
   S_IFLNK  = __S_IFLNK;
   S_IFSOCK = __S_IFSOCK;

function __S_ISTYPE(mode, mask : __mode_t) : boolean;
function S_ISDIR(mode : __mode_t) : boolean;
function S_ISCHR(mode : __mode_t) : boolean;
function S_ISBLK(mode : __mode_t) : boolean;
function S_ISREG(mode : __mode_t) : boolean;
function S_ISFIFO(mode : __mode_t) : boolean;
function S_ISLNK(mode : __mode_t) : boolean;
function S_ISSOCK(mode : __mode_t) : boolean;

const
  S_ISUID = __S_ISUID;
  S_ISGID = __S_ISGID;
  S_ISVTX = __S_ISVTX;

  S_IRUSR = __S_IREAD;
  S_IWUSR = __S_IWRITE;
  S_IXUSR = __S_IEXEC;
  S_IRWXU = (__S_IREAD or __S_IWRITE) or __S_IEXEC;

  S_IREAD = S_IRUSR;
  S_IWRITE = S_IWUSR;
  S_IEXEC = S_IXUSR;

  S_IRGRP = S_IRUSR shr 3;
  S_IWGRP = S_IWUSR shr 3;
  S_IXGRP = S_IXUSR shr 3;
  S_IRWXG = S_IRWXU shr 3;
  S_IROTH = S_IRGRP shr 3;
  S_IWOTH = S_IWGRP shr 3;
  S_IXOTH = S_IXGRP shr 3;
  S_IRWXO = S_IRWXG shr 3;

const
  ACCESSPERMS = (S_IRWXU or S_IRWXG) or S_IRWXO;
  ALLPERMS = ((((S_ISUID or S_ISGID) or S_ISVTX) or S_IRWXU) or S_IRWXG) or S_IRWXO;
  DEFFILEMODE = ((((S_IRUSR or S_IWUSR) or S_IRGRP) or S_IWGRP) or S_IROTH) or S_IWOTH;
  S_BLKSIZE = 512;

const
  DT_UNKNOWN = 0;
  DT_FIFO = 1;
  DT_CHR = 2;
  DT_DIR = 4;
  DT_BLK = 6;
  DT_REG = 8;
  DT_LNK = 10;
  DT_SOCK = 12;
  DT_WHT = 14;

const
  RTLD_LAZY = $00001;
  RTLD_NOW = $00002;
  RTLD_BINDING_MASK = $3;
  RTLD_NOLOAD = $00004;
  RTLD_GLOBAL = $00100;
  RTLD_LOCAL = 0;
  RTLD_NODELETE = $01000;

const
  _PATH_DEFPATH = '/usr/bin:/bin';
  _PATH_STDPATH = '/usr/bin:/bin:/usr/sbin:/sbin';
  _PATH_BSHELL     = '/bin/sh';
  _PATH_CONSOLE = '/dev/console';
  _PATH_CSHELL = '/bin/csh';
  _PATH_DEVDB = '/var/run/dev.db';
  _PATH_DEVNULL = '/dev/null';
  _PATH_DRUM = '/dev/drum';
  _PATH_KLOG = '/proc/kmsg';
  _PATH_KMEM = '/dev/kmem';
  _PATH_LASTLOG = '/var/log/lastlog';
  _PATH_MAILDIR = '/var/mail';
  _PATH_MAN = '/usr/share/man';
  _PATH_MEM = '/dev/mem';
  _PATH_MNTTAB = '/etc/fstab';
  _PATH_MOUNTED = '/etc/mtab';
  _PATH_NOLOGIN = '/etc/nologin';
  _PATH_PRESERVE = '/var/lib';
  _PATH_RWHODIR = '/var/spool/rwho';
  _PATH_SENDMAIL = '/usr/sbin/sendmail';
  _PATH_SHADOW = '/etc/shadow';
  _PATH_SHELLS = '/etc/shells';
  _PATH_TTY = '/dev/tty';
  _PATH_UNIX = '/boot/vmlinux';
  _PATH_UTMP = '/var/run/utmp';
  _PATH_VI = '/usr/bin/vi';
  _PATH_WTMP = '/var/log/wtmp';
  _PATH_DEV = '/dev/';
  _PATH_TMP = '/tmp/';
  _PATH_VARDB = '/var/db/';
  _PATH_VARRUN = '/var/run/';
  _PATH_VARTMP = '/var/tmp/';

const
  WCOREFLAG          = $80;

const
  SIG_ERR  = (-1);
  SIG_DFL  = (0);
  SIG_IGN  = (1);
  SIG_HOLD = (2);

const
   SIGHUP = 1;
   SIGINT = 2;
   SIGQUIT = 3;
   SIGILL = 4;
   SIGTRAP = 5;
   SIGABRT = 6;
   SIGIOT = 6;
   SIGBUS = 7;
   SIGFPE = 8;
   SIGKILL = 9;
   SIGUSR1 = 10;
   SIGSEGV = 11;
   SIGUSR2 = 12;
   SIGPIPE = 13;
   SIGALRM = 14;
   SIGTERM = 15;
   SIGSTKFLT = 16;
   SIGCHLD = 17;
   SIGCLD = SIGCHLD;
   SIGCONT = 18;
   SIGSTOP = 19;
   SIGTSTP = 20;
   SIGTTIN = 21;
   SIGTTOU = 22;
   SIGURG = 23;
   SIGXCPU = 24;
   SIGXFSZ = 25;
   SIGVTALRM = 26;
   SIGPROF = 27;
   SIGWINCH = 28;
   SIGIO = 29;
   SIGPOLL = SIGIO;
   SIGPWR = 30;
   SIGSYS = 31;
   SIGUNUSED = 31;
   _NSIG = 64;

const
   WNOHANG = 1;
   WUNTRACED = 2;
   __WALL = $40000000;
   __WCLONE = $80000000;

const
   STDIN_FILENO = 0;
   STDOUT_FILENO = 1;
   STDERR_FILENO = 2;

const
   R_OK = 4;
   W_OK = 2;
   X_OK = 1;
   F_OK = 0;

const
   SEEK_SET = 0;
   SEEK_CUR = 1;
   SEEK_END = 2;

const
   _STAT_VER_LINUX_OLD = 1;
   _STAT_VER_KERNEL = 1;
   _STAT_VER_SVR4 = 2;
   _STAT_VER_LINUX = 3;
   _STAT_VER = _STAT_VER_LINUX;

   _MKNOD_VER_LINUX = 1;
   _MKNOD_VER_SVR4 = 2;
   _MKNOD_VER = _MKNOD_VER_LINUX;

{$IFNDEF KYLIX}
function stat64(const afile: PChar; buf: Pstat64): longint; cdecl; external GLIBC_LIB name 'stat64';
function lstat64(const path: PChar; buf: Pstat64): longint; cdecl; external GLIBC_LIB name 'lstat64';
{$ELSE}
function stat64(const afile: PChar; buf: Pstat64): longint;
function lstat64(const path: PChar; buf: Pstat64): longint;
{$ENDIF}

function statfs64(const path: PChar; buf: Pstatfs64): longint; cdecl; external GLIBC_LIB name 'statfs64';

function chmod(const path: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'chmod';
function libc_chmod(const path: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'chmod';
function fchmod(fildes: Longint; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'fchmod';
function umask(mask: __mode_t): __mode_t; cdecl; external GLIBC_LIB name 'umask';
function getumask: __mode_t; cdecl; external GLIBC_LIB name 'getumask';
function chown(const path: PChar; owner: __uid_t; group: __gid_t): Longint; cdecl; external GLIBC_LIB name 'chown';
function libc_chown(const path: PChar; owner: __uid_t; group: __gid_t): Longint; cdecl; external GLIBC_LIB name 'chown';
function fchown(fd: Longint; owner: __uid_t; group: __gid_t): Longint; cdecl; external GLIBC_LIB name 'fchown';
function lchown(const path: PChar; owner: __uid_t; group:__gid_t): Longint; cdecl; external GLIBC_LIB name 'lchown';

function __mkdir(const pathname: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'mkdir';
function mkdir(const pathname: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'mkdir';
function libc_mkdir(const pathname: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'mkdir';
function mknod(const pathname: PChar; mode: __mode_t; dev: __dev_t): Longint; cdecl; external GLIBC_LIB name 'mknod';
function mkfifo(const pathname: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'mkfifo';

function fileno(stream: PFILE): integer; cdecl; external GLIBC_LIB name 'fileno';

function utime(const afile: Pchar; buf: Putimbuf): Longint; cdecl; external GLIBC_LIB name 'utime';

function setmntent(const afile: PChar; const mode: PChar): PFILE; cdecl; external GLIBC_LIB name 'setmntent';
function getmntent(stream: PFILE): Pmntent; cdecl; external GLIBC_LIB name 'getmntent';
function endmntent(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'endmntent';

function dlopen(const filename: PChar; flag: Longint): Pointer; cdecl; external DL_LIB name 'dlopen';
function dlclose(handle: Pointer): Longint; cdecl; external DL_LIB name 'dlclose';
function dlsym(handle: Pointer; const symbol: PChar): Pointer; cdecl; external DL_LIB name 'dlsym';
function dlerror: PChar; cdecl; external GLIBC_LIB name 'dlerror';

function real_libc_malloc(size: size_t): Pointer; cdecl; external GLIBC_LIB name 'malloc';
{$IFNDEF CPUPOWERPC}
function malloc(size: size_t): Pointer; cdecl; external GLIBC_LIB name 'malloc';
{$ELSE}
function malloc(size: size_t): Pointer;
{$ENDIF}
function calloc(nmemb: size_t; size: size_t): Pointer; cdecl; external GLIBC_LIB name 'calloc';
function realloc(ptr: Pointer; size: size_t): Pointer; cdecl; external GLIBC_LIB name 'realloc';

procedure real_libc_free(ptr: Pointer); cdecl; external GLIBC_LIB name 'free';
{$IFNDEF CPUPOWERPC}
procedure free(ptr: Pointer); cdecl; external GLIBC_LIB name 'free';
procedure libc_free(ptr: Pointer); cdecl; external GLIBC_LIB name 'free';
{$ELSE}
procedure free(ptr: Pointer);
procedure libc_free(ptr: Pointer);
{$ENDIF}
procedure cfree(ptr: Pointer); cdecl; external GLIBC_LIB name 'cfree';
function memalign(boundary: size_t; size: size_t): Pointer; cdecl; external GLIBC_LIB name 'memalign';
function valloc(size: size_t): Pointer; cdecl; external GLIBC_LIB name 'valloc';

function memcpy(dest: Pointer; src: Pointer; n: size_t): Pointer; cdecl; external GLIBC_LIB name 'memcpy';
function memmove(dest: Pointer; src: Pointer; n: size_t): Pointer; cdecl; external GLIBC_LIB name 'memmove';
function memccpy(dest: Pointer; src: Pointer; c: longint; n: size_t): Pointer; cdecl; external GLIBC_LIB name 'memccpy';
function memset(s: Pointer; c: Longint; n: size_t): Pointer; cdecl; external GLIBC_LIB name 'memset';
function memcmp(s1: Pointer; s2: Pointer; n: size_t): Longint; cdecl; external GLIBC_LIB name 'memcmp';
function memchr(s: Pointer; c: Longint; n: size_t): Pointer; cdecl; external GLIBC_LIB name 'memchr';
function strcpy(dest: PChar; const src: PChar): PChar; cdecl; external GLIBC_LIB name 'strcpy';
function strncpy(dest: PChar; const src: PChar; n: size_t): PChar; cdecl; external GLIBC_LIB name 'strncpy';
function strcat(dest: PChar; const src: PChar): PChar; cdecl; external GLIBC_LIB name 'strcat';
function strncat(dest: PChar; const src: PChar; n: size_t): PChar; cdecl; external GLIBC_LIB name 'strncat';
function strcmp(const s1: PChar; const s2: PChar): Longint; cdecl; external GLIBC_LIB name 'strcmp';
function strncmp(const s1: PChar; const s2: PChar; n: size_t): Longint; cdecl; external GLIBC_LIB name 'strncmp';
function strcasecmp(const s1: PChar; const s2: PChar): Longint; cdecl; external GLIBC_LIB name 'strcasecmp';
function strncasecmp(const s1: PChar; const s2: PChar; n: size_t): Longint; cdecl; external GLIBC_LIB name 'strncasecmp';
{$IFNDEF CPUPOWERPC}
function strdup(const s: PChar): PChar; cdecl; external GLIBC_LIB name 'strdup';
function strndup(const s: PChar; n: size_t): PChar; cdecl; external GLIBC_LIB name 'strndup';
{$ELSE}
function strdup(const s: PChar): PChar;
function strndup(const s: PChar; n: size_t): PChar;
{$ENDIF}
function strchr(const s: PChar; c: Longint): PChar; cdecl; external GLIBC_LIB name 'strchr';
function strrchr(const s: PChar; c: Longint): PChar; cdecl; external GLIBC_LIB name 'strrchr';
function strstr(const haystack: PChar; const needle: PChar): PChar; cdecl; external GLIBC_LIB name 'strstr';
function strcasestr(const haystack: PChar; const needle: PChar): PChar; cdecl; external GLIBC_LIB name 'strcasestr';
function strtok(s: PChar; const delim: PChar): PChar; cdecl; external GLIBC_LIB name 'strtok';
function strtok_r(s: PChar; const delim: PChar; save_ptr: PPchar): PChar; cdecl; external GLIBC_LIB name 'strtok_r';
function strsep(stringp: PPchar; const delim: PChar): PChar; cdecl; external GLIBC_LIB name 'strsep';
function strlen(const s: PChar): size_t; cdecl; external GLIBC_LIB name 'strlen';
function strnlen(const s: PChar; maxlen: size_t): size_t; cdecl; external GLIBC_LIB name 'strnlen';
function strerror(errnum: Longint): PChar; cdecl; external GLIBC_LIB name 'strerror';
function strerror_r(errnum: Longint; buf: PChar; buflen: size_t): PChar; cdecl; external GLIBC_LIB name 'strerror_r';
function strsignal(sig: Longint): PChar; cdecl; external GLIBC_LIB name 'strsignal';

function __chdir(const path: PChar): Longint; cdecl; external GLIBC_LIB name 'chdir';
function chdir(const path: PChar): Longint; cdecl; external GLIBC_LIB name 'chdir';
function libc_chdir(const path: PChar): Longint; cdecl; external GLIBC_LIB name 'chdir';

function errno : error_t;
function __errno_location: PInteger; cdecl; external GLIBC_LIB name '__errno_location';

function fork: __pid_t; cdecl; external GLIBC_LIB name 'fork';
function vfork: __pid_t; cdecl; external GLIBC_LIB name 'vfork';
function link(const oldpath: PChar; const newpath: PChar): Longint; cdecl; external GLIBC_LIB name 'link';
function symlink(const oldpath: PChar; const newpath: PChar): Longint; cdecl; external GLIBC_LIB name 'symlink';
function readlink(const path: PChar; buf: PChar; bufsiz: size_t): Longint; cdecl; external GLIBC_LIB name 'readlink';
function unlink(const pathname: PChar): Longint; cdecl; external GLIBC_LIB name 'unlink';
function __rmdir(const pathname: PChar): Longint; cdecl; external GLIBC_LIB name 'rmdir';
function rmdir(const pathname: PChar): Longint; cdecl; external GLIBC_LIB name 'rmdir';
function libc_rmdir(const pathname: PChar): Longint; cdecl; external GLIBC_LIB name 'rmdir';
function remove(const pathname: PChar): Longint; cdecl; external GLIBC_LIB name 'remove';
function libc_remove(const pathname: PChar): Longint; cdecl; external GLIBC_LIB name 'remove';
function __rename(const oldpath: PChar; const newpath: PChar): Longint; cdecl; external GLIBC_LIB name 'rename';
function libc_rename(const oldpath: PChar; const newpath: PChar): Longint; cdecl; external GLIBC_LIB name 'rename';
function wait(status: PLongint): __pid_t; cdecl; external GLIBC_LIB name 'wait';
function waitpid(pid: __pid_t; status: Plongint; options: Longint): __pid_t; cdecl; external GLIBC_LIB name 'waitpid';
function waitid(idtype: idtype_t; id: __id_t; infop: Psiginfo_t; options: Longint): Longint; cdecl; external GLIBC_LIB name 'waitid';
function wait3(status: Plongint; options: Longint; rusage: Prusage): __pid_t; cdecl; external GLIBC_LIB name 'wait3';
function wait4(pid: __pid_t; status: Plongint; options: Longint; rusage: Prusage): __pid_t; cdecl; external GLIBC_LIB name 'wait4';

function opendir(const name: PChar): PDIR; cdecl; external GLIBC_LIB name 'opendir';
function closedir(dir: PDIR): Longint; cdecl; external GLIBC_LIB name 'closedir';
function readdir64(dir: PDIR): PDirent64; cdecl; external GLIBC_LIB name 'readdir64';
procedure rewinddir(dir: PDIR); cdecl; external GLIBC_LIB name 'rewinddir';
procedure seekdir(dir: PDIR; pos: Longint); cdecl; external GLIBC_LIB name 'seekdir';
function telldir(dir: PDIR): Longint; cdecl; external GLIBC_LIB name 'telldir';
function dirfd(dir: PDIR): Longint; cdecl; external GLIBC_LIB name 'dirfd';

function getcwd(buf: PChar; size: size_t): PChar; cdecl; external GLIBC_LIB name 'getcwd';
function get_current_dir_name: PChar; cdecl; external GLIBC_LIB name 'get_current_dir_name';
function getwd(buf: PChar): PChar; cdecl; external GLIBC_LIB name 'getwd';

function dup(oldfd: Longint): Longint; cdecl; external GLIBC_LIB name 'dup';
function dup2(oldfd: Longint; newfd: Longint): Longint; cdecl; external GLIBC_LIB name 'dup2';

function execve(const filename: PChar; const argv: PPchar; const envp: PPchar): Longint; cdecl; external GLIBC_LIB name 'execve';
function execv(const path: PChar; const argv: PPchar): Longint; cdecl; external GLIBC_LIB name 'execv';
function execle(const path: PChar; const arg: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'execle';
function execl(const path: PChar; const arg: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'execl';
function execvp(const afile: PChar; const argv: PPchar): Longint; cdecl; external GLIBC_LIB name 'execvp';
function execlp(const afile: PChar; const arg: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'execlp';

function getpid: __pid_t; cdecl; external GLIBC_LIB name 'getpid';
function getppid: __pid_t; cdecl; external GLIBC_LIB name 'getppid';
function getpgrp: __pid_t; cdecl; external GLIBC_LIB name 'getpgrp';

procedure setpwent; cdecl; external GLIBC_LIB name 'setpwent';
procedure endpwent; cdecl; external GLIBC_LIB name 'endpwent';
function getpwent: PPasswd; cdecl; external GLIBC_LIB name 'getpwent';
function fgetpwent(stream: PFILE): PPasswd; cdecl; external GLIBC_LIB name 'fgetpwent';
function putpwent(const p: PPasswd; stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'putpwent';
function getpwuid(uid: __uid_t): PPasswd; cdecl; external GLIBC_LIB name 'getpwuid';
function getpwnam(const name: PChar): PPasswd; cdecl; external GLIBC_LIB name 'getpwnam';

procedure setgrent; cdecl; external GLIBC_LIB name 'setgrent';
procedure endgrent; cdecl; external GLIBC_LIB name 'endgrent';
function getgrent:PGroup; cdecl; external GLIBC_LIB name 'getgrent';
function fgetgrent(stream: PFILE): PGroup; cdecl; external GLIBC_LIB name 'fgetgrent';
function putgrent(p: PGroup; stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'putgrent';
function getgrgid(gid: __gid_t): PGroup; cdecl; external GLIBC_LIB name 'getgrgid';
function getgrnam(name: PChar): PGroup; cdecl; external GLIBC_LIB name 'getgrnam';

function __time(t: Ptime_t): time_t; cdecl; external GLIBC_LIB name 'time';
function time(t: Ptime_t): time_t; cdecl; external GLIBC_LIB name 'time';
function libc_time(t: Ptime_t): time_t; cdecl; external GLIBC_LIB name 'time';
function mktime(timep: Ptm): time_t; cdecl; external GLIBC_LIB name 'mktime';
function strftime(s: PChar; max: size_t; const format: PChar; tm: Ptm): size_t; cdecl; external GLIBC_LIB name 'strftime';
function gmtime(timep: Ptime_t): Ptm; cdecl; external GLIBC_LIB name 'gmtime';
function localtime(timep: Ptime_t): Ptm; cdecl; external GLIBC_LIB name 'localtime';
function ctime(timep: Ptime_t): PChar; cdecl; external GLIBC_LIB name 'ctime';
function usleep(usec: DWord): Longint; cdecl; external GLIBC_LIB name 'usleep';

function mktemp(template: PChar): PChar; cdecl; external GLIBC_LIB name 'mktemp';
function mkstemp(template: PChar): Longint; cdecl; external GLIBC_LIB name 'mkstemp';
function mkstemp64(template: PChar): Longint; cdecl; external GLIBC_LIB name 'mkstemp64';
function mkdtemp(template: PChar): PChar; cdecl; external GLIBC_LIB name 'mkdtemp';

function fprintf(stream: PFILE; const format: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'fprintf';
function printf(const format: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'printf';
function sprintf(s: PChar; const format: PChar): Longint; varargs; cdecl; external GLIBC_LIB name 'sprintf';
function snprintf(s: PChar; size: size_t; const format: PChar): Longint; varargs; cdecl; external GLIBC_LIB name 'snprintf';

function WEXITSTATUS(Status: longint): longint;
function WTERMSIG(Status: longint): longint;
function WSTOPSIG(Status: longint): longint;
function WIFEXITED(Status: longint): Boolean;
function WIFSIGNALED(Status: longint): Boolean;
function WIFSTOPPED(Status: longint): Boolean;
function WCOREDUMP(Status: longint): Boolean;
function W_EXITCODE(ReturnCode, Signal: longint): longint;
function W_STOPCODE(Signal: longint): longint;

procedure _exit(status: longint); cdecl; external GLIBC_LIB name '_exit';

function gethostname(name: PChar; len: size_t): Longint; cdecl; external GLIBC_LIB name 'gethostname';

function sigqueue(pid: __pid_t; sig: Longint; val: sigval): Longint; cdecl; external GLIBC_LIB name 'sigqueue';
function sigaction(sig: Longint; Action: PSigAction; OldAction: PSigAction): Integer; cdecl; external GLIBC_LIB name 'sigaction';
function __system(const command: PChar): Longint; cdecl; external GLIBC_LIB name 'system';
function system(const command: PChar): Longint; cdecl; external GLIBC_LIB name 'system';
function libc_system(const command: PChar): Longint; cdecl; external GLIBC_LIB name 'system';

procedure perror(const s: PChar); cdecl; external GLIBC_LIB name 'perror';
function popen(const command: PChar; const _type: PChar): PFILE; cdecl; external GLIBC_LIB name 'popen';
function pclose(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'pclose';
function pipe(pipedes: Plongint): Longint; cdecl; external GLIBC_LIB name 'pipe';

function fopen(const path: PChar; const mode: PChar): PFILE; cdecl; external GLIBC_LIB name 'fopen';
function fopen64(const path: PChar; const mode: PChar): PFILE; cdecl; external GLIBC_LIB name 'fopen64';
function fdopen(fd: Longint; mode: PChar): PFILE; cdecl; external GLIBC_LIB name 'fdopen';
function fclose(fp: PFILE): Longint; cdecl; external GLIBC_LIB name 'fclose';
function fflush(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'fflush';
function fflush_unlocked(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'fflush_unlocked';
function fread(ptr: Pointer; size: size_t; n: size_t; stream: PFILE): size_t; cdecl; external GLIBC_LIB name 'fread';
function fwrite(const ptr: Pointer; size: size_t; n: size_t; stream: PFILE): size_t; cdecl; external GLIBC_LIB name 'fwrite';
function fseek(stream: PFILE; off: Longint; whence: Longint): Longint; cdecl; external GLIBC_LIB name 'fseek';
function ftell(stream:PFILE): Longint; cdecl; external GLIBC_LIB name 'ftell';
procedure rewind(stream:PFILE); cdecl; external GLIBC_LIB name 'rewind';

function fseeko(stream: PFILE; offset: __off_t; whence: Longint): Longint; cdecl; external GLIBC_LIB name 'fseeko';
function ftello(stream: PFILE): __off_t; cdecl; external GLIBC_LIB name 'ftello';
function fgetpos(stream: PFILE; pos: Pfpos_t): Longint; cdecl; external GLIBC_LIB name 'fgetpos';
function fsetpos(stream: PFILE; pos: Pfpos_t): Longint; cdecl; external GLIBC_LIB name 'fsetpos';
function fseeko64(stream: PFILE; offset: __off64_t; whence: Longint): Longint; cdecl; external GLIBC_LIB name 'fseeko64';
function ftello64(stream: PFILE): __off64_t; cdecl; external GLIBC_LIB name 'ftello64';
function fgetpos64(stream: PFILE; pos: Pfpos64_t): Longint; cdecl; external GLIBC_LIB name 'fgetpos64';
function fsetpos64(stream: PFILE; pos: Pfpos64_t): Longint; cdecl; external GLIBC_LIB name 'fsetpos64';
function feof(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'feof';
function ferror(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'ferror';

function fcntl(fd: Longint; cmd: Longint): Longint; cdecl; varargs; external GLIBC_LIB name 'fcntl';
function open(const pathname: PChar; flags: Longint): Longint; cdecl; varargs; external GLIBC_LIB name 'open';
function open64(const pathname: PChar; flags: Longint): Longint; cdecl; varargs; external GLIBC_LIB name 'open64';
function creat(const pathname: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'creat';
function creat64(const pathname: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'creat64';

function __read(Handle: Integer; var Buffer; Count: size_t): ssize_t; cdecl; external GLIBC_LIB name 'read';
function libc_read(Handle: Integer; var Buffer; Count: size_t): ssize_t; cdecl; external GLIBC_LIB name 'read';
function __write(Handle: Integer; const Buffer; Count: size_t): ssize_t; cdecl; external GLIBC_LIB name 'write';
function libc_write(Handle: Integer; const Buffer; Count: size_t): ssize_t; cdecl; external GLIBC_LIB name 'write';
function __close(Handle: Integer): Integer; cdecl; external GLIBC_LIB name 'close';
function libc_close(Handle: Integer): Integer; cdecl; external GLIBC_LIB name 'close';

function getuid: __uid_t; cdecl; external GLIBC_LIB name 'getuid';
function geteuid: __uid_t; cdecl; external GLIBC_LIB name 'geteuid';
function getgid: __gid_t; cdecl; external GLIBC_LIB name 'getgid';
function getegid: __gid_t; cdecl; external GLIBC_LIB name 'getegid';

function access(pathname: PChar; mode: Longint): Longint; cdecl; external GLIBC_LIB name 'access';
function euidaccess(pathname: PChar; mode: Longint): Longint; cdecl; external GLIBC_LIB name 'euidaccess';


type pthread_t = {$ifdef cpu64}QWord{$else}DWord{$endif};

function pthread_self: pthread_t; cdecl; external PTHREAD_LIB name 'pthread_self';


implementation

{$IFDEF CPUPOWERPC}
uses SysUtils;
{$ENDIF}


{$IFDEF KYLIX}
function glibc__xstat64(ver: integer; const afile: PChar; buf: Pstat64): longint; cdecl; external GLIBC_LIB name '__xstat64';
function glibc__lxstat64(ver: integer; const path: PChar; buf: Pstat64): longint; cdecl; external GLIBC_LIB name '__lxstat64';

function stat64(const afile: PChar; buf: Pstat64): longint;
begin
  Result := glibc__xstat64(_STAT_VER, afile, buf);
end;

function lstat64(const path: PChar; buf: Pstat64): longint;
begin
  Result := glibc__lxstat64(_STAT_VER, path, buf);
end;
{$ENDIF}

function errno : error_t;
begin
  Result := __errno_location()^;
end;

function __S_ISTYPE(mode, mask : __mode_t) : boolean;
begin
  Result := (mode and __S_IFMT) = mask;
end;

function S_ISDIR(mode : __mode_t) : boolean;
begin
   Result := __S_ISTYPE(mode, __S_IFDIR);
end;

function S_ISCHR(mode : __mode_t) : boolean;
begin
   Result := __S_ISTYPE(mode, __S_IFCHR);
end;

function S_ISBLK(mode : __mode_t) : boolean;
begin
   Result := __S_ISTYPE(mode, __S_IFBLK);
end;

function S_ISREG(mode : __mode_t) : boolean;
begin
   Result := __S_ISTYPE(mode, __S_IFREG);
end;

function S_ISFIFO(mode : __mode_t) : boolean;
begin
   Result := __S_ISTYPE(mode, __S_IFIFO);
end;

function S_ISLNK(mode : __mode_t) : boolean;
begin
   Result := __S_ISTYPE(mode, __S_IFLNK);
end;

function S_ISSOCK(mode : __mode_t) : boolean;
begin
   Result := __S_ISTYPE(mode, __S_IFSOCK);
end;

Function WEXITSTATUS(Status: longint): longint;
begin
  Result:=(Status and $FF00) shr 8;
end;


Function WTERMSIG(Status: longint): longint;
begin
  Result:=(Status and $7F);
end;


Function WSTOPSIG(Status: longint): longint;
begin
  Result:=WEXITSTATUS(Status);
end;


Function WIFEXITED(Status: longint): Boolean;
begin
  Result:=(WTERMSIG(Status)=0);
end;


Function WIFSIGNALED(Status: longint): Boolean;
begin
  Result:=(not WIFSTOPPED(Status)) and (not WIFEXITED(Status));
end;


Function WIFSTOPPED(Status: longint): Boolean;
begin
  Result:=((Status and $FF)=$7F);
end;


Function WCOREDUMP(Status: longint): Boolean;
begin
  Result:=((Status and WCOREFLAG)<>0);
end;


Function W_EXITCODE(ReturnCode, Signal: longint): longint;
begin
  Result:=(ReturnCode shl 8) or Signal;
end;


Function W_STOPCODE(Signal: longint): longint;
begin
  Result:=(Signal shl 8) or $7F;
end;


{$IFDEF CPUPOWERPC}
function malloc(size: size_t): Pointer;
begin
  Result := GetMem(size);
end;

procedure libc_free(ptr: Pointer);
begin
  FreeMem(ptr);
end;

procedure free(ptr: Pointer);
begin
  libc_free(ptr);
end;

function strdup(const s: PChar): PChar;
begin
  Result := GetMem(strlen(s) + 1);
  SysUtils.StrLCopy(Result, s, strlen(s) + 1);
end;

function strndup(const s: PChar; n: size_t): PChar;
begin
  Result := GetMem(n + 1);
  SysUtils.StrLCopy(Result, s, n);
end;
{$ENDIF}

end.

