Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
sa(3)			      Socket Abstraction			 sa(3)

NAME
       OSSP sa - Socket	Abstraction

VERSION
       OSSP sa 1.2.5 (02-Oct-2005)

SYNOPSIS
       Abstract	Data Types:
	   sa_rc_t, sa_addr_t, sa_t.

       Address Object Operations:
	   sa_addr_create, sa_addr_destroy.

       Address Operations:
	   sa_addr_u2a,	sa_addr_s2a, sa_addr_a2u, sa_addr_a2s, sa_addr_match.

       Socket Object Operations:
	   sa_create, sa_destroy.

       Socket Parameter	Operations:
	   sa_type, sa_timeout,	sa_buffer, sa_option, sa_syscall.

       Socket Connection Operations:
	   sa_bind, sa_connect,	sa_listen, sa_accept, sa_getremote, sa_getlo-
	   cal,	sa_shutdown.

       Socket Input/Output Operations (Stream Communication):
	   sa_getfd, sa_read, sa_readln, sa_write, sa_writef, sa_flush.

       Socket Input/Output Operations (Datagram	Communication):
	   sa_recv, sa_send, sa_sendf.

       Socket Error Handling:
	   sa_error.

DESCRIPTION
       OSSP sa is an abstraction library for the Unix Socket networking	appli-
       cation programming interface (API), featuring stream and	datagram ori-
       ented communication over	Unix Domain and	Internet Domain	(TCP and UDP)
       sockets.

       It provides the following key features:

       Stand-Alone, Self-Contained, Embeddable
	   Although there are various Open Source libraries available which
	   provide a similar abstraction approach, they	all either lack	impor-
	   tant	features or unfortunately depend on other companion libraries.
	   OSSP	sa fills this gap by providing all important features (see
	   following points) as	a stand-alone and fully	self-contained li-
	   brary. This way OSSP	sa can be trivially embedded as	a sub-library
	   into	other libraries. It especially provides	additional support for
	   namespace-safe embedding of its API in order	to avoid symbol	con-
	   flicts (see SA_PREFIX in sa.h).

       Address Abstraction
	   Most	of the ugliness	in the Unix Socket API is the necessity	to
	   have	to deal	with the various address structures (struct sock-
	   addr_xx) which exist	because	of both	the different communication
	   types and addressing	schemes. OSSP sa fully hides this by providing
	   an abstract and opaque address type (sa_addr_t) together with util-
	   ity functions which allow one to convert from the traditional
	   struct sockaddr or URI specification	to the sa_addr_t and vice
	   versa without having	to deal	with special cases related to the un-
	   derlying particular struct sockaddr_xx. OSSP	sa support Unix	Domain
	   and both IPv4 and IPv6 Internet Domain addressing.

       Type Abstraction
	   Some	other subtle details in	the Unix Socket	API make the life hard
	   in practice:	socklen_t and ssize_t. These two types originally were
	   (and	on some	platforms still	are) plain integers or unsigned	inte-
	   gers	while POSIX later introduced own types for them	(and even re-
	   vised these types after some	time again). This is nasty, because
	   for 100% type-correct API usage (especially important on 64-bit ma-
	   chines where	pointers to different integer types make trouble), ev-
	   ery application has to check	whether	the newer types	exists,	and if
	   not provide own definitions which map to the	still actually used
	   integer type	on the underlying platform. OSSP sa hides most of this
	   in its API and for socklen_t	provides a backward-compatibility def-
	   inition.  Instead of	ssize_t	it can use size_t because OSSP sa does
	   not use traditional Unix return code	semantics.

       I/O Timeouts
	   Each	I/O function in	OSSP sa	is aware of timeouts (set by sa_time-
	   out(3)), i.e., all I/O operations return SA_ERR_TMT if the timeout
	   expired before the I/O operation was	able to	succeed.  This allows
	   one to easily program less-blocking network services.  OSSP sa in-
	   ternally implements these timeouts either through the
	   SO_{SND,RCV}TIMEO feature on	more modern Socket implementations or
	   through traditional select(2). This way high	performance is
	   achieved on modern platforms	while the full functionality still is
	   available on	older platforms.

       I/O Stream Buffering
	   If OSSP sa is used for stream communication,	internally all I/O op-
	   erations can	be performed through input and/or output buffers (set
	   by sa_buffer(3)) for	achieving higher I/O performance by doing I/O
	   operations on larger	aggregated messages and	with less required
	   system calls. Additionally if OSSP sa is used for stream communica-
	   tion, for convenience reasons line-oriented reading (sa_readln(3))
	   and formatted writing (see sa_writef(3)) is provided, modelled af-
	   ter STDIO's fgets(3)	and fprintf(3).	Both features fully leverage
	   from	the I/O	buffering.

DATA TYPES
       OSSP sa uses three data types in	its API:

       sa_rc_t (Return Code Type)
	   This	is an exported enumerated integer type with the	following pos-
	   sible values:

	    SA_OK	Everything Ok
	    SA_ERR_ARG	Invalid	Argument
	    SA_ERR_USE	Invalid	Use Or Context
	    SA_ERR_MEM	Not Enough Memory
	    SA_ERR_MTC	Matching Failed
	    SA_ERR_EOF	End Of Communication
	    SA_ERR_TMT	Communication Timeout
	    SA_ERR_SYS	Operating System Error (see errno)
	    SA_ERR_IMP	Implementation Not Available
	    SA_ERR_INT	Internal Error

       sa_addr_t (Socket Address Abstraction Type)
	   This	is an opaque data type representing a socket address.  Only
	   pointers to this abstract data type are used	in the API.

       sa_t (Socket Abstraction	Type)
	   This	is an opaque data type representing a socket.  Only pointers
	   to this abstract data type are used in the API.

FUNCTIONS
       OSSP sa provides	a bunch	of API functions, all modelled after the same
       prototype:

       sa_rc_t sa_name(sa_[addr_]_t *, ...)

       This means, every function returns sa_rc_t to indicate its success
       (SA_OK) or failure (SA_ERR_XXX) by returning a return code (the corre-
       sponding	describing text	can be determined by passing this return code
       to sa_error(3)).	Each function name starts with the common prefix sa_
       and receives a sa_t (or sa_addr_t) object handle	on which it operates
       as its first argument.

       Address Object Operations

       This API	part provides operations for the creation and destruction of
       address abstraction sa_addr_t.

       sa_rc_t sa_addr_create(sa_addr_t	**saa);
	   Create a socket address abstraction object.	The object is stored
	   in saa on success.

	   Example: sa_addr_t *saa; sa_addr_create(&saa);

       sa_rc_t sa_addr_destroy(sa_addr_t *saa);
	   Destroy a socket address abstraction	object.	 The object saa	is in-
	   valid after this call succeeded.

	   Example: sa_addr_destroy(saa);

       Address Operations

       This API	part provides operations for working with the address abstrac-
       tion sa_addr_t.

       sa_rc_t sa_addr_u2a(sa_addr_t *saa, const char *uri, ...);
	   Import an address into by converting	from an	URI specification to
	   the corresponding address abstraction.

	   The supported syntax	for uri	is: "unix:path"	for Unix Domain	ad-
	   dresses and "inet://addr:port[#protocol]" for Internet Domain ad-
	   dresses.

	   In the URI, path can	be an absolute or relative filesystem path to
	   an existing or not-existing file. addr can be an IPv4 address in
	   dotted decimal notation ("127.0.0.1"), an IPv6 address in colon-
	   separated (optionally abbreviated) hexadecimal notation ("::1") or
	   a to-be-resolved hostname ("localhost.example.com").	port has to be
	   either a decimal port in the	range 1...65535	or a port name
	   ("smtp"). If	port is	specified as a name, it	is resolved as a TCP
	   port	by default. To force resolving a port name via a particular
	   protocol, protocol can be specified as either "tcp" or "udp".

	   The result is stored	in saa on success.

	   Example: sa_addr_u2a(saa, "inet://192.168.0.1:smtp");

       sa_rc_t sa_addr_s2a(sa_addr_t *saa, const struct	sockaddr *sabuf,
       socklen_t salen);
	   Import an address by	converting from	a traditional struct sockaddr
	   object to the corresponding address abstraction.

	   The accepted	addresses for sabuf are: struct	sockaddr_un (AF_LO-
	   CAL), struct	sockaddr_in (AF_INET) and struct sockaddr_in6
	   (AF_INET6). The salen is the	corresponding sizeof(...) of the par-
	   ticular underyling structure.

	   The result is stored	in saa on success.

	   Example: sockaddr_in	in; sa_addr_s2a(saa, (struct sockaddr *)&in,
	   (socklen_t)sizeof(in));

       sa_rc_t sa_addr_a2u(sa_addr_t *saa, char	**uri);
	   Export an address by	converting from	the address abstraction	to the
	   corresponding URI specification.

	   The result is a string of the form "unix:path" for Unix Domain ad-
	   dresses and "inet://addr:port" for Internet Domain addresses. No-
	   tice	that addr and port are returned	in numerical (unresolved) way.
	   Additionally, because usually one cannot map	bidirectionally	be-
	   tween TCP or	UDP port names and the numerical value,	there is no
	   distinction between TCP and UDP here.

	   The result is stored	in uri on success.  The	caller has to free(3)
	   the uri buffer later.

	   Example: char *uri; sa_addr_a2u(saa,	&uri);

       sa_rc_t sa_addr_a2s(sa_addr_t *saa, struct sockaddr **sabuf, socklen_t
       *salen);
	   Export an address by	converting from	the address abstraction	to the
	   corresponding traditional struct sockaddr object.

	   The result is one of	the following particular underlying address
	   structures: struct sockaddr_un (AF_LOCAL), struct sockaddr_in
	   (AF_INET) and struct	sockaddr_in6 (AF_INET6).

	   The result is stored	in sabuf and salen on success.	The caller has
	   to free(3) the sabuf	buffer later.

	   Example: struct sockaddr sabuf, socklen_t salen; sa_addr_a2s(saa,
	   &sa,	&salen);

       sa_rc_t sa_addr_match(sa_addr_t *saa1, sa_addr_t	*saa2, size_t pre-
       fixlen);
	   Match two address abstractions up to	a specified prefix.

	   This	compares the addresses saa1 and	saa2 by	only taking the	prefix
	   part	of length prefixlen into account. prefixlen is number of
	   filesystem path characters for Unix Domain addresses	and number of
	   bits	for Internet Domain addresses. In case of Internet Domain ad-
	   dresses, the	addresses are matched in network byte order and	the
	   port	(counting as an	additional bit/item of length 1) is virtually
	   appended to the address for matching. Specifying prefixlen as -1
	   means matching the whole address (but without the virtually ap-
	   pended port)	without	having to know how long	the underlying address
	   representation (length of path for Unix Domain addresses, 32+1
	   [IPv4] or 128+1 [IPv6] for Internet Domain addresses) is. Specify-
	   ing prefixlen as -2 is equal	to -1 but additionally the port	is
	   matched, too.

	   This	especially can be used to implement Access Control Lists (ACL)
	   without having to fiddle around with	the underlying representation.
	   For this, make saa1 the to be checked address and saa2 plus pre-
	   fixlen the ACL pattern as shown in the following example.

	   Example:

	    sa_addr_t *srv_sa;
	    sa_addr_t *clt_saa;
	    sa_t      *clt_sa;
	    sa_addr_t *acl_saa;
	    char      *acl_addr	= "192.168.0.0";
	    int	       acl_len	= 24;
	    ...
	    sa_addr_u2a(&acl_saa, "inet://%s:0", acl_addr);
	    ...
	    while (sa_accept(srv_sa, &clt_saa, &clt_sa)	== SA_OK) {
		if (sa_addr_match(clt_saa, acl_saa, acl_len) !=	SA_OK) {
		    /* connection refused */
		    ...
		    sa_addr_destroy(clt_saa);
		    sa_destroy(clt_sa);
		    continue;
		}
		...
	    }
	    ...

       Socket Object Operations

       This API	part provides operations for the creation and destruction of
       socket abstraction sa_t.

       sa_rc_t sa_create(sa_t **sa);
	   Create a socket abstraction object.	The object is stored in	sa on
	   success.

	   Example: sa_t *sa; sa_create(&sa);

       sa_rc_t sa_destroy(sa_t *sa);
	   Destroy a socket abstraction	object.	 The object sa is invalid af-
	   ter this call succeeded.

	   Example: sa_destroy(sa);

       Socket Parameter	Operations

       This API	part provides operations for parameterizing the	socket ab-
       straction sa_t.

       sa_rc_t sa_type(sa_t *sa, sa_type_t type);
	   Assign a particular communication protocol type to the socket ab-
	   straction object.

	   A socket can	only be	assigned a single protocol type	at any time.
	   Nevertheless	one can	switch the type	of a socket abstraction	object
	   at any time in order	to reuse it for	a different communication.
	   Just	keep in	mind that switching the	type will stop a still ongoing
	   communication by closing the	underlying socket.

	   Possible values for type are	SA_TYPE_STREAM (stream communication)
	   and SA_TYPE_DATAGRAM	(datagram communication). The default communi-
	   cation protocol type	is SA_TYPE_STREAM.

	   Example: sa_type(sa,	SA_TYPE_STREAM);

       sa_rc_t sa_timeout(sa_t *sa, sa_timeout_t id, long sec, long usec);
	   Assign one or more communication timeouts to	the socket abstraction
	   object.

	   Possible values for id are: SA_TIMEOUT_ACCEPT (affecting sa_ac-
	   cept(3)), SA_TIMEOUT_CONNECT	(affecting sa_connect(3)), SA_TIME-
	   OUT_READ (affecting sa_read(3), sa_readln(3)	and sa_recv(3))	and
	   SA_TIMEOUT_WRITE (affecting sa_write(3), sa_writef(3), sa_send(3),
	   and sa_sendf(3)). Additionally you can set all four timeouts	at
	   once	by using SA_TIMEOUT_ALL. The default is	that no	communication
	   timeouts are	used which is equal to sec=0/usec=0.

	   Example: sa_timeout(sa, SA_TIMEOUT_ALL, 30, 0);

       sa_rc_t sa_buffer(sa_t *sa, sa_buffer_t id, size_t size);
	   Assign I/O communication buffers to the socket abstraction object.

	   Possible values for id are: SA_BUFFER_READ (affecting sa_read(3)
	   and sa_readln(3)) and SA_BUFFER_WRITE (affecting sa_write(3)	and
	   sa_writef(3)). The default is that no communication buffers are
	   used	which is equal to size=0.

	   Example: sa_buffer(sa, SA_BUFFER_READ, 16384);

       sa_rc_t sa_option(sa_t *sa, sa_option_t id, ...);
	   Adjust various options of the socket	abstraction object.

	   The adjusted	option is controlled by	id. The	number and type	of the
	   expected following argument(s) are dependent	on the particular op-
	   tion.  Currently the	following options are implemented (option ar-
	   guments in parenthesis):

	   SA_OPTION_NAGLE (int	yesno) for enabling (yesno=1) or disabling
	   (yesno == 0)	Nagle's	Algorithm (see RFC898 and TCP_NODELAY of set-
	   sockopt(2)).

	   SA_OPTION_LINGER (int amount) for enabling (amount == seconds != 0)
	   or disabling	(amount	== 0) lingering	on close (see SO_LINGER	of
	   setsockopt(2)). Notice: using seconds > 0 results in	a regular
	   (maximum of seconds lasting)	lingering on close while using seconds
	   < 0 results in the special case of a	TCP RST	based connection ter-
	   mination on close.

	   SA_OPTION_REUSEADDR (int yesno) for enabling	(yesno == 1) or	dis-
	   abling (yesno == 0) the reusability of the address on binding via
	   sa_bind(3) (see SO_REUSEADDR	of setsockopt(2)).

	   SA_OPTION_REUSEPORT (int yesno) for enabling	(yesno == 1) or	dis-
	   abling (yesno == 0) the reusability of the port on binding via
	   sa_bind(3) (see SO_REUSEPORT	of setsockopt(2)).

	   SA_OPTION_NONBLOCK (int yesno) for enabling (yesno == 1) or dis-
	   abling (yesno == 0) non-blocking I/O	mode (see O_NONBLOCK of	fc-
	   ntl(2)).

	   Example: sa_option(sa, SA_OPTION_NONBLOCK, 1);

       sa_rc_t sa_syscall(sa_t *sa, sa_syscall_t id, void (*fptr)(), void
       *fctx);
	   Divert I/O communication related system calls to user supplied
	   callback functions.

	   This	allows you to override mostly all I/O related system calls
	   OSSP	sa internally performs while communicating. This can be	used
	   to adapt OSSP sa to different run-time environments and require-
	   ments without having	to change the source code. Usually this	is
	   used	to divert the system calls to the variants of a	user-land mul-
	   tithreading facility	like GNU Pth.

	   The function	supplied as fptr is required to	fulfill	the API	of the
	   replaced system call, i.e., it has to have the same prototype (if
	   fctx	is NULL). If fctx is not NULL, this prototype has to be	ex-
	   tended to accept an additional first	argument of type void *	which
	   receives the	value of fctx. It is up	to the callback	function
	   whether to pass the call through to the replaced actual system call
	   or not.

	   Possible values for id are (expected	prototypes behind fptr are
	   given in parenthesis):

	   SA_SYSCALL_CONNECT: "int (*)([void *,] int, const struct sockaddr
	   *, socklen_t)", see connect(2).

	   SA_SYSCALL_ACCEPT: "int (*)([void *,] int, struct sockaddr *,
	   socklen_t *)", see accept(2).

	   SA_SYSCALL_SELECT: "int (*)([void *,] int, fd_set *,	fd_set *,
	   fd_set *, struct timeval *)", see select(2).

	   SA_SYSCALL_READ: "ssize_t (*)([void *,] int,	void *,	size_t)", see
	   read(2).

	   SA_SYSCALL_WRITE: "ssize_t (*)([void	*,] int, const void *,
	   size_t)", see write(2).

	   SA_SYSCALL_RECVFROM:	"ssize_t (*)([void *,] int, void *, size_t,
	   int,	struct sockaddr	*, socklen_t *)", see recvfrom(2).

	   SA_SYSCALL_SENDTO: "ssize_t (*)([void *,] int, const	void *,
	   size_t, int,	const struct sockaddr *, socklen_t)", see sendto(2).

	   Example:

	    ssize_t
	    trace_read(void *ctx, int fd, void *buf, size_t len)
	    {
		FILE *fp = (FILE *)ctx;
		ssize_t	rv;
		int errno_saved;

		rv = read(fd, buf, len);
		errno_saved = errno;
		fprintf(fp, "read(%d, %lx, %d) = %d\n",
			fd, (long)buf, len, rv);
		errno =	errno_saved;
		return rv;
	    }

	    ...
	    FILE *trace_fp = ...;
	    sa_syscall(sa, SA_SC_READ, trace_read, trace_fp);
	    ...

       Socket Connection Operations

       This API	part provides connection operations for	stream-oriented	data
       communication through the socket	abstraction sa_t.

       sa_rc_t sa_bind(sa_t *sa, sa_addr_t *laddr);
	   Bind	socket abstraction object to a local protocol address.

	   This	assigns	the local protocol address laddr. When a socket	is
	   created, it exists in an address family space but has no protocol
	   address assigned. This call requests	that laddr be used as the lo-
	   cal address.	For servers this is the	address	they later listen on
	   (see	sa_listen(3)) for incoming connections,	for clients this is
	   the address used for	outgoing connections (see sa_connect(3)). In-
	   ternally this directly maps to bind(2).

	   Example: sa_bind(sa,	laddr);

       sa_rc_t sa_connect(sa_t *sa, sa_addr_t *raddr);
	   Initiate an outgoing	connection on a	socket abstraction object.

	   This	performs a connect to the remote address raddr.	If the socket
	   is of type SA_TYPE_DATAGRAM,	this call specifies the	peer with
	   which the socket is to be associated; this address is that to which
	   datagrams are to be sent, and the only address from which datagrams
	   are to be received. If the socket is	of type	SA_TYPE_STREAM,	this
	   call	attempts to make a connection to the remote socket. Internally
	   this	directly maps to connect(2).

	   Example: sa_connect(sa, raddr);

       sa_rc_t sa_listen(sa_t *sa, int backlog);
	   Listen for incoming connections on a	socket abstraction object.

	   A willingness to accept incoming connections	and a queue limit for
	   incoming connections	are specified by this call. The	backlog	argu-
	   ment	defines	the maximum length the queue of	pending	connections
	   may grow to.	 Internally this directly maps to listen(2).

	   Example: sa_listen(sa, 128);

       sa_rc_t sa_accept(sa_t *sa, sa_addr_t **caddr, sa_t **csa);
	   Accept incoming connection on a socket abstraction object.

	   This	accepts	an incoming connection by extracting the first connec-
	   tion	request	on the queue of	pending	connections. It	creates	a new
	   socket abstraction object (returned in csa) and a new socket	ad-
	   dress abstraction object (returned in caddr)	describing the connec-
	   tion. The caller has	to destroy these objects later.	If no pending
	   connections are present on the queue, it blocks the caller until a
	   connection is present.

	   Example:

	    sa_addr_t *clt_saa;
	    sa_t      *clt_sa;
	    ...
	    while (sa_accept(srv_sa, &clt_saa, &clt_sa)	== SA_OK) {
		...
	    }

       sa_rc_t sa_getremote(sa_t *sa, sa_addr_t	**raddr);
	   Get address abstraction of remote side of communication.

	   This	determines the address of the communication peer and creates a
	   new socket address abstraction object (returned in raddr) describ-
	   ing the peer	address. The application has to	destroy	raddr later
	   with	sa_addr_destroy(3). Internally this maps to getpeername(2).

	   Example: sa_addr_t *raddr; sa_getremote(sa, &raddr);

       sa_rc_t sa_getlocal(sa_t	*sa, sa_addr_t **laddr);
	   Get address abstraction of local side of communication.

	   This	determines the address of the local communication side and
	   creates a new socket	address	abstraction object (returned in	laddr)
	   describing the local	address. The application has to	destroy	laddr
	   later with sa_addr_destroy(3). Internally this maps to getsock-
	   name(2).

	   Example: sa_addr_t *laddr; sa_getlocal(sa, &laddr);

       sa_rc_t sa_shutdown(sa_t	*sa, char *flags);
	   Shut	down part of the full-duplex connection.

	   This	performs a shut	down of	the connection described in sa.	The
	   flags string	can be either "r" (indicating the read channel of the
	   communication is shut down only), "w" (indicating the write channel
	   of the communication	is shut	down only), or "rw" (indicating	both
	   the read and	write channels of the communication are	shut down).
	   Internally this directly maps to shutdown(2).

	   Example: sa_shutdown(sa, "w");

       Socket Input/Output Operations (Stream Communication)

       This API	part provides I/O operations for stream-oriented data communi-
       cation through the socket abstraction sa_t.

       sa_rc_t sa_getfd(sa_t *sa, int *fd);
	   Get underlying socket filedescriptor.

	   This	peeks into the underlying socket filedescriptor	OSSP sa	allo-
	   cated internally for	the communication. This	can be used for	ad-
	   justing the socket communication (via fcntl(2), setsockopt(2), etc)
	   directly.

	   Think twice before using this, then think once more.	After all
	   that, think again. With enough thought, the need for	directly ma-
	   nipulating the underlying socket can	often be eliminated. At	least
	   remember that all your direct socket	operations fully by-pass OSSP
	   sa and this way can leads to	nasty side-effects.

	   Example: int	fd; sa_getfd(sa, &fd);

       sa_rc_t sa_read(sa_t *sa, char *buf, size_t buflen, size_t *bufdone);
	   Read	a chunk	of data	from socket into own buffer.

	   This	reads from the socket (optionally through the internal read
	   buffer) up to a maximum of buflen bytes into	buffer buf. The	actual
	   number of read bytes	is stored in bufdone. This internally maps to
	   read(2).

	   Example: char buf[1024]; size_t n; sa_read(sa, buf, sizeof(buf),
	   &n);

       sa_rc_t sa_readln(sa_t *sa, char	*buf, size_t buflen, size_t *bufdone);
	   Read	a line of data from socket into	own buffer.

	   This	reads from the socket (optionally through the internal read
	   buffer) up to a maximum of buflen bytes into	buffer buf, but	only
	   as long as no line terminating newline character (0x0a) was found.
	   The line terminating	newline	character is stored in the buffer plus
	   a (not counted) terminating NUL character ('\0'), too. The actual
	   number of read bytes	is stored in bufdone. This internally maps to
	   sa_read(3).

	   Keep	in mind	that for efficiency reasons, line-oriented I/O usually
	   always should be performed with read	buffer (see sa_option(3) and
	   SA_BUFFER_READ). Without such a read	buffer,	the performance	is
	   cruel, because single character read(2) operations would be per-
	   formed on the underlying socket.

	   Example: char buf[1024]; size_t n; sa_readln(sa, buf, sizeof(buf),
	   &n);

       sa_rc_t sa_write(sa_t *sa, const	char *buf, size_t buflen, size_t *buf-
       done);
	   Write a chunk of data to socket from	own buffer.

	   This	writes to the socket (optionally through the internal write
	   buffer) buflen bytes	from buffer buf. In case of a partial write,
	   the actual number of	written	bytes is stored	in bufdone. This in-
	   ternally maps to write(2).

	   Example: sa_write(sa, cp, strlen(cp), NULL);

       sa_rc_t sa_writef(sa_t *sa, const char *fmt, ...);
	   Write formatted data	data to	socket.

	   This	formats	a string according to the printf(3)-style format spec-
	   ification fmt and sends the result to the socket (optionally
	   through the internal	write buffer). In case of a partial socket
	   write, the not written data of the formatted	string is internally
	   discarded. Hence using a write buffer is strongly recommended here
	   (see	sa_option(3) and SA_BUFFER_WRITE). This	internally maps	to
	   sa_write(3).

	   The underlying string formatting engine is just a minimal one and
	   for security	and independence reasons intentionally not directly
	   based on s[n]printf(3). It understands only the following format
	   specifications: "%%", "%c" (char), "%s" (char *) and	"%d" (int)
	   without any precision and padding possibilities. It is intended for
	   minimal formatting only. If you need	more sophisticated formatting,
	   you have to format first into an own	buffer via s[n]printf(3) and
	   then	write this to the socket via sa_write(3) instead.

	   Example: sa_writef(sa, "%s=%d\n", cp, i);

       sa_rc_t sa_flush(sa_t *sa);
	   Flush still pending outgoing	data to	socket.

	   This	writes all still pending outgoing data for the internal	write
	   buffer (see sa_option(3) and	SA_BUFFER_WRITE) to the	socket.	This
	   internally maps to write(2).

	   Example: sa_flush(sa);

       Socket Input/Output Operations (Datagram	Communication)

       This API	part provides I/O operations for datagram-oriented data	commu-
       nication	through	the socket abstraction sa_t.

       sa_rc_t sa_recv(sa_t *sa, sa_addr_t **raddr, char *buf, size_t buflen,
       size_t *bufdone);
	   Receive a chunk of data from	remote address via socket into own
	   buffer.

	   This	receives from the remote address specified in raddr via	the
	   socket up to	a maximum of buflen bytes into buffer buf. The actual
	   number of received bytes is stored in bufdone. This internally maps
	   to recvfrom(2).

	   Example: char buf[1024]; size_t n; sa_recv(sa, buf, sizeof(buf),
	   &n, saa);

       sa_rc_t sa_send(sa_t *sa, sa_addr_t *raddr, const char *buf, size_t bu-
       flen, size_t *bufdone);
	   Send	a chunk	of data	to remote address via socket from own buffer.

	   This	sends to the remote address specified in raddr via the socket
	   buflen bytes	from buffer buf. The actual number of sent bytes is
	   stored in bufdone. This internally maps to sendto(2).

	   Example: sa_send(sa,	buf, strlen(buf), NULL,	saa);

       sa_rc_t sa_sendf(sa_t *sa, sa_addr_t *raddr, const char *fmt, ...);
	   Send	formatted data data to remote address via socket.

	   This	formats	a string according to the printf(3)-style format spec-
	   ification fmt and sends the result to the socket as a single	piece
	   of data chunk. In case of a partial socket write, the not written
	   data	of the formatted string	is internally discarded.

	   The underlying string formatting engine is just a minimal one and
	   for security	and independence reasons intentionally not directly
	   based on s[n]printf(3). It understands only the following format
	   specifications: "%%", "%c" (char), "%s" (char *) and	"%d" (int)
	   without any precision and padding possibilities. It is intended for
	   minimal formatting only. If you need	more sophisticated formatting,
	   you have to format first into an own	buffer via s[n]printf(3) and
	   then	send this to the remote	address	via sa_send(3) instead.

	   Example: sa_sendf(sa, saa, "%s=%d\n", cp, i);

       Socket Error Handling

       This API	part provides error handling operations	only.

       char *sa_error(sa_rc_t rv);
	   Return the string representation corresponding to the return	code
	   value rv. The returned string has to	be treated read-only by	the
	   application and is not required to be deallocated.

SEE ALSO
       Standards

       R. Gilligan, S. Thomson,	J. Bound, W. Stevens: "Basic Socket Interface
       Extensions for IPv6", RFC 2553, March 1999.

       W. Stevens: "Advanced Sockets API for IPv6", RFC	2292, February 1998.

       R. Fielding, L. Masinter, T. Berners-Lee: "Uniform Resource Identi-
       fiers: Generic Syntax", RFC 2396, August	1998.

       R. Hinden, S. Deering: "IP Version 6 Addressing Architecture", RFC
       2373, July 1998.

       R. Hinden, B. Carpenter,	L. Masinter: "Format for Literal IPv6 Ad-
       dresses in URL's", RFC 2732, December 1999.

       Papers

       Stuart Sechrest:	"An Introductory 4.4BSD	Interprocess Communication Tu-
       torial",	FreeBSD	4.4 (/usr/share/doc/psd/20.ipctut/).

       Samuel J. Leffler, Robert S. Fabry, William N. Joy, Phil	Lapsley: "An
       Advanced	4.4BSD Interprocess Communication Tutorial", FreeBSD 4.4
       (/usr/share/doc/psd/21.ipc/).

       Craig Metz: "Protocol Independence Using	the Sockets API",
       http://www.usenix.org/publications/library/proceed-
       ings/usenix2000/freenix/metzprotocol.html, USENIX Annual	Technical Con-
       ference,	June 2000.

       Manual Pages

       socket(2), accept(2), bind(2), connect(2), getpeername(2), getsock-
       name(2),	getsockopt(2), ioctl(2), listen(2), read(2), recv(2), se-
       lect(2),	send(2), shutdown(2), socketpair(2), write(2), getprotoent(3),
       protocols(4).

HISTORY
       OSSP sa was invented in August 2001 by Ralf S. Engelschall <rse@en-
       gelschall.com> under contract with Cable	& Wireless
       <http://www.cw.com/> for	use inside the OSSP project. Its creation was
       prompted	by the requirement to implement	an SMTP	logging	channel	for
       the OSSP	l2 library. Its	initial	code was derived from a	predecessor
       sub-library originally written for socket address abstraction inside
       the OSSP	lmtp2nntp tool.

AUTHOR
	Ralf S.	Engelschall
	rse@engelschall.com
	www.engelschall.com

02-Oct-2005			 OSSP sa 1.2.5				 sa(3)

NAME | VERSION | SYNOPSIS | DESCRIPTION | DATA TYPES | FUNCTIONS | SEE ALSO | HISTORY | AUTHOR

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=sa&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help