%
%   $Id$
%   This file is part of the FPC documentation.
%   Copyright (C) 1997, by Michael Van Canneyt
%
%   The FPC documentation is free text; you can redistribute it and/or
%   modify it under the terms of the GNU Library General Public License as
%   published by the Free Software Foundation; either version 2 of the
%   License, or (at your option) any later version.
%
%   The FPC Documentation 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
%   Library General Public License for more details.
%
%   You should have received a copy of the GNU Library General Public
%   License along with the FPC documentation; see the file COPYING.LIB.  If not,
%   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
%   Boston, MA 02111-1307, USA. 
%
\chapter{The SOCKETS unit.}
This chapter describes the SOCKETS unit for Free Pascal. 
it was written for \linux by Micha\"el Van Canneyt. 

The chapter is divided in 2 sections:
\begin{itemize}
\item The first section lists types, constants and variables from the
interface part of the unit.
\item The second section describes the functions defined in the unit.
\end{itemize}

\section {Types, Constants and variables : }
The following constants identify the different socket types, as needed in
the \seef{Socket} call.
\begin{verbatim}
SOCK_STREAM     = 1; { stream (connection) socket   }
SOCK_DGRAM      = 2; { datagram (conn.less) socket  }
SOCK_RAW        = 3; { raw socket                   }
SOCK_RDM        = 4; { reliably-delivered message   }
SOCK_SEQPACKET  = 5; { sequential packet socket     }
SOCK_PACKET     =10;
\end{verbatim}
The following constants determine the socket domain, they are used in the
\seef{Socket} call.
\begin{verbatim}
AF_UNSPEC       = 0;
AF_UNIX         = 1; { Unix domain sockets          }
AF_INET         = 2; { Internet IP Protocol         }
AF_AX25         = 3; { Amateur Radio AX.25          }
AF_IPX          = 4; { Novell IPX                   }
AF_APPLETALK    = 5; { Appletalk DDP                }
AF_NETROM       = 6; { Amateur radio NetROM         }
AF_BRIDGE       = 7; { Multiprotocol bridge         }
AF_AAL5         = 8; { Reserved for Werner's ATM    }
AF_X25          = 9; { Reserved for X.25 project    }
AF_INET6        = 10; { IP version 6                 }
AF_MAX          = 12;
\end{verbatim}
The following constants determine the protocol family, they are used in the
\seef{Socket} call.
\begin{verbatim} 
PF_UNSPEC       = AF_UNSPEC;
PF_UNIX         = AF_UNIX;
PF_INET         = AF_INET;
PF_AX25         = AF_AX25;
PF_IPX          = AF_IPX;
PF_APPLETALK    = AF_APPLETALK;
PF_NETROM       = AF_NETROM;
PF_BRIDGE       = AF_BRIDGE;
PF_AAL5         = AF_AAL5;
PF_X25          = AF_X25;
PF_INET6        = AF_INET6;
PF_MAX          = AF_MAX;   
\end{verbatim}
The following types are used to store different kinds of eddresses for the
\seef{Bind}, \seef{Recv} and \seef{Send} calls.
\begin{verbatim}  
TSockAddr = packed Record
  family:word;
  data  :array [0..13] of char;
  end;

TUnixSockAddr = packed Record
  family:word;
  path:array[0..108] of char;
  end;

TInetSockAddr = packed Record
  family:Word;
  port  :Word;
  addr  :Cardinal;
  pad   :array [1..8] of byte; 
  end;
\end{verbatim}
The following type is returned by the \seef{SocketPair} call.
\begin{verbatim}
TSockArray = Array[1..2] of Longint;
\end{verbatim}

\section {Functions and Procedures}

\function{Socket}{(Domain,SocketType,Protocol:Longint)}{Longint}
{\var{Socket} creates a new socket in domain \var{Domain}, from type
\var{SocketType} using protocol \var{Protocol}.

The Domain, Socket type and Protocol can be specified using predefined
constants (see the section on constants for available constants)

If succesfull, the function returns a socket descriptor, which can be passed
to a subsequent \seef{Bind} call. If unsuccesfull, the function returns -1.
}
{Errors are returned in \var{SocketError}, and include the follwing:
\begin{description}
\item[SYS\_EPROTONOSUPPORT]
The protocol type or the specified protocol is not
supported within this domain.
\item[SYS\_EMFILE]
The per-process descriptor table is full.
\item[SYS\_ENFILE]
The system file table is full.
\item[SYS\_EACCESS]
 Permission  to  create  a  socket of the specified
 type and/or protocol is denied.
\item[SYS\_ENOBUFS]
 Insufficient  buffer  space  is  available.    The
 socket   cannot   be   created   until  sufficient
 resources are freed.
\end{description}}
{\seef{SocketPair}, \seem{socket}{2}}
for an example, see \seef{Accept}.
\function{Send}{(Sock:Longint;Var Addr;AddrLen,Flags:Longint)}{Longint}
{\var{Send} sends \var{AddrLen} bytes starting from address \var{Addr}
to socket \var{Sock}. \var{Sock} must be in a connected state.

The function returns the number of bytes sent, or -1 if a detectable 
error occurred.

\var{Flags} can be one of the following:
\begin{description}
\item [1] : Process out-of band data.
\item [4] : Bypass routing, use a direct interface.
\end{description}
}
{Errors are reported in \var{SocketError}, and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\item[SYS\_EFAULT] The address is outside your address space.
\item[SYS\_EMSGSIZE] The message cannot be sent atomically.
\item[SYS\_EWOULDBLOCK] The requested operation would block the process.
\item[SYS\_ENOBUFS] The system doesn't have enough free buffers available.
\end{description}
}{\seef{Recv}, \seem{send}{2}}

\function{Recv}{(Sock:Longint;Var Addr;AddrLen,Flags:Longint)}{Longint}
{\var{Recv} reads at most \var{Addrlen} bytes from socket \var{Sock} into
address \var{Addr}. The socket must be in a connected state.

\var{Flags} can be one of the following:
\begin{description}
\item [1] : Process out-of band data.
\item [4] : Bypass routing, use a direct interface.
\item [??] : Wait for full request or report an error.
\end{description}

The functions returns the number of bytes actually read from the socket, or
-1 if a detectable error occurred.}
{Errors are reported in \var{SocketError}, and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOTCONN] The socket isn't connected.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\item[SYS\_EFAULT] The address is outside your address space.
\item[SYS\_EMSGSIZE] The message cannot be sent atomically.
\item[SYS\_EWOULDBLOCK] The requested operation would block the process.
\item[SYS\_ENOBUFS] The system doesn't have enough free buffers available.
\end{description}
}{\seef{Send}}

\function{Bind}{(Sock:Longint;Var Addr;AddrLen:Longint)}{Boolean}
{\var{Bind} binds the socket \var{Sock} to address \var{Addr}. \var{Addr}
has length \var{Addrlen}.

The function returns \var{True} if the call was succesful, \var{False} if
not.
}
{Errors are returned in \var{SocketError} and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_EINVAL] The socket is already bound to an address,
\item[SYS\_EACCESS] Address is protected and you don't have permission to
open it.
\end{description}
More arrors can be found in the Unix man pages.
}{\seef{Socket}}

\functionl{Bind}{AltBind}{(Sock:longint;const addr:string)}{boolean}
{This is an alternate form of the \var{Bind} command.
This form of the \var{Bind} command is equivalent to subsequently 
calling \seep{Str2UnixSockAddr} and the regular \seef{Bind} function.

The function returns \var{True} if successfull, \var{False} otherwise.
}
{Errors are those of the regular \seef{Bind} command.}
{\seef{Bind}}


\function{Listen}{(Sock,MaxConnect:Longint)}{Boolean}
{\var{Listen} listens for up to \var{MaxConnect} connections from socket
\var{Sock}. The socket \var{Sock} must be of type \var{SOCK\_STREAM} or
\var{Sock\_SEQPACKET}.

The function returns \var{True} if a connection was accepted, \var{False} 
if an error occurred.
}
{Errors are reported in \var{SocketError}, and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\item[SYS\_EOPNOTSUPP] The socket type doesn't support the \var{Listen}
operation.
\end{description}
}{\seef{Socket}, \seef{Bind}, \seef{Connect}}

\function{Accept}{(Sock:Longint;Var Addr;Var Addrlen:Longint)}{Longint}
{\var{Accept} accepts a connection from a socket \var{Sock}, which was
listening for a connection. The accepted socket may NOT be used to accept
more connections. The original socket remains open.

The \var{Accept} call fills the address of the connecting entity in \var{Addr},
and sets its length in \var{Addrlen}. \var{Addr} should be pointing to
enough space, and \var{Addrlen} should be set to the amount of space
available, prior to the call.
}
{Errors are reported in \var{SocketError}, and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\item[SYS\_EOPNOTSUPP] The socket type doesn't support the \var{Listen}
operation.
\item[SYS\_EFAULT] \var{Addr} points outside your address space.
\item[SYS\_EWOULDBLOCK] The requested operation would block the process.
\end{description}
}
{\seef{Listen}, \seef{Connect}}

\input{sockex/sock_svr.tex}

\functionl{Accept}{AltAAccept}{(Sock:longint;var addr:string;var SockIn,SockOut:text)}{Boolean}
{ This is an alternate form of the \seef{Accept} command. It is equivalent
to subsequently calling the regular \seef{Accept}
function and the \seep{Sock2Text} function.

The function returns \var{True} if successfull, \var{False} otherwise.
}
{The errors are those of \seef{Accept}.}
{\seef{Accept}}

\functionl{Accept}{AltBAccept}{(Sock:longint;var addr:string;var SockIn,SockOut:File)}{Boolean}
{ This is an alternate form of the \seef{Accept} command. 
It is equivalent
to subsequently calling the regular \seef{Accept} function and the 
\seep{Sock2File} function.

The function returns \var{True} if successfull, \var{False} otherwise.
}
{The errors are those of \seef{Accept}.}
{\seef{Accept}}


\function{Connect}{(Sock:Longint;Var Addr;Addrlen:Longint)}{Boolean}
{\var{Connect} opens a connection to a peer, whose address is described by
var{Addr}. \var{AddrLen} contains the length of the address.

The type of \var{Addr} depends on the kind of connection you're trying to
make, but is generally one of \var{TSockAddr} or \var{TUnixSockAddr}.
}
{Errors are reported in \var{SocketError}.}
{\seef{Listen}, \seef{Bind},\seef{Accept}}

\input{sockex/sock_cli.tex}

\functionl{Connect}{AltAConnect}{(Sock:longint;const addr:string;var SockIn,SockOut:text)}{Boolean}
{ This is an alternate form of the \seef{Connect} command. 
It is equivalent
to subsequently calling the regular \seef{Connect} function and the 
\seep{Sock2Text} function.

The function returns \var{True} if successfull, \var{False} otherwise.
}{The errors are those of \seef{Connect}.}
{\seef{Connect}}

\functionl{Connect}{AltBConnect}{(Sock:longint;const addr:string;var SockIn,SockOut:file)}{Boolean}
{ This is an alternate form of the \seef{Connect} command. 
It is equivalent
to subsequently calling the regular \seef{Connect} function and the 
\seep{Sock2File} function.

The function returns \var{True} if successfull, \var{False} otherwise.
}{The errors are those of \seef{Connect}.}
{\seef{Connect}}


\function{Shutdown}{(Sock:Longint;How:Longint)}{Longint}
{\var{ShutDown} closes one end of a full duplex socket connection, described
by \var{Sock}. \var{How} determines how the connection will be shut down,
and can be one of the following:
\begin{description}
\item[0] : Further receives are disallowed.
\item[1] : Further sends are disallowed.
\item[2] : Sending nor receiving are allowed.
\end{description}

On succes, the function returns 0, on error -1 is returned.
}
{\var{SocketError} is used to report errors, and includes the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOTCONN] The socket isn't connected.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\end{description}
}{\seef{Socket}, \seef{Connect}}

\function{GetSocketName}{(Sock:Longint;Var Addr;Var Addrlen:Longint)}{Longint}
{\var{GetSockName} returns the current name of the specified socket
\var{Sock}. \var{Addr} should point to enough space to store the name, the
amount of space pointed to should be set in \var{Addrlen}. 
When the function returns succesfully, \var{Addr} will be filled with the 
name, and \var{Addrlen} will be set to the length of \var{Addr}.}
{Errors are reported in \var{SocketError}, and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOBUFS] The system doesn't have enough buffers to perform the
operation.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\item[SYS\_EFAULT] \var{Addr} points outside your address space.
\end{description}
}{\seef{Bind}}

\function{GetPeerName}{(Sock:Longint;Var Addr;Var Addrlen:Longint)}{Longint}
{\var{GetPeerName} returns the name of the entity connected to the 
specified socket \var{Sock}. The Socket must be connected for this call to
work. 
\var{Addr} should point to enough space to store the name, the
amount of space pointed to should be set in \var{Addrlen}. 
When the function returns succesfully, \var{Addr} will be filled with the 
name, and \var{Addrlen} will be set to the length of \var{Addr}.
}
{Errors are reported in \var{SocketError}, and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOBUFS] The system doesn't have enough buffers to perform the
operation.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\item[SYS\_EFAULT] \var{Addr} points outside your address space.
\item[SYS\_ENOTCONN] The socket isn't connected.
\end{description}
}{\seef{Connect}, \seef{Socket}, \seem{connect}{2}}

\function{SetSocketOptions}{(Sock,Level,OptName:Longint;Var OptVal;optlen:longint)}{Longint}
{\var{SetSocketOptions} sets the connection options for socket \var{Sock}.
The socket may be manipulated at different levels, indicated by \var{Level},
which can be one of the following:
\begin{description}
\item[SOL\_SOCKET] To manipulate the socket itself. 
\item[XXX] set \var{Level} to \var{XXX}, the protocol number of the protocol
which should interprete the option.
 \end{description}
For more information on this call, refer to the unix manual page \seem{setsockopt}{2}.
}
{Errors are reported in \var{SocketError}, and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\item[SYS\_EFAULT] \var{OptVal} points outside your address space.
\end{description}
}
{\seef{GetSocketOptions}}

\function{GetSocketOptions}{(Sock,Level,OptName:Longint;Var OptVal;optlen:longint)}{Longint}
{\var{GetSocketOptions} gets the connection options for socket \var{Sock}.
The socket may be obtained from different levels, indicated by \var{Level},
which can be one of the following:
\begin{description}
\item[SOL\_SOCKET] From the socket itself. 
\item[XXX] set \var{Level} to \var{XXX}, the protocol number of the protocol
which should interprete the option.
 \end{description}
For more information on this call, refer to the unix manual page \seem{getsockopt}{2}.
}
{Errors are reported in \var{SocketError}, and include the following:
\begin{description}
\item[SYS\_EBADF] The socket descriptor is invalid.
\item[SYS\_ENOTSOCK] The descriptor is not a socket.
\item[SYS\_EFAULT] \var{OptVal} points outside your address space.
\end{description}
}
{\seef{GetSocketOptions}}

\function{SocketPair}{(Domain,SocketType,Protocol:Longint;var Pair:TSockArray)}{Longint}
{\var{SocketPair} creates 2 sockets in domain \var{Domain}, from type
\var{SocketType} and using protocol \var{Protocol}.

The pair is returned in \var{Pair}, and they are indistinguishable.

The function returns -1 upon error and 0 upon success.
}
{Errors are reported in \var{SocketError}, and are the same as in \seef{Socket}}

\procedure{Sock2Text}{(Sock:Longint;Var SockIn,SockOut: Text)}
{\var{Sock2Text} transforms a socket \var{Sock} into 2 Pascal file
descriptors of type \var{Text}, one for reading from the socket
(\var{SockIn}), one for writing to the socket (\var{SockOut}).}
{None.}
{\seef{Socket}, \seep{Sock2File}}

\procedure{Sock2File}{(Sock:Longint;Var SockIn,SockOut:File)}
{\var{Sock2File} transforms a socket \var{Sock} into 2 Pascal file
descriptors of type \var{File}, one for reading from the socket
(\var{SockIn}), one for writing to the socket (\var{SockOut}).}
{None.}
{\seef{Socket}, \seep{Sock2Text}}

\procedure{Str2UnixSockAddr}{(const addr:string;var t:TUnixSockAddr;var len:longint)}
{\var{Str2UnixSockAddr} transforms a Unix socket address in a string to a
\var{TUnixSockAddr} sturcture which can be passed to the \seef{Bind} call.
}
{None.}
{\seef{Socket}, \seef{Bind}}
