588 lines
19 KiB
PHP
588 lines
19 KiB
PHP
{******************************************************************************}
|
|
{ }
|
|
{ Library: Fundamentals 5.00 }
|
|
{ File name: flcSocketLibPosixDelphi.inc }
|
|
{ File version: 5.03 }
|
|
{ Description: Delphi Posix socket library }
|
|
{ }
|
|
{ Copyright: Copyright © 2018-2020, David J Butler }
|
|
{ All rights reserved. }
|
|
{ Redistribution and use in source and binary forms, with }
|
|
{ or without modification, are permitted provided that }
|
|
{ the following conditions are met: }
|
|
{ Redistributions of source code must retain the above }
|
|
{ copyright notice, this list of conditions and the }
|
|
{ following disclaimer. }
|
|
{ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND }
|
|
{ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED }
|
|
{ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED }
|
|
{ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A }
|
|
{ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL }
|
|
{ THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, }
|
|
{ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR }
|
|
{ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, }
|
|
{ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF }
|
|
{ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) }
|
|
{ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER }
|
|
{ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING }
|
|
{ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE }
|
|
{ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE }
|
|
{ POSSIBILITY OF SUCH DAMAGE. }
|
|
{ }
|
|
{ Github: https://github.com/fundamentalslib }
|
|
{ E-mail: fundamentals.library at gmail.com }
|
|
{ }
|
|
{ Revision history: }
|
|
{ }
|
|
{ 2018/07/12 5.01 Initial implementation. }
|
|
{ 2018/07/16 5.02 Fixes. }
|
|
{ 2018/09/09 5.03 Poll function. }
|
|
{ }
|
|
{ Supported compilers: }
|
|
{ }
|
|
{ Delphi 10.2-10.4 Linux64 5.03 2020/06/02 }
|
|
{ Delphi 10.2-10.4 iOS32/64 5.03 2020/06/02 }
|
|
{ Delphi 10.2-10.4 OSX32/64 5.03 2020/06/02 }
|
|
{ Delphi 10.2-10.4 Android32/64 5.03 2020/06/02 }
|
|
{ }
|
|
{******************************************************************************}
|
|
|
|
{$WARN SYMBOL_PLATFORM OFF}
|
|
{$WARN UNIT_PLATFORM OFF}
|
|
|
|
interface
|
|
|
|
uses
|
|
{ System }
|
|
Posix.Errno,
|
|
Posix.SysTime,
|
|
Posix.SysSelect,
|
|
Posix.SysSocket,
|
|
Posix.NetinetIn,
|
|
Posix.NetDB,
|
|
|
|
{ Fundamentals }
|
|
flcStdTypes;
|
|
|
|
|
|
|
|
type
|
|
TTimeVal = timeval;
|
|
PTimeVal = Posix.SysTime.Ptimeval;
|
|
|
|
type
|
|
TSocket = Integer;
|
|
|
|
const
|
|
INVALID_SOCKET = TSocket(not 0);
|
|
|
|
type
|
|
TInAddr = in_addr;
|
|
PInAddr = Pin_addr;
|
|
TIn6Addr = in6_addr;
|
|
PIn6Addr = Pin6_addr;
|
|
|
|
const
|
|
INADDR_NONE = Posix.NetinetIn.INADDR_NONE;
|
|
INADDR_ANY = Posix.NetinetIn.INADDR_ANY;
|
|
INADDR_BROADCAST = Posix.NetinetIn.INADDR_BROADCAST;
|
|
INADDR_LOOPBACK = Posix.NetinetIn.INADDR_LOOPBACK;
|
|
|
|
type
|
|
TSockAddr = sockaddr_storage;
|
|
PTSockAddr = ^TSockAddr;
|
|
PSockAddr = Posix.SysSocket.psockaddr;
|
|
|
|
TSockAddrIn = sockaddr_in;
|
|
PSockAddrIn = ^TSockAddrIn;
|
|
|
|
TSockAddrIn6 = sockaddr_in6;
|
|
PSockAddrIn6 = ^TSockAddrIn6;
|
|
|
|
TFDSet = fd_set;
|
|
|
|
THostEnt = hostent;
|
|
PHostEnt = Posix.NetDB.phostent;
|
|
|
|
TServEnt = servent;
|
|
PServEnt = Posix.NetDB.Pservent;
|
|
|
|
TProtoEnt = protoent;
|
|
PProtoEnt = Posix.NetDB.Pprotoent;
|
|
|
|
TAddrInfo = addrinfo;
|
|
PAddrInfo = Posix.NetDB.paddrinfo;
|
|
|
|
const
|
|
AF_INET = Posix.SysSocket.AF_INET;
|
|
AF_INET6 = Posix.SysSocket.AF_INET6;
|
|
AF_UNSPEC = Posix.SysSocket.AF_UNSPEC;
|
|
|
|
IPPROTO_IP = Posix.NetinetIn.IPPROTO_IP;
|
|
IPPROTO_ICMP = Posix.NetinetIn.IPPROTO_ICMP;
|
|
IPPROTO_TCP = Posix.NetinetIn.IPPROTO_TCP;
|
|
IPPROTO_UDP = Posix.NetinetIn.IPPROTO_UDP;
|
|
IPPROTO_RAW = Posix.NetinetIn.IPPROTO_RAW;
|
|
|
|
SOCK_STREAM = Posix.SysSocket.SOCK_STREAM;
|
|
SOCK_DGRAM = Posix.SysSocket.SOCK_DGRAM;
|
|
SOCK_RAW = Posix.SysSocket.SOCK_RAW;
|
|
|
|
MSG_OOB = Posix.SysSocket.MSG_OOB;
|
|
MSG_PEEK = Posix.SysSocket.MSG_PEEK;
|
|
|
|
SOL_SOCKET = Posix.SysSocket.SOL_SOCKET;
|
|
{$IFNDEF ANDROID}
|
|
{$IFNDEF OSX}
|
|
{$IFNDEF IOS}
|
|
SOL_RAW = Posix.SysSocket.SOL_RAW;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
SO_RCVTIMEO = Posix.SysSocket.SO_RCVTIMEO;
|
|
SO_SNDTIMEO = Posix.SysSocket.SO_SNDTIMEO;
|
|
SO_BROADCAST = Posix.SysSocket.SO_BROADCAST;
|
|
SO_LINGER = Posix.SysSocket.SO_LINGER;
|
|
SO_RCVBUF = Posix.SysSocket.SO_RCVBUF;
|
|
SO_SNDBUF = Posix.SysSocket.SO_SNDBUF;
|
|
TCP_NODELAY = 1; //Posix.SysSocket.TCP_NODELAY;
|
|
|
|
type
|
|
TFD_MASK = fd_mask;
|
|
TFD_Set = fd_set;
|
|
PFDSet = Pfd_set;
|
|
|
|
const
|
|
FD_SETSIZE = Posix.SysSelect.FD_SETSIZE;
|
|
NFDBITS = Posix.SysSelect.NFDBITS;
|
|
|
|
function FDMASK(const d: Int32): TFD_MASK;
|
|
function FD_ISSET(fd: Int32; const fdset: TFDSet): Boolean;
|
|
|
|
procedure FD_SET(const fd: Int32; var fdset: TFDSet);
|
|
procedure FD_CLR(const fd: Int32; var fdset: TFDSet);
|
|
procedure FD_ZERO(out fdset: TFDSet);
|
|
|
|
function FD_COUNT(const fdset: TFDSet): Integer;
|
|
|
|
|
|
const
|
|
NI_MAXHOST = Posix.NetDB.NI_MAXHOST;
|
|
NI_MAXSERV = Posix.NetDB.NI_MAXSERV;
|
|
NI_NUMERICSERV = Posix.NetDB.NI_NUMERICSERV;
|
|
AI_NUMERICHOST = Posix.NetDB.AI_NUMERICHOST;
|
|
|
|
|
|
{$IFDEF OS_ANDROID32}
|
|
{$IFDEF DELPHI10_4_UP}
|
|
{$DEFINE SockLen_Int32}
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
{$IFDEF SockLen_Int32}
|
|
type
|
|
TSockLen = Int32;
|
|
{$ELSE}
|
|
type
|
|
TSockLen = FixedUInt;
|
|
{$ENDIF}
|
|
|
|
type
|
|
TPollfd = record
|
|
fd : TSocket;
|
|
events : Int16;
|
|
revents : Int16;
|
|
end;
|
|
PPollfd = ^TPollfd;
|
|
|
|
const
|
|
POLLIN = $0001;
|
|
POLLPRI = $0002;
|
|
POLLOUT = $0004;
|
|
POLLERR = $0008;
|
|
POLLHUP = $0010;
|
|
POLLNVAL = $0020;
|
|
|
|
function Accept(const socket: TSocket; const address: PSockAddr; var address_len: TSockLen): Integer;
|
|
function Bind(const socket: TSocket; const address: TSockAddr; const address_len: TSockLen): Integer;
|
|
function CloseSocket(const socket: TSocket): Integer;
|
|
function Connect(const socket: TSocket; const address: PSockAddr; const address_len: TSockLen): Integer;
|
|
procedure FreeAddrInfo(const ai: PAddrInfo);
|
|
function GetAddrInfo(const HostName: Pointer; const ServName: Pointer;
|
|
const Hints: PAddrInfo; var AddrInfo: PAddrInfo): Integer;
|
|
function GetHostByAddr(const Addr: Pointer; const Len: Integer;
|
|
const AF: Integer): PHostEnt;
|
|
function GetHostByName(const Name: Pointer): PHostEnt;
|
|
function GetHostName(const Name: Pointer; const Len: Integer): Integer;
|
|
function GetNameInfo(const Addr: PSockAddr; const NameLen: Integer;
|
|
const Host: Pointer; const HostLen: Word32;
|
|
const Serv: Pointer; const ServLen: Word32; const Flags: Integer): Integer;
|
|
function GetProtoByName(const Name: Pointer): PProtoEnt;
|
|
function GetProtoByNumber(const Proto: Integer): PProtoEnt;
|
|
function GetPeerName(const S: TSocket; var Name: TSockAddr; var NameLen: TSockLen): Integer;
|
|
function GetServByName(const Name, Proto: Pointer): PServEnt;
|
|
function GetServByPort(const Port: Integer; const Proto: Pointer): PServEnt;
|
|
function GetSockName(const S: TSocket; var Name: TSockAddr; var NameLen: TSockLen): Integer;
|
|
function GetSockOpt(const S: TSocket; const Level, OptName: Integer;
|
|
const OptVal: Pointer; var OptLen: TSockLen): Integer;
|
|
function htons(const HostShort: Word): Word;
|
|
function htonl(const HostLong: Word32): Word32;
|
|
function inet_ntoa(const InAddr: TInAddr): Pointer;
|
|
function inet_addr(const P: Pointer): Word32;
|
|
function Listen(const S: TSocket; const Backlog: Integer): Integer;
|
|
function ntohs(const NetShort: Word): Word;
|
|
function ntohl(const NetLong: Word32): Word32;
|
|
function Poll(fds: Pointer; nfds: Integer; timeout: Integer): Integer;
|
|
function Recv(const S: TSocket; var Buf; const Len, Flags: Integer): Integer;
|
|
function RecvFrom(const S: TSocket; var Buf; const Len, Flags: Integer;
|
|
var From: TSockAddr; var FromLen: Integer): Integer;
|
|
function Select(const nfds: Word32; const ReadFDS, WriteFDS, ExceptFDS: PFDSet;
|
|
const TimeOut: PTimeVal): Integer;
|
|
function Send(const S: TSocket; const Buf; const Len, Flags: Integer): Integer;
|
|
function SendTo(const S: TSocket; const Buf; const Len, Flags: Integer;
|
|
const AddrTo: PSockAddr; const ToLen: Integer): Integer;
|
|
function SetSockOpt(const S: TSocket; const Level, OptName: Integer;
|
|
const OptVal: Pointer; const OptLen: Integer): Integer;
|
|
function Shutdown(const S: TSocket; const How: Integer): Integer;
|
|
function Socket(const AF, Struct, Protocol: Integer): TSocket;
|
|
|
|
const
|
|
EINTR = Posix.Errno.EINTR;
|
|
EBADF = Posix.Errno.EBADF;
|
|
EACCES = Posix.Errno.EACCES;
|
|
EFAULT = Posix.Errno.EFAULT;
|
|
EINVAL = Posix.Errno.EINVAL;
|
|
EMFILE = Posix.Errno.EMFILE;
|
|
EWOULDBLOCK = Posix.Errno.EWOULDBLOCK;
|
|
EINPROGRESS = Posix.Errno.EINPROGRESS;
|
|
EALREADY = Posix.Errno.EALREADY;
|
|
ENOTSOCK = Posix.Errno.ENOTSOCK;
|
|
EDESTADDRREQ = Posix.Errno.EDESTADDRREQ;
|
|
EMSGSIZE = Posix.Errno.EMSGSIZE;
|
|
EPROTOTYPE = Posix.Errno.EPROTOTYPE;
|
|
ENOPROTOOPT = Posix.Errno.ENOPROTOOPT;
|
|
EPROTONOSUPPORT = Posix.Errno.EPROTONOSUPPORT;
|
|
ESOCKTNOSUPPORT = Posix.Errno.ESOCKTNOSUPPORT;
|
|
EOPNOTSUPP = Posix.Errno.EOPNOTSUPP;
|
|
EPFNOSUPPORT = Posix.Errno.EPFNOSUPPORT;
|
|
EAFNOSUPPORT = Posix.Errno.EAFNOSUPPORT;
|
|
EADDRINUSE = Posix.Errno.EADDRINUSE;
|
|
EADDRNOTAVAIL = Posix.Errno.EADDRNOTAVAIL;
|
|
ENETDOWN = Posix.Errno.ENETDOWN;
|
|
ENETUNREACH = Posix.Errno.ENETUNREACH;
|
|
ENETRESET = Posix.Errno.ENETRESET;
|
|
ECONNABORTED = Posix.Errno.ECONNABORTED;
|
|
ECONNRESET = Posix.Errno.ECONNRESET;
|
|
ENOBUFS = Posix.Errno.ENOBUFS;
|
|
EISCONN = Posix.Errno.EISCONN;
|
|
ENOTCONN = Posix.Errno.ENOTCONN;
|
|
ESHUTDOWN = Posix.Errno.ESHUTDOWN;
|
|
ETOOMANYREFS = Posix.Errno.ETOOMANYREFS;
|
|
ETIMEDOUT = Posix.Errno.ETIMEDOUT;
|
|
ECONNREFUSED = Posix.Errno.ECONNREFUSED;
|
|
ENAMETOOLONG = Posix.Errno.ENAMETOOLONG;
|
|
EHOSTDOWN = Posix.Errno.EHOSTDOWN;
|
|
EHOSTUNREACH = Posix.Errno.EHOSTUNREACH;
|
|
|
|
function GetLastSocketError: Integer;
|
|
procedure SetSockBlocking(const S: TSocket; const Blocking: Boolean);
|
|
function SockAvailableToRecv(const S: TSocket): Integer;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
Posix.Unistd,
|
|
Posix.ArpaInet,
|
|
Posix.Fcntl,
|
|
Posix.StrOpts,
|
|
Posix.Base;
|
|
|
|
|
|
|
|
function FDMASK(const d: Int32): TFD_MASK;
|
|
begin
|
|
Result := 1 shl (d mod NFDBITS);
|
|
end;
|
|
|
|
function FD_ISSET(fd: Int32; const fdset: TFDSet): Boolean;
|
|
begin
|
|
Result := (fdset.fds_bits[fd div NFDBITS] and FDMASK(fd)) <> 0;
|
|
end;
|
|
|
|
procedure FD_SET(const fd: Int32; var fdset: TFDSet);
|
|
var I : Integer;
|
|
begin
|
|
I := fd div NFDBITS;
|
|
Assert(I < FD_SETSIZE);
|
|
fdset.fds_bits[I] := fdset.fds_bits[I] or FDMASK(fd);
|
|
end;
|
|
|
|
procedure FD_CLR(const fd: Int32; var fdset: TFDSet);
|
|
var I : Integer;
|
|
begin
|
|
I := fd div NFDBITS;
|
|
Assert(I < FD_SETSIZE);
|
|
fdset.fds_bits[I] := fdset.fds_bits[I] and not FDMASK(fd);
|
|
end;
|
|
|
|
procedure FD_ZERO(out fdset: TFDSet);
|
|
var I : Integer;
|
|
begin
|
|
for I := 0 to FD_SETSIZE div NFDBITS - 1 do
|
|
fdset.fds_bits[I] := 0;
|
|
end;
|
|
|
|
|
|
function FD_COUNT(const fdset: TFDSet): Integer;
|
|
|
|
var C, I, J : Integer;
|
|
|
|
F : Int32;
|
|
|
|
begin
|
|
C := 0;
|
|
for I := 0 to FD_SETSIZE div NFDBITS - 1 do
|
|
if fdset.fds_bits[I] <> 0 then
|
|
begin
|
|
F := I * NFDBITS;
|
|
for J := 0 to NFDBITS - 1 do
|
|
begin
|
|
if FD_ISSET(F, FDSet) then
|
|
Inc(C);
|
|
Inc(F);
|
|
end;
|
|
end;
|
|
Result := C;
|
|
end;
|
|
|
|
function Accept(const socket: TSocket; const address: PSockAddr; var address_len: TSockLen): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.accept(socket, address^, address_len);
|
|
end;
|
|
|
|
function Bind(const socket: TSocket; const address: TSockAddr; const address_len: TSockLen): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.bind(socket, Psockaddr(@address)^, address_len);
|
|
end;
|
|
|
|
function CloseSocket(const socket: TSocket): Integer;
|
|
begin
|
|
Result := __close(socket);
|
|
end;
|
|
|
|
function Connect(const socket: TSocket; const address: PSockAddr; const address_len: TSockLen): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.connect(socket, address^, address_len);
|
|
end;
|
|
|
|
procedure FreeAddrInfo(const ai: PAddrInfo);
|
|
begin
|
|
Posix.NetDB.freeaddrinfo(ai^);
|
|
end;
|
|
|
|
function GetAddrInfo(const HostName: Pointer; const ServName: Pointer;
|
|
const Hints: PAddrInfo; var AddrInfo: PAddrInfo): Integer;
|
|
begin
|
|
Result := Posix.NetDB.getaddrinfo(
|
|
MarshaledAString(HostName),
|
|
MarshaledAString(ServName),
|
|
Hints^,
|
|
AddrInfo);
|
|
end;
|
|
|
|
function GetHostByAddr(const Addr: Pointer; const Len: Integer; const AF: Integer): PHostEnt;
|
|
begin
|
|
Result := Posix.NetDB.gethostbyaddr(Addr^, Len, AF);
|
|
end;
|
|
|
|
function GetHostByName(const Name: Pointer): PHostEnt;
|
|
begin
|
|
Result := Posix.NetDB.gethostbyname(MarshaledAString(Name));
|
|
end;
|
|
|
|
function GetHostName(const Name: Pointer; const Len: Integer): Integer;
|
|
begin
|
|
Result := Posix.Unistd.gethostname(MarshaledAString(Name), Len);
|
|
end;
|
|
|
|
function GetNameInfo(const Addr: PSockAddr; const NameLen: Integer;
|
|
const Host: Pointer; const HostLen: Word32;
|
|
const Serv: Pointer; const ServLen: Word32; const Flags: Integer): Integer;
|
|
begin
|
|
Result := Posix.NetDB.getnameinfo(Addr^, NameLen,
|
|
MarshaledAString(Host), HostLen,
|
|
MarshaledAString(Serv), ServLen, Flags);
|
|
end;
|
|
|
|
function GetProtoByName(const Name: Pointer): PProtoEnt;
|
|
begin
|
|
Result := Posix.NetDB.getprotobyname(Name);
|
|
end;
|
|
|
|
function GetProtoByNumber(const Proto: Integer): PProtoEnt;
|
|
begin
|
|
Result := Posix.NetDB.getprotobynumber(Proto);
|
|
end;
|
|
|
|
function GetPeerName(const S: TSocket; var Name: TSockAddr; var NameLen: TSockLen): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.getpeername(S, Psockaddr(@Name)^, NameLen);
|
|
end;
|
|
|
|
function GetServByName(const Name, Proto: Pointer): PServEnt;
|
|
begin
|
|
Result := Posix.NetDB.getservbyname(Name, Proto);
|
|
end;
|
|
|
|
function GetServByPort(const Port: Integer; const Proto: Pointer): PServEnt;
|
|
begin
|
|
Result := Posix.NetDB.getservbyport(Port, Proto);
|
|
end;
|
|
|
|
function GetSockName(const S: TSocket; var Name: TSockAddr; var NameLen: TSockLen): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.getsockname(S, Psockaddr(@Name)^, NameLen);
|
|
end;
|
|
|
|
function GetSockOpt(const S: TSocket; const Level, OptName: Integer;
|
|
const OptVal: Pointer; var OptLen: TSockLen): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.getsockopt(S, Level, OptName,
|
|
OptVal^, OptLen);
|
|
end;
|
|
|
|
function htons(const HostShort: Word): Word;
|
|
begin
|
|
Result := Posix.ArpaInet.htons(HostShort);
|
|
end;
|
|
|
|
function htonl(const HostLong: Word32): Word32;
|
|
begin
|
|
Result := Posix.ArpaInet.htonl(HostLong);
|
|
end;
|
|
|
|
function inet_ntoa(const InAddr: TInAddr): Pointer;
|
|
begin
|
|
Result := Posix.ArpaInet.inet_ntoa(InAddr);
|
|
end;
|
|
|
|
function inet_addr(const P: Pointer): Word32;
|
|
begin
|
|
Result := Posix.ArpaInet.inet_addr(P);
|
|
end;
|
|
|
|
function Listen(const S: TSocket; const Backlog: Integer): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.listen(S, Backlog);
|
|
end;
|
|
|
|
function ntohs(const NetShort: Word): Word;
|
|
begin
|
|
Result := Posix.ArpaInet.ntohs(NetShort);
|
|
end;
|
|
|
|
function ntohl(const NetLong: Word32): Word32;
|
|
begin
|
|
Result := Posix.ArpaInet.ntohl(NetLong);
|
|
end;
|
|
|
|
function libcpoll(fds: Pointer; nfds: Int32; timeout: Int32): Int32; cdecl;
|
|
external libc name _PU + 'poll';
|
|
{$EXTERNALSYM libcpoll}
|
|
|
|
function Poll(fds: Pointer; nfds: Integer; timeout: Integer): Integer;
|
|
begin
|
|
Result := libcpoll(fds, nfds, timeout);
|
|
end;
|
|
|
|
function Recv(const S: TSocket; var Buf; const Len, Flags: Integer): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.recv(S, Buf, Len, Flags);
|
|
end;
|
|
|
|
function RecvFrom(const S: TSocket; var Buf; const Len, Flags: Integer;
|
|
var From: TSockAddr; var FromLen: Integer): Integer;
|
|
var
|
|
FromLenT : TSockLen;
|
|
begin
|
|
FromLenT := FromLen;
|
|
Result := Posix.SysSocket.recvfrom(S, Buf, Len, Flags, Psockaddr(@From)^, FromLenT);
|
|
FromLen := FromLenT;
|
|
end;
|
|
|
|
function Select(const nfds: Word32; const ReadFDS, WriteFDS, ExceptFDS: PFDSet;
|
|
const TimeOut: PTimeVal): Integer;
|
|
begin
|
|
Result := Posix.SysSelect.select(nfds, ReadFDS, WriteFDS, ExceptFDS, TimeOut);
|
|
end;
|
|
|
|
function Send(const S: TSocket; const Buf; const Len, Flags: Integer): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.send(S, Buf, Len, Flags);
|
|
end;
|
|
|
|
function SendTo(const S: TSocket; const Buf; const Len, Flags: Integer;
|
|
const AddrTo: PSockAddr; const ToLen: Integer): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.sendto(S, Buf, Len, Flags, AddrTo^, ToLen);
|
|
end;
|
|
|
|
function SetSockOpt(const S: TSocket; const Level, OptName: Integer;
|
|
const OptVal: Pointer; const OptLen: Integer): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.setsockopt(S, Level, OptName, OptVal^, OptLen);
|
|
end;
|
|
|
|
function Shutdown(const S: TSocket; const How: Integer): Integer;
|
|
begin
|
|
Result := Posix.SysSocket.shutdown(S, How);
|
|
end;
|
|
|
|
function Socket(const AF, Struct, Protocol: Integer): TSocket;
|
|
begin
|
|
Result := Posix.SysSocket.socket(AF, Struct, Protocol);
|
|
end;
|
|
|
|
function GetLastSocketError: Integer;
|
|
begin
|
|
Result := errno;
|
|
end;
|
|
|
|
procedure SetSockBlocking(const S: TSocket; const Blocking: Boolean);
|
|
var
|
|
Flags : Integer;
|
|
begin
|
|
Flags := Posix.Fcntl.fcntl(Integer(S), F_GETFL, 0);
|
|
if Blocking then
|
|
Flags := Flags and not O_NONBLOCK
|
|
else
|
|
Flags := Flags or O_NONBLOCK;
|
|
Posix.Fcntl.fcntl(Integer(S), F_SETFL, Flags);
|
|
end;
|
|
|
|
{$IFDEF ANDROID}
|
|
function SockAvailableToRecv(const S: TSocket): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
{$ELSE}{$IFDEF OSX}
|
|
function SockAvailableToRecv(const S: TSocket): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
{$ELSE}{$IFDEF IOS}
|
|
function SockAvailableToRecv(const S: TSocket): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
{$ELSE}
|
|
function SockAvailableToRecv(const S: TSocket): Integer;
|
|
var L : Word32;
|
|
begin
|
|
if Ioctl(S, I_NREAD, @L) <> 0 then
|
|
Result := 0
|
|
else
|
|
Result := L;
|
|
end;
|
|
{$ENDIF}{$ENDIF}{$ENDIF}{$ENDIF}
|
|
|
|
|
|
|
|
end.
|
|
|