~ubuntu-branches/ubuntu/trusty/osspsa/trusty

« back to all changes in this revision

Viewing changes to sa-1.2.2.orig/sa.3

  • Committer: Bazaar Package Importer
  • Author(s): Raphael Bossek
  • Date: 2005-04-24 11:46:57 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050424114657-b9azplzw1aw4viba
Tags: 1.2.4-1
Update to new upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
2
 
.\"
3
 
.\" Standard preamble:
4
 
.\" ========================================================================
5
 
.de Sh \" Subsection heading
6
 
.br
7
 
.if t .Sp
8
 
.ne 5
9
 
.PP
10
 
\fB\\$1\fR
11
 
.PP
12
 
..
13
 
.de Sp \" Vertical space (when we can't use .PP)
14
 
.if t .sp .5v
15
 
.if n .sp
16
 
..
17
 
.de Vb \" Begin verbatim text
18
 
.ft CW
19
 
.nf
20
 
.ne \\$1
21
 
..
22
 
.de Ve \" End verbatim text
23
 
.ft R
24
 
.fi
25
 
..
26
 
.\" Set up some character translations and predefined strings.  \*(-- will
27
 
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
28
 
.\" double quote, and \*(R" will give a right double quote.  | will give a
29
 
.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
30
 
.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
31
 
.\" expand to `' in nroff, nothing in troff, for use with C<>.
32
 
.tr \(*W-|\(bv\*(Tr
33
 
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
34
 
.ie n \{\
35
 
.    ds -- \(*W-
36
 
.    ds PI pi
37
 
.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
38
 
.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
39
 
.    ds L" ""
40
 
.    ds R" ""
41
 
.    ds C` 
42
 
.    ds C' 
43
 
'br\}
44
 
.el\{\
45
 
.    ds -- \|\(em\|
46
 
.    ds PI \(*p
47
 
.    ds L" ``
48
 
.    ds R" ''
49
 
'br\}
50
 
.\"
51
 
.\" If the F register is turned on, we'll generate index entries on stderr for
52
 
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
53
 
.\" entries marked with X<> in POD.  Of course, you'll have to process the
54
 
.\" output yourself in some meaningful fashion.
55
 
.if \nF \{\
56
 
.    de IX
57
 
.    tm Index:\\$1\t\\n%\t"\\$2"
58
 
..
59
 
.    nr % 0
60
 
.    rr F
61
 
.\}
62
 
.\"
63
 
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
64
 
.\" way too many mistakes in technical documents.
65
 
.hy 0
66
 
.if n .na
67
 
.\"
68
 
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
69
 
.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
70
 
.    \" fudge factors for nroff and troff
71
 
.if n \{\
72
 
.    ds #H 0
73
 
.    ds #V .8m
74
 
.    ds #F .3m
75
 
.    ds #[ \f1
76
 
.    ds #] \fP
77
 
.\}
78
 
.if t \{\
79
 
.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
80
 
.    ds #V .6m
81
 
.    ds #F 0
82
 
.    ds #[ \&
83
 
.    ds #] \&
84
 
.\}
85
 
.    \" simple accents for nroff and troff
86
 
.if n \{\
87
 
.    ds ' \&
88
 
.    ds ` \&
89
 
.    ds ^ \&
90
 
.    ds , \&
91
 
.    ds ~ ~
92
 
.    ds /
93
 
.\}
94
 
.if t \{\
95
 
.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
96
 
.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
97
 
.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
98
 
.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
99
 
.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
100
 
.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
101
 
.\}
102
 
.    \" troff and (daisy-wheel) nroff accents
103
 
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
104
 
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
105
 
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
106
 
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
107
 
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
108
 
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
109
 
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
110
 
.ds ae a\h'-(\w'a'u*4/10)'e
111
 
.ds Ae A\h'-(\w'A'u*4/10)'E
112
 
.    \" corrections for vroff
113
 
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
114
 
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
115
 
.    \" for low resolution devices (crt and lpr)
116
 
.if \n(.H>23 .if \n(.V>19 \
117
 
\{\
118
 
.    ds : e
119
 
.    ds 8 ss
120
 
.    ds o a
121
 
.    ds d- d\h'-1'\(ga
122
 
.    ds D- D\h'-1'\(hy
123
 
.    ds th \o'bp'
124
 
.    ds Th \o'LP'
125
 
.    ds ae ae
126
 
.    ds Ae AE
127
 
.\}
128
 
.rm #[ #] #H #V #F C
129
 
.\" ========================================================================
130
 
.\"
131
 
.IX Title "sa 3"
132
 
.TH sa 3 "OSSP sa 1.2.2" "26-Jun-2004" "Socket Abstraction"
133
 
.SH "NAME"
134
 
\&\fBOSSP sa\fR \- Socket Abstraction
135
 
.SH "VERSION"
136
 
.IX Header "VERSION"
137
 
\&\fB\s-1OSSP\s0 sa \s-11.2.2 (26-Jun-2004)\s0\fR
138
 
.SH "SYNOPSIS"
139
 
.IX Header "SYNOPSIS"
140
 
.IP "\fBAbstract Data Types\fR:" 4
141
 
.IX Item "Abstract Data Types:"
142
 
sa_rc_t,
143
 
sa_addr_t,
144
 
sa_t.
145
 
.IP "\fBAddress Object Operations\fR:" 4
146
 
.IX Item "Address Object Operations:"
147
 
sa_addr_create,
148
 
sa_addr_destroy.
149
 
.IP "\fBAddress Operations\fR:" 4
150
 
.IX Item "Address Operations:"
151
 
sa_addr_u2a,
152
 
sa_addr_s2a,
153
 
sa_addr_a2u,
154
 
sa_addr_a2s,
155
 
sa_addr_match.
156
 
.IP "\fBSocket Object Operations\fR:" 4
157
 
.IX Item "Socket Object Operations:"
158
 
sa_create,
159
 
sa_destroy.
160
 
.IP "\fBSocket Parameter Operations\fR:" 4
161
 
.IX Item "Socket Parameter Operations:"
162
 
sa_type,
163
 
sa_timeout,
164
 
sa_buffer,
165
 
sa_option,
166
 
sa_syscall.
167
 
.IP "\fBSocket Connection Operations\fR:" 4
168
 
.IX Item "Socket Connection Operations:"
169
 
sa_bind,
170
 
sa_connect,
171
 
sa_listen,
172
 
sa_accept,
173
 
sa_getremote,
174
 
sa_getlocal,
175
 
sa_shutdown.
176
 
.IP "\fBSocket Input/Output Operations (Stream Communication)\fR:" 4
177
 
.IX Item "Socket Input/Output Operations (Stream Communication):"
178
 
sa_getfd,
179
 
sa_read,
180
 
sa_readln,
181
 
sa_write,
182
 
sa_writef,
183
 
sa_flush.
184
 
.IP "\fBSocket Input/Output Operations (Datagram Communication)\fR:" 4
185
 
.IX Item "Socket Input/Output Operations (Datagram Communication):"
186
 
sa_recv,
187
 
sa_send,
188
 
sa_sendf.
189
 
.IP "\fBSocket Error Handling\fR:" 4
190
 
.IX Item "Socket Error Handling:"
191
 
sa_error.
192
 
.SH "DESCRIPTION"
193
 
.IX Header "DESCRIPTION"
194
 
\&\fB\s-1OSSP\s0 sa\fR is an abstraction library for the Unix \fISocket\fR networking
195
 
application programming interface (\s-1API\s0), featuring stream and datagram
196
 
oriented communication over \fIUnix Domain\fR and \fIInternet Domain\fR (\s-1TCP\s0
197
 
and \s-1UDP\s0) sockets.
198
 
.PP
199
 
It provides the following key features:
200
 
.IP "\fBStand\-Alone, Self\-Contained, Embeddable\fR" 4
201
 
.IX Item "Stand-Alone, Self-Contained, Embeddable"
202
 
Although there are various Open Source libraries available which provide
203
 
a similar abstraction approach, they all either lack important features
204
 
or unfortunately depend on other companion libraries. \fB\s-1OSSP\s0 sa\fR fills
205
 
this gap by providing all important features (see following points) as a
206
 
stand-alone and fully self-contained library. This way \fB\s-1OSSP\s0 sa\fR can be
207
 
trivially embedded as a sub-library into other libraries. It especially
208
 
provides additional support for namespace-safe embedding of its \s-1API\s0 in
209
 
order to avoid symbol conflicts (see \f(CW\*(C`SA_PREFIX\*(C'\fR in \fIsa.h\fR).
210
 
.IP "\fBAddress Abstraction\fR" 4
211
 
.IX Item "Address Abstraction"
212
 
Most of the ugliness in the Unix \fISocket\fR \s-1API\s0 is the necessity to
213
 
have to deal with the various address structures (\f(CW\*(C`struct sockaddr_xx\*(C'\fR)
214
 
which exist because of both the different communication types and
215
 
addressing schemes. \fB\s-1OSSP\s0 sa\fR fully hides this by providing an abstract
216
 
and opaque address type (\f(CW\*(C`sa_addr_t\*(C'\fR) together with utility functions
217
 
which allow one to convert from the traditional \f(CW\*(C`struct sockaddr\*(C'\fR or
218
 
\&\s-1URI\s0 specification to the \f(CW\*(C`sa_addr_t\*(C'\fR and vice versa without having to
219
 
deal with special cases related to the underlying particular \f(CW\*(C`struct
220
 
sockaddr_xx\*(C'\fR. \fB\s-1OSSP\s0 sa\fR support \fIUnix Domain\fR and both IPv4 and IPv6
221
 
\&\fIInternet Domain\fR addressing.
222
 
.IP "\fBType Abstraction\fR" 4
223
 
.IX Item "Type Abstraction"
224
 
Some other subtle details in the Unix \fISocket\fR \s-1API\s0 make the life hard
225
 
in practice: \f(CW\*(C`socklen_t\*(C'\fR and \f(CW\*(C`ssize_t\*(C'\fR. These two types originally
226
 
were (and on some platforms still are) plain integers or unsigned
227
 
integers while \s-1POSIX\s0 later introduced own types for them (and even
228
 
revised these types after some time again). This is nasty, because
229
 
for 100% type-correct \s-1API\s0 usage (especially important on 64\-bit
230
 
machines where pointers to different integer types make trouble), every
231
 
application has to check whether the newer types exists, and if not
232
 
provide own definitions which map to the still actually used integer
233
 
type on the underlying platform. \fB\s-1OSSP\s0 sa\fR hides most of this in its
234
 
\&\s-1API\s0 and for \f(CW\*(C`socklen_t\*(C'\fR provides a backward-compatibility definition.
235
 
Instead of \f(CW\*(C`ssize_t\*(C'\fR it can use \f(CW\*(C`size_t\*(C'\fR because \fB\s-1OSSP\s0 sa\fR does not use
236
 
traditional Unix return code semantics.
237
 
.IP "\fBI/O Timeouts\fR" 4
238
 
.IX Item "I/O Timeouts"
239
 
Each I/O function in \fB\s-1OSSP\s0 sa\fR is aware of timeouts (set by
240
 
\&\fIsa_timeout\fR\|(3)), i.e., all I/O operations return \f(CW\*(C`SA_ERR_TMT\*(C'\fR if
241
 
the timeout expired before the I/O operation was able to succeed.
242
 
This allows one to easily program less-blocking network services.
243
 
\&\fB\s-1OSSP\s0 sa\fR internally implements these timeouts either through the
244
 
\&\f(CW\*(C`SO_\*(C'\fR{\f(CW\*(C`SND\*(C'\fR,\f(CW\*(C`RCV\*(C'\fR}\f(CW\*(C`TIMEO\*(C'\fR feature on more modern \fISocket\fR
245
 
implementations or through traditional \fIselect\fR\|(2). This way high
246
 
performance is achieved on modern platforms while the full functionality
247
 
still is available on older platforms.
248
 
.IP "\fBI/O Stream Buffering\fR" 4
249
 
.IX Item "I/O Stream Buffering"
250
 
If \fB\s-1OSSP\s0 sa\fR is used for stream communication, internally all I/O
251
 
operations can be performed through input and/or output buffers (set
252
 
by \fIsa_buffer\fR\|(3)) for achieving higher I/O performance by doing I/O
253
 
operations on larger aggregated messages and with less required system
254
 
calls. Additionally if \fB\s-1OSSP\s0 sa\fR is used for stream communication, for
255
 
convenience reasons line-oriented reading (\fIsa_readln\fR\|(3)) and formatted
256
 
writing (see \fIsa_writef\fR\|(3)) is provided, modelled after \s-1STDIO\s0's \fIfgets\fR\|(3)
257
 
and \fIfprintf\fR\|(3). Both features fully leverage from the I/O buffering.
258
 
.SH "DATA TYPES"
259
 
.IX Header "DATA TYPES"
260
 
\&\fB\s-1OSSP\s0 sa\fR uses three data types in its \s-1API:\s0
261
 
.IP "\fBsa_rc_t\fR (Return Code Type)" 4
262
 
.IX Item "sa_rc_t (Return Code Type)"
263
 
This is an exported enumerated integer type with the following possible
264
 
values:
265
 
.Sp
266
 
.Vb 10
267
 
\& SA_OK       Everything Ok
268
 
\& SA_ERR_ARG  Invalid Argument
269
 
\& SA_ERR_USE  Invalid Use Or Context
270
 
\& SA_ERR_MEM  Not Enough Memory
271
 
\& SA_ERR_MTC  Matching Failed
272
 
\& SA_ERR_EOF  End Of Communication
273
 
\& SA_ERR_TMT  Communication Timeout
274
 
\& SA_ERR_SYS  Operating System Error (see errno)
275
 
\& SA_ERR_IMP  Implementation Not Available
276
 
\& SA_ERR_INT  Internal Error
277
 
.Ve
278
 
.IP "\fBsa_addr_t\fR (Socket Address Abstraction Type)" 4
279
 
.IX Item "sa_addr_t (Socket Address Abstraction Type)"
280
 
This is an opaque data type representing a socket address.
281
 
Only pointers to this abstract data type are used in the \s-1API\s0.
282
 
.IP "\fBsa_t\fR (Socket Abstraction Type)" 4
283
 
.IX Item "sa_t (Socket Abstraction Type)"
284
 
This is an opaque data type representing a socket.
285
 
Only pointers to this abstract data type are used in the \s-1API\s0.
286
 
.SH "FUNCTIONS"
287
 
.IX Header "FUNCTIONS"
288
 
\&\fB\s-1OSSP\s0 sa\fR provides a bunch of \s-1API\s0 functions, all modelled after the
289
 
same prototype:
290
 
.PP
291
 
\&\f(CW\*(C`sa_rc_t\*(C'\fR \fBsa_\fR\fIname\fR\f(CW\*(C`(sa_\*(C'\fR[\f(CW\*(C`addr_\*(C'\fR]\f(CW\*(C`_t *,\*(C'\fR ...\f(CW\*(C`)\*(C'\fR
292
 
.PP
293
 
This means, every function returns \f(CW\*(C`sa_rc_t\*(C'\fR to indicate its success
294
 
(\f(CW\*(C`SA_OK\*(C'\fR) or failure (\f(CW\*(C`SA_ERR_\*(C'\fR\fI\s-1XXX\s0\fR) by returning a return code (the
295
 
corresponding describing text can be determined by passing this return
296
 
code to \fIsa_error\fR\|(3)). Each function name starts with the common prefix
297
 
\&\f(CW\*(C`sa_\*(C'\fR and receives a \f(CW\*(C`sa_t\*(C'\fR (or \f(CW\*(C`sa_addr_t\*(C'\fR) object handle on which
298
 
it operates as its first argument.
299
 
.Sh "Address Object Operations"
300
 
.IX Subsection "Address Object Operations"
301
 
This \s-1API\s0 part provides operations for the creation and destruction of
302
 
address abstraction \f(CW\*(C`sa_addr_t\*(C'\fR.
303
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_create\fR\f(CW\*(C`(sa_addr_t **\*(C'\fR\fIsaa\fR\f(CW\*(C`);\*(C'" 4
304
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_create\fR\f(CW\*(C`(sa_addr_t **\*(C'\fR\fIsaa\fR\f(CW\*(C`);\*(C'\fR" 4
305
 
.IX Item "sa_rc_t sa_addr_create(sa_addr_t **saa);"
306
 
Create a socket address abstraction object.
307
 
The object is stored in \fIsaa\fR on success.
308
 
.Sp
309
 
Example: \f(CW\*(C`sa_addr_t *saa; sa_addr_create(&saa);\*(C'\fR
310
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_destroy\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`);\*(C'" 4
311
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_destroy\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`);\*(C'\fR" 4
312
 
.IX Item "sa_rc_t sa_addr_destroy(sa_addr_t *saa);"
313
 
Destroy a socket address abstraction object.
314
 
The object \fIsaa\fR is invalid after this call succeeded.
315
 
.Sp
316
 
Example: \f(CW\*(C`sa_addr_destroy(saa);\*(C'\fR
317
 
.Sh "Address Operations"
318
 
.IX Subsection "Address Operations"
319
 
This \s-1API\s0 part provides operations for working with the address
320
 
abstraction \f(CW\*(C`sa_addr_t\*(C'\fR.
321
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_u2a\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, const char *\*(C'\fR\fIuri\fR\f(CW\*(C`, ...);\*(C'" 4
322
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_u2a\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, const char *\*(C'\fR\fIuri\fR\f(CW\*(C`, ...);\*(C'\fR" 4
323
 
.IX Item "sa_rc_t sa_addr_u2a(sa_addr_t *saa, const char *uri, ...);"
324
 
Import an address into by converting from an \s-1URI\s0 specification to the
325
 
corresponding address abstraction.
326
 
.Sp
327
 
The supported syntax for \fIuri\fR is: "\f(CW\*(C`unix:\*(C'\fR\fIpath\fR" for \fIUnix Domain\fR
328
 
addresses and "\f(CW\*(C`inet://\*(C'\fR\fIaddr\fR\f(CW\*(C`:\*(C'\fR\fIport\fR[\f(CW\*(C`#\*(C'\fR\fIprotocol\fR]" for
329
 
\&\fIInternet Domain\fR addresses.
330
 
.Sp
331
 
In the \s-1URI\s0, \fIpath\fR can be an absolute or relative filesystem path
332
 
to an existing or not-existing file. \fIaddr\fR can be an IPv4 address
333
 
in dotted decimal notation ("\f(CW127.0.0.1\fR\*(L"), an IPv6 address in
334
 
colon-separated (optionally abbreviated) hexadecimal notation (\*(R"\f(CW\*(C`::1\*(C'\fR\*(L")
335
 
or a to-be-resolved hostname (\*(R"\f(CW\*(C`localhost.example.com\*(C'\fR"). \fIport\fR has
336
 
to be either a decimal port in the range \f(CW1\fR...\f(CW65535\fR or a port name
337
 
("\f(CW\*(C`smtp\*(C'\fR"). If \fIport\fR is specified as a name, it is resolved as a \s-1TCP\s0
338
 
port by default. To force resolving a \fIport\fR name via a particular
339
 
protocol, \fIprotocol\fR can be specified as either "\f(CW\*(C`tcp\*(C'\fR\*(L" or \*(R"\f(CW\*(C`udp\*(C'\fR".
340
 
.Sp
341
 
The result is stored in \fIsaa\fR on success.
342
 
.Sp
343
 
Example: \f(CW\*(C`sa_addr_u2a(saa, "inet://192.168.0.1:smtp");\*(C'\fR
344
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_s2a\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, const struct sockaddr *\*(C'\fR\fIsabuf\fR\f(CW\*(C`, socklen_t \*(C'\fR\fIsalen\fR\f(CW\*(C`);\*(C'" 4
345
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_s2a\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, const struct sockaddr *\*(C'\fR\fIsabuf\fR\f(CW\*(C`, socklen_t \*(C'\fR\fIsalen\fR\f(CW\*(C`);\*(C'\fR" 4
346
 
.IX Item "sa_rc_t sa_addr_s2a(sa_addr_t *saa, const struct sockaddr *sabuf, socklen_t salen);"
347
 
Import an address by converting from a traditional \f(CW\*(C`struct sockaddr\*(C'\fR
348
 
object to the corresponding address abstraction.
349
 
.Sp
350
 
The accepted addresses for \fIsabuf\fR are: \f(CW\*(C`struct sockaddr_un\*(C'\fR
351
 
(\f(CW\*(C`AF_LOCAL\*(C'\fR), \f(CW\*(C`struct sockaddr_in\*(C'\fR (\f(CW\*(C`AF_INET\*(C'\fR) and \f(CW\*(C`struct
352
 
sockaddr_in6\*(C'\fR (\f(CW\*(C`AF_INET6\*(C'\fR). The \fIsalen\fR is the corresponding
353
 
\&\f(CW\*(C`sizeof(...)\*(C'\fR of the particular underyling structure.
354
 
.Sp
355
 
The result is stored in \fIsaa\fR on success.
356
 
.Sp
357
 
Example: \f(CW\*(C`sockaddr_in in; sa_addr_s2a(saa, (struct sockaddr *)&in, (socklen_t)sizeof(in));\*(C'\fR
358
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_a2u\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, char **\*(C'\fR\fIuri\fR\f(CW\*(C`);\*(C'" 4
359
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_a2u\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, char **\*(C'\fR\fIuri\fR\f(CW\*(C`);\*(C'\fR" 4
360
 
.IX Item "sa_rc_t sa_addr_a2u(sa_addr_t *saa, char **uri);"
361
 
Export an address by converting from the address abstraction to the
362
 
corresponding \s-1URI\s0 specification.
363
 
.Sp
364
 
The result is a string of the form "\f(CW\*(C`unix:\*(C'\fR\fIpath\fR" for \fIUnix
365
 
Domain\fR addresses and "\f(CW\*(C`inet://\*(C'\fR\fIaddr\fR\f(CW\*(C`:\*(C'\fR\fIport\fR" for \fIInternet
366
 
Domain\fR addresses. Notice that \fIaddr\fR and \fIport\fR are returned in
367
 
numerical (unresolved) way. Additionally, because usually one cannot map
368
 
bidirectionally between \s-1TCP\s0 or \s-1UDP\s0 port names and the numerical value,
369
 
there is no distinction between \s-1TCP\s0 and \s-1UDP\s0 here.
370
 
.Sp
371
 
The result is stored in \fIuri\fR on success.
372
 
The caller has to \fIfree\fR\|(3) the \fIuri\fR buffer later.
373
 
.Sp
374
 
Example: \f(CW\*(C`char *uri; sa_addr_a2u(saa, &uri);\*(C'\fR
375
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_a2s\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, struct sockaddr **\*(C'\fR\fIsabuf\fR\f(CW\*(C`, socklen_t *\*(C'\fR\fIsalen\fR\f(CW\*(C`);\*(C'" 4
376
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_a2s\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, struct sockaddr **\*(C'\fR\fIsabuf\fR\f(CW\*(C`, socklen_t *\*(C'\fR\fIsalen\fR\f(CW\*(C`);\*(C'\fR" 4
377
 
.IX Item "sa_rc_t sa_addr_a2s(sa_addr_t *saa, struct sockaddr **sabuf, socklen_t *salen);"
378
 
Export an address by converting from the address abstraction to the
379
 
corresponding traditional \f(CW\*(C`struct sockaddr\*(C'\fR object.
380
 
.Sp
381
 
The result is one of the following particular underlying address
382
 
structures: \f(CW\*(C`struct sockaddr_un\*(C'\fR (\f(CW\*(C`AF_LOCAL\*(C'\fR), \f(CW\*(C`struct sockaddr_in\*(C'\fR
383
 
(\f(CW\*(C`AF_INET\*(C'\fR) and \f(CW\*(C`struct sockaddr_in6\*(C'\fR (\f(CW\*(C`AF_INET6\*(C'\fR).
384
 
.Sp
385
 
The result is stored in \fIsabuf\fR and \fIsalen\fR on success.
386
 
The caller has to \fIfree\fR\|(3) the \fIsabuf\fR buffer later.
387
 
.Sp
388
 
Example: \f(CW\*(C`struct sockaddr sabuf, socklen_t salen; sa_addr_a2s(saa, &sa, &salen);\*(C'\fR
389
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_match\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa1\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIsaa2\fR\f(CW\*(C`, size_t \*(C'\fR\fIprefixlen\fR\f(CW\*(C`);\*(C'" 4
390
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_match\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa1\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIsaa2\fR\f(CW\*(C`, size_t \*(C'\fR\fIprefixlen\fR\f(CW\*(C`);\*(C'\fR" 4
391
 
.IX Item "sa_rc_t sa_addr_match(sa_addr_t *saa1, sa_addr_t *saa2, size_t prefixlen);"
392
 
Match two address abstractions up to a specified prefix.
393
 
.Sp
394
 
This compares the addresses \fIsaa1\fR and \fIsaa2\fR by only taking the
395
 
prefix part of length \fIprefixlen\fR into account. \fIprefixlen\fR is number
396
 
of filesystem path characters for \fIUnix Domain\fR addresses and number
397
 
of bits for \fIInternet Domain\fR addresses. In case of \fIInternet Domain\fR
398
 
addresses, the addresses are matched in network byte order and the port
399
 
(counting as an additional bit/item of length 1) is virtually appended
400
 
to the address for matching. Specifying \fIprefixlen\fR as \f(CW\*(C`\-1\*(C'\fR means
401
 
matching the whole address (but without the virtually appended port)
402
 
without having to know how long the underlying address representation
403
 
(length of path for Unix Domain addresses, 32+1 [IPv4] or 128+1 [IPv6]
404
 
for Internet Domain addresses) is. Specifying \fIprefixlen\fR as \f(CW\*(C`\-2\*(C'\fR is
405
 
equal to \f(CW\*(C`\-1\*(C'\fR but additionally the port is matched, too.
406
 
.Sp
407
 
This especially can be used to implement Access Control Lists (\s-1ACL\s0)
408
 
without having to fiddle around with the underlying representation.
409
 
For this, make \fIsaa1\fR the to be checked address and \fIsaa2\fR plus
410
 
\&\fIprefixlen\fR the \s-1ACL\s0 pattern as shown in the following example.
411
 
.Sp
412
 
Example:
413
 
.Sp
414
 
.Vb 20
415
 
\& sa_addr_t *srv_sa;
416
 
\& sa_addr_t *clt_saa;
417
 
\& sa_t      *clt_sa;
418
 
\& sa_addr_t *acl_saa;
419
 
\& char      *acl_addr = "192.168.0.0";
420
 
\& int        acl_len  = 24;
421
 
\& ...
422
 
\& sa_addr_u2a(&acl_saa, "inet://%s:0", acl_addr);
423
 
\& ...
424
 
\& while (sa_accept(srv_sa, &clt_saa, &clt_sa) == SA_OK) {
425
 
\&     if (sa_addr_match(clt_saa, acl_saa, acl_len) != SA_OK) {
426
 
\&         /* connection refused */
427
 
\&         ...
428
 
\&         sa_addr_destroy(clt_saa);
429
 
\&         sa_destroy(clt_sa);
430
 
\&         continue;
431
 
\&     }
432
 
\&     ...
433
 
\& }
434
 
\& ...
435
 
.Ve
436
 
.Sh "Socket Object Operations"
437
 
.IX Subsection "Socket Object Operations"
438
 
This \s-1API\s0 part provides operations for the creation and destruction of
439
 
socket abstraction \f(CW\*(C`sa_t\*(C'\fR.
440
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_create\fR\f(CW\*(C`(sa_t **\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'" 4
441
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_create\fR\f(CW\*(C`(sa_t **\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'\fR" 4
442
 
.IX Item "sa_rc_t sa_create(sa_t **sa);"
443
 
Create a socket abstraction object.
444
 
The object is stored in \fIsa\fR on success.
445
 
.Sp
446
 
Example: \f(CW\*(C`sa_t *sa; sa_create(&sa);\*(C'\fR
447
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_destroy\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'" 4
448
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_destroy\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'\fR" 4
449
 
.IX Item "sa_rc_t sa_destroy(sa_t *sa);"
450
 
Destroy a socket abstraction object.
451
 
The object \fIsa\fR is invalid after this call succeeded.
452
 
.Sp
453
 
Example: \f(CW\*(C`sa_destroy(sa);\*(C'\fR
454
 
.Sh "Socket Parameter Operations"
455
 
.IX Subsection "Socket Parameter Operations"
456
 
This \s-1API\s0 part provides operations for parameterizing the socket
457
 
abstraction \f(CW\*(C`sa_t\*(C'\fR.
458
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_type\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_type_t \*(C'\fR\fItype\fR\f(CW\*(C`);\*(C'" 4
459
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_type\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_type_t \*(C'\fR\fItype\fR\f(CW\*(C`);\*(C'\fR" 4
460
 
.IX Item "sa_rc_t sa_type(sa_t *sa, sa_type_t type);"
461
 
Assign a particular communication protocol type to the socket
462
 
abstraction object.
463
 
.Sp
464
 
A socket can only be assigned a single protocol type at any time.
465
 
Nevertheless one can switch the type of a socket abstraction object at
466
 
any time in order to reuse it for a different communication. Just keep
467
 
in mind that switching the type will stop a still ongoing communication
468
 
by closing the underlying socket.
469
 
.Sp
470
 
Possible values for \fItype\fR are \f(CW\*(C`SA_TYPE_STREAM\*(C'\fR (stream communication)
471
 
and \f(CW\*(C`SA_TYPE_DATAGRAM\*(C'\fR (datagram communication). The default
472
 
communication protocol type is \f(CW\*(C`SA_TYPE_STREAM\*(C'\fR.
473
 
.Sp
474
 
Example: \f(CW\*(C`sa_type(sa, SA_TYPE_STREAM);\*(C'\fR
475
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_timeout\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_timeout_t \*(C'\fR\fIid\fR\f(CW\*(C`, long \*(C'\fR\fIsec\fR\f(CW\*(C`, long \*(C'\fR\fIusec\fR\f(CW\*(C`);\*(C'" 4
476
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_timeout\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_timeout_t \*(C'\fR\fIid\fR\f(CW\*(C`, long \*(C'\fR\fIsec\fR\f(CW\*(C`, long \*(C'\fR\fIusec\fR\f(CW\*(C`);\*(C'\fR" 4
477
 
.IX Item "sa_rc_t sa_timeout(sa_t *sa, sa_timeout_t id, long sec, long usec);"
478
 
Assign one or more communication timeouts to the socket abstraction
479
 
object.
480
 
.Sp
481
 
Possible values for \fIid\fR are: \f(CW\*(C`SA_TIMEOUT_ACCEPT\*(C'\fR (affecting
482
 
\&\fIsa_accept\fR\|(3)), \f(CW\*(C`SA_TIMEOUT_CONNECT\*(C'\fR (affecting \fIsa_connect\fR\|(3)),
483
 
\&\f(CW\*(C`SA_TIMEOUT_READ\*(C'\fR (affecting \fIsa_read\fR\|(3), \fIsa_readln\fR\|(3) and \fIsa_recv\fR\|(3))
484
 
and \f(CW\*(C`SA_TIMEOUT_WRITE\*(C'\fR (affecting \fIsa_write\fR\|(3), \fIsa_writef\fR\|(3),
485
 
\&\fIsa_send\fR\|(3), and \fIsa_sendf\fR\|(3)). Additionally you can set all four timeouts
486
 
at once by using \f(CW\*(C`SA_TIMEOUT_ALL\*(C'\fR. The default is that no communication
487
 
timeouts are used which is equal to \fIsec\fR=\f(CW0\fR/\fIusec\fR=\f(CW0\fR.
488
 
.Sp
489
 
Example: \f(CW\*(C`sa_timeout(sa, SA_TIMEOUT_ALL, 30, 0);\*(C'\fR
490
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_buffer\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_buffer_t \*(C'\fR\fIid\fR\f(CW\*(C`, size_t \*(C'\fR\fIsize\fR\f(CW\*(C`);\*(C'" 4
491
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_buffer\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_buffer_t \*(C'\fR\fIid\fR\f(CW\*(C`, size_t \*(C'\fR\fIsize\fR\f(CW\*(C`);\*(C'\fR" 4
492
 
.IX Item "sa_rc_t sa_buffer(sa_t *sa, sa_buffer_t id, size_t size);"
493
 
Assign I/O communication buffers to the socket abstraction object.
494
 
.Sp
495
 
Possible values for \fIid\fR are: \f(CW\*(C`SA_BUFFER_READ\*(C'\fR (affecting \fIsa_read\fR\|(3)
496
 
and \fIsa_readln\fR\|(3)) and \f(CW\*(C`SA_BUFFER_WRITE\*(C'\fR (affecting \fIsa_write\fR\|(3) and
497
 
\&\fIsa_writef\fR\|(3)). The default is that no communication buffers are used
498
 
which is equal to \fIsize\fR=\f(CW0\fR.
499
 
.Sp
500
 
Example: \f(CW\*(C`sa_buffer(sa, SA_BUFFER_READ, 16384);\*(C'\fR
501
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_option\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_option_t \*(C'\fR\fIid\fR\f(CW\*(C`, ...);\*(C'" 4
502
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_option\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_option_t \*(C'\fR\fIid\fR\f(CW\*(C`, ...);\*(C'\fR" 4
503
 
.IX Item "sa_rc_t sa_option(sa_t *sa, sa_option_t id, ...);"
504
 
Adjust various options of the socket abstraction object.
505
 
.Sp
506
 
The adjusted option is controlled by \fIid\fR. The number and type of the
507
 
expected following argument(s) are dependent on the particular option.
508
 
Currently the following options are implemented (option arguments in
509
 
parenthesis):
510
 
.Sp
511
 
\&\f(CW\*(C`SA_OPTION_NAGLE\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIyesno\fR) for enabling (\fIyesno\fR=\f(CW1\fR)
512
 
or disabling (\fIyesno\fR == \f(CW0\fR) Nagle's Algorithm (see \s-1RFC898\s0 and
513
 
\&\f(CW\*(C`TCP_NODELAY\*(C'\fR of \fIsetsockopt\fR\|(2)).
514
 
.Sp
515
 
\&\f(CW\*(C`SA_OPTION_LINGER\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIamount\fR) for enabling (\fIamount\fR ==
516
 
\&\fIseconds\fR != \f(CW0\fR) or disabling (\fIamount\fR == \f(CW0\fR) lingering on close
517
 
(see \f(CW\*(C`SO_LINGER\*(C'\fR of \fIsetsockopt\fR\|(2)). Notice: using \fIseconds\fR > \f(CW0\fR
518
 
results in a regular (maximum of \fIseconds\fR lasting) lingering on close
519
 
while using \fIseconds\fR < \f(CW0\fR results in the special case of a \s-1TCP\s0
520
 
\&\s-1RST\s0 based connection termination on close.
521
 
.Sp
522
 
\&\f(CW\*(C`SA_OPTION_REUSEADDR\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIyesno\fR) for enabling (\fIyesno\fR ==
523
 
\&\f(CW1\fR) or disabling (\fIyesno\fR == \f(CW0\fR) the reusability of the address on
524
 
binding via \fIsa_bind\fR\|(3) (see \f(CW\*(C`SO_REUSEADDR\*(C'\fR of \fIsetsockopt\fR\|(2)).
525
 
.Sp
526
 
\&\f(CW\*(C`SA_OPTION_REUSEPORT\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIyesno\fR) for enabling (\fIyesno\fR == \f(CW1\fR)
527
 
or disabling (\fIyesno\fR == \f(CW0\fR) the reusability of the port on binding
528
 
via \fIsa_bind\fR\|(3) (see \f(CW\*(C`SO_REUSEPORT\*(C'\fR of \fIsetsockopt\fR\|(2)).
529
 
.Sp
530
 
\&\f(CW\*(C`SA_OPTION_NONBLOCK\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIyesno\fR) for enabling (\fIyesno\fR == \f(CW1\fR)
531
 
or disabling (\fIyesno\fR == \f(CW0\fR) non-blocking I/O mode (see \f(CW\*(C`O_NONBLOCK\*(C'\fR
532
 
of \fIfcntl\fR\|(2)).
533
 
.Sp
534
 
Example: \f(CW\*(C`sa_option(sa, SA_OPTION_NONBLOCK, 1);\*(C'\fR
535
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_syscall\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_syscall_t \*(C'\fR\fIid\fR\f(CW\*(C`, void (*\*(C'\fR\fIfptr\fR\f(CW\*(C`)(), void *\*(C'\fR\fIfctx\fR\f(CW\*(C`);\*(C'" 4
536
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_syscall\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_syscall_t \*(C'\fR\fIid\fR\f(CW\*(C`, void (*\*(C'\fR\fIfptr\fR\f(CW\*(C`)(), void *\*(C'\fR\fIfctx\fR\f(CW\*(C`);\*(C'\fR" 4
537
 
.IX Item "sa_rc_t sa_syscall(sa_t *sa, sa_syscall_t id, void (*fptr)(), void *fctx);"
538
 
Divert I/O communication related system calls to user supplied callback
539
 
functions.
540
 
.Sp
541
 
This allows you to override mostly all I/O related system calls \fB\s-1OSSP\s0
542
 
sa\fR internally performs while communicating. This can be used to adapt
543
 
\&\fB\s-1OSSP\s0 sa\fR to different run-time environments and requirements without
544
 
having to change the source code. Usually this is used to divert the
545
 
system calls to the variants of a user-land multithreading facility like
546
 
\&\fB\s-1GNU\s0 Pth\fR.
547
 
.Sp
548
 
The function supplied as \fIfptr\fR is required to fulfill the \s-1API\s0 of
549
 
the replaced system call, i.e., it has to have the same prototype (if
550
 
\&\fIfctx\fR is \f(CW\*(C`NULL\*(C'\fR). If \fIfctx\fR is not \f(CW\*(C`NULL\*(C'\fR, this prototype has to be
551
 
extended to accept an additional first argument of type \f(CW\*(C`void *\*(C'\fR which
552
 
receives the value of \fIfctx\fR. It is up to the callback function whether
553
 
to pass the call through to the replaced actual system call or not.
554
 
.Sp
555
 
Possible values for \fIid\fR are (expected prototypes behind \fIfptr\fR are
556
 
given in parenthesis):
557
 
.Sp
558
 
\&\f(CW\*(C`SA_SYSCALL_CONNECT\*(C'\fR: "\f(CW\*(C`int (*)([void *,] int, const struct sockaddr
559
 
*, socklen_t)\*(C'\fR", see \fIconnect\fR\|(2).
560
 
.Sp
561
 
\&\f(CW\*(C`SA_SYSCALL_ACCEPT\*(C'\fR: "\f(CW\*(C`int (*)([void *,] int, struct sockaddr *,
562
 
socklen_t *)\*(C'\fR", see \fIaccept\fR\|(2).
563
 
.Sp
564
 
\&\f(CW\*(C`SA_SYSCALL_SELECT\*(C'\fR: "\f(CW\*(C`int (*)([void *,] int, fd_set *, fd_set *,
565
 
fd_set *, struct timeval *)\*(C'\fR", see \fIselect\fR\|(2).
566
 
.Sp
567
 
\&\f(CW\*(C`SA_SYSCALL_READ\*(C'\fR: "\f(CW\*(C`ssize_t (*)([void *,] int, void *, size_t)\*(C'\fR", see
568
 
\&\fIread\fR\|(2).
569
 
.Sp
570
 
\&\f(CW\*(C`SA_SYSCALL_WRITE\*(C'\fR: "\f(CW\*(C`ssize_t (*)([void *,] int, const void *,
571
 
size_t)\*(C'\fR", see \fIwrite\fR\|(2).
572
 
.Sp
573
 
\&\f(CW\*(C`SA_SYSCALL_RECVFROM\*(C'\fR: "\f(CW\*(C`ssize_t (*)([void *,] int, void *, size_t,
574
 
int, struct sockaddr *, socklen_t *)\*(C'\fR", see \fIrecvfrom\fR\|(2).
575
 
.Sp
576
 
\&\f(CW\*(C`SA_SYSCALL_SENDTO\*(C'\fR: "\f(CW\*(C`ssize_t (*)([void *,] int, const void *,
577
 
size_t, int, const struct sockaddr *, socklen_t)\*(C'\fR", see \fIsendto\fR\|(2).
578
 
.Sp
579
 
Example:
580
 
.Sp
581
 
.Vb 1
582
 
\& FILE *trace_fp = ...;
583
 
.Ve
584
 
.Sp
585
 
.Vb 6
586
 
\& ssize_t
587
 
\& trace_read(void *ctx, int fd, void *buf, size_t len)
588
 
\& {
589
 
\&     FILE *fp = (FILE *)ctx;
590
 
\&     ssize_t rv;
591
 
\&     int errno_saved;
592
 
.Ve
593
 
.Sp
594
 
.Vb 7
595
 
\&     rv = read(fd, buf, len);
596
 
\&     errno_saved = errno;
597
 
\&     fprintf(fp, "read(%d, %lx, %d) = %d\en",
598
 
\&             fd, (long)buf, len, rv);
599
 
\&     errno = errno_saved;
600
 
\&     return rv;
601
 
\& }
602
 
.Ve
603
 
.Sp
604
 
.Vb 1
605
 
\& sa_syscall(sa, SA_SC_READ, trace_read, trace_fp);
606
 
.Ve
607
 
.Sh "Socket Connection Operations"
608
 
.IX Subsection "Socket Connection Operations"
609
 
This \s-1API\s0 part provides connection operations for stream-oriented data
610
 
communication through the socket abstraction \f(CW\*(C`sa_t\*(C'\fR.
611
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_bind\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIladdr\fR\f(CW\*(C`);\*(C'" 4
612
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_bind\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIladdr\fR\f(CW\*(C`);\*(C'\fR" 4
613
 
.IX Item "sa_rc_t sa_bind(sa_t *sa, sa_addr_t *laddr);"
614
 
Bind socket abstraction object to a local protocol address.
615
 
.Sp
616
 
This assigns the local protocol address \fIladdr\fR. When a socket is
617
 
created, it exists in an address family space but has no protocol
618
 
address assigned. This call requests that \fIladdr\fR be used as the local
619
 
address. For servers this is the address they later listen on (see
620
 
\&\fIsa_listen\fR\|(3)) for incoming connections, for clients this is the address
621
 
used for outgoing connections (see \fIsa_connect\fR\|(3)). Internally this
622
 
directly maps to \fIbind\fR\|(2).
623
 
.Sp
624
 
Example: \f(CW\*(C`sa_bind(sa, laddr);\*(C'\fR
625
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_connect\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`);\*(C'" 4
626
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_connect\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`);\*(C'\fR" 4
627
 
.IX Item "sa_rc_t sa_connect(sa_t *sa, sa_addr_t *raddr);"
628
 
Initiate an outgoing connection on a socket abstraction object.
629
 
.Sp
630
 
This performs a connect to the remote address \fIraddr\fR. If the socket
631
 
is of type \f(CW\*(C`SA_TYPE_DATAGRAM\*(C'\fR, this call specifies the peer with which
632
 
the socket is to be associated; this address is that to which datagrams
633
 
are to be sent, and the only address from which datagrams are to be
634
 
received. If the socket is of type \f(CW\*(C`SA_TYPE_STREAM\*(C'\fR, this call attempts
635
 
to make a connection to the remote socket. Internally this directly maps
636
 
to \fIconnect\fR\|(2).
637
 
.Sp
638
 
Example: \f(CW\*(C`sa_connect(sa, raddr);\*(C'\fR
639
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_listen\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, int \*(C'\fR\fIbacklog\fR\f(CW\*(C`);\*(C'" 4
640
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_listen\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, int \*(C'\fR\fIbacklog\fR\f(CW\*(C`);\*(C'\fR" 4
641
 
.IX Item "sa_rc_t sa_listen(sa_t *sa, int backlog);"
642
 
Listen for incoming connections on a socket abstraction object.
643
 
.Sp
644
 
A willingness to accept incoming connections and a queue limit for
645
 
incoming connections are specified by this call. The \fIbacklog\fR argument
646
 
defines the maximum length the queue of pending connections may grow to.
647
 
Internally this directly maps to \fIlisten\fR\|(2).
648
 
.Sp
649
 
Example: \f(CW\*(C`sa_listen(sa, 128);\*(C'\fR
650
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_accept\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIcaddr\fR\f(CW\*(C`, sa_t **\*(C'\fR\fIcsa\fR\f(CW\*(C`);\*(C'" 4
651
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_accept\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIcaddr\fR\f(CW\*(C`, sa_t **\*(C'\fR\fIcsa\fR\f(CW\*(C`);\*(C'\fR" 4
652
 
.IX Item "sa_rc_t sa_accept(sa_t *sa, sa_addr_t **caddr, sa_t **csa);"
653
 
Accept incoming connection on a socket abstraction object.
654
 
.Sp
655
 
This accepts an incoming connection by extracting the first connection
656
 
request on the queue of pending connections. It creates a new socket
657
 
abstraction object (returned in \fIcsa\fR) and a new socket address
658
 
abstraction object (returned in \fIcaddr\fR) describing the connection. The
659
 
caller has to destroy these objects later. If no pending connections
660
 
are present on the queue, it blocks the caller until a connection is
661
 
present.
662
 
.Sp
663
 
Example:
664
 
.Sp
665
 
.Vb 6
666
 
\& sa_addr_t *clt_saa;
667
 
\& sa_t      *clt_sa;
668
 
\& ...
669
 
\& while (sa_accept(srv_sa, &clt_saa, &clt_sa) == SA_OK) {
670
 
\&     ...
671
 
\& }
672
 
.Ve
673
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_getremote\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIraddr\fR\f(CW\*(C`);\*(C'" 4
674
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_getremote\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIraddr\fR\f(CW\*(C`);\*(C'\fR" 4
675
 
.IX Item "sa_rc_t sa_getremote(sa_t *sa, sa_addr_t **raddr);"
676
 
Get address abstraction of remote side of communication.
677
 
.Sp
678
 
This determines the address of the communication peer and creates a new
679
 
socket address abstraction object (returned in \fIraddr\fR) describing
680
 
the peer address. The application has to destroy \fIraddr\fR later with
681
 
\&\fIsa_addr_destroy\fR\|(3). Internally this maps to \fIgetpeername\fR\|(2).
682
 
.Sp
683
 
Example: \f(CW\*(C`sa_addr_t *raddr; sa_getremote(sa, &raddr);\*(C'\fR
684
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_getlocal\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIladdr\fR\f(CW\*(C`);\*(C'" 4
685
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_getlocal\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIladdr\fR\f(CW\*(C`);\*(C'\fR" 4
686
 
.IX Item "sa_rc_t sa_getlocal(sa_t *sa, sa_addr_t **laddr);"
687
 
Get address abstraction of local side of communication.
688
 
.Sp
689
 
This determines the address of the local communication side and
690
 
creates a new socket address abstraction object (returned in \fIladdr\fR)
691
 
describing the local address. The application has to destroy \fIladdr\fR
692
 
later with \fIsa_addr_destroy\fR\|(3). Internally this maps to \fIgetsockname\fR\|(2).
693
 
.Sp
694
 
Example: \f(CW\*(C`sa_addr_t *laddr; sa_getlocal(sa, &laddr);\*(C'\fR
695
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_shutdown\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIflags\fR\f(CW\*(C`);\*(C'" 4
696
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_shutdown\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIflags\fR\f(CW\*(C`);\*(C'\fR" 4
697
 
.IX Item "sa_rc_t sa_shutdown(sa_t *sa, char *flags);"
698
 
Shut down part of the full-duplex connection.
699
 
.Sp
700
 
This performs a shut down of the connection described in \fIsa\fR. The
701
 
flags string can be either "\f(CW\*(C`r\*(C'\fR\*(L" (indicating the read channel of the
702
 
communication is shut down only), \*(R"\f(CW\*(C`w\*(C'\fR\*(L" (indicating the write channel
703
 
of the communication is shut down only), or \*(R"\f(CW\*(C`rw\*(C'\fR" (indicating both the
704
 
read and write channels of the communication are shut down). Internally
705
 
this directly maps to \fIshutdown\fR\|(2).
706
 
.Sp
707
 
Example: \f(CW\*(C`sa_shutdown(sa, "w");\*(C'\fR
708
 
.Sh "Socket Input/Output Operations (Stream Communication)"
709
 
.IX Subsection "Socket Input/Output Operations (Stream Communication)"
710
 
This \s-1API\s0 part provides I/O operations for stream-oriented data
711
 
communication through the socket abstraction \f(CW\*(C`sa_t\*(C'\fR.
712
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_getfd\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, int *\*(C'\fR\fIfd\fR\f(CW\*(C`);\*(C'" 4
713
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_getfd\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, int *\*(C'\fR\fIfd\fR\f(CW\*(C`);\*(C'\fR" 4
714
 
.IX Item "sa_rc_t sa_getfd(sa_t *sa, int *fd);"
715
 
Get underlying socket filedescriptor.
716
 
.Sp
717
 
This peeks into the underlying socket filedescriptor \fB\s-1OSSP\s0 sa\fR
718
 
allocated internally for the communication. This can be used for
719
 
adjusting the socket communication (via \fIfcntl\fR\|(2), \fIsetsockopt\fR\|(2), etc)
720
 
directly.
721
 
.Sp
722
 
Think twice before using this, then think once more. After all that,
723
 
think again. With enough thought, the need for directly manipulating the
724
 
underlying socket can often be eliminated. At least remember that all
725
 
your direct socket operations fully by-pass \fB\s-1OSSP\s0 sa\fR and this way can
726
 
leads to nasty side\-effects.
727
 
.Sp
728
 
Example: \f(CW\*(C`int fd; sa_getfd(sa, &fd);\*(C'\fR
729
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_read\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
730
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_read\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
731
 
.IX Item "sa_rc_t sa_read(sa_t *sa, char *buf, size_t buflen, size_t *bufdone);"
732
 
Read a chunk of data from socket into own buffer.
733
 
.Sp
734
 
This reads from the socket (optionally through the internal read buffer)
735
 
up to a maximum of \fIbuflen\fR bytes into buffer \fIbuf\fR. The actual number
736
 
of read bytes is stored in \fIbufdone\fR. This internally maps to \fIread\fR\|(2).
737
 
.Sp
738
 
Example: \f(CW\*(C`char buf[1024]; size_t n; sa_read(sa, buf, sizeof(buf), &n);\*(C'\fR
739
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_readln\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
740
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_readln\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
741
 
.IX Item "sa_rc_t sa_readln(sa_t *sa, char *buf, size_t buflen, size_t *bufdone);"
742
 
Read a line of data from socket into own buffer.
743
 
.Sp
744
 
This reads from the socket (optionally through the internal read buffer)
745
 
up to a maximum of \fIbuflen\fR bytes into buffer \fIbuf\fR, but only as long
746
 
as no line terminating newline character (0x0a) was found. The line
747
 
terminating newline character is stored in the buffer plus a (not
748
 
counted) terminating \f(CW\*(C`NUL\*(C'\fR character ('\f(CW\*(C`\e0\*(C'\fR'), too. The actual
749
 
number of read bytes is stored in \fIbufdone\fR. This internally maps to
750
 
\&\fIsa_read\fR\|(3).
751
 
.Sp
752
 
Keep in mind that for efficiency reasons, line-oriented I/O usually
753
 
always should be performed with read buffer (see \fIsa_option\fR\|(3) and
754
 
\&\f(CW\*(C`SA_BUFFER_READ\*(C'\fR). Without such a read buffer, the performance is
755
 
cruel, because single character \fIread\fR\|(2) operations would be performed on
756
 
the underlying socket.
757
 
.Sp
758
 
Example: \f(CW\*(C`char buf[1024]; size_t n; sa_readln(sa, buf, sizeof(buf), &n);\*(C'\fR
759
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_write\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, const char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
760
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_write\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, const char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
761
 
.IX Item "sa_rc_t sa_write(sa_t *sa, const char *buf, size_t buflen, size_t *bufdone);"
762
 
Write a chunk of data to socket from own buffer.
763
 
.Sp
764
 
This writes to the socket (optionally through the internal write buffer)
765
 
\&\fIbuflen\fR bytes from buffer \fIbuf\fR. In case of a partial write, the
766
 
actual number of written bytes is stored in \fIbufdone\fR. This internally
767
 
maps to \fIwrite\fR\|(2).
768
 
.Sp
769
 
Example: \f(CW\*(C`sa_write(sa, cp, strlen(cp), NULL);\*(C'\fR
770
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_writef\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, const char *\*(C'\fR\fIfmt\fR\f(CW\*(C`, ...);\*(C'" 4
771
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_writef\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, const char *\*(C'\fR\fIfmt\fR\f(CW\*(C`, ...);\*(C'\fR" 4
772
 
.IX Item "sa_rc_t sa_writef(sa_t *sa, const char *fmt, ...);"
773
 
Write formatted data data to socket.
774
 
.Sp
775
 
This formats a string according to the \fIprintf\fR\|(3)\-style format
776
 
specification \fIfmt\fR and sends the result to the socket (optionally
777
 
through the internal write buffer). In case of a partial socket
778
 
write, the not written data of the formatted string is internally
779
 
discarded. Hence using a write buffer is strongly recommended here
780
 
(see \fIsa_option\fR\|(3) and \f(CW\*(C`SA_BUFFER_WRITE\*(C'\fR). This internally maps to
781
 
\&\fIsa_write\fR\|(3).
782
 
.Sp
783
 
The underlying string formatting engine is just a minimal one and for
784
 
security and independence reasons intentionally not directly based on
785
 
s[n]\fIprintf\fR\|(3). It understands only the following format specifications:
786
 
"\f(CW\*(C`%%\*(C'\fR\*(L", \*(R"\f(CW%c\fR" (\f(CW\*(C`char\*(C'\fR), "\f(CW%s\fR" (\f(CW\*(C`char *\*(C'\fR) and "\f(CW%d\fR" (\f(CW\*(C`int\*(C'\fR)
787
 
without any precision and padding possibilities. It is intended for
788
 
minimal formatting only. If you need more sophisticated formatting, you
789
 
have to format first into an own buffer via s[n]\fIprintf\fR\|(3) and then write
790
 
this to the socket via \fIsa_write\fR\|(3) instead.
791
 
.Sp
792
 
Example: \f(CW\*(C`sa_writef(sa, "%s=%d\en", cp, i);\*(C'\fR
793
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_flush\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'" 4
794
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_flush\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'\fR" 4
795
 
.IX Item "sa_rc_t sa_flush(sa_t *sa);"
796
 
Flush still pending outgoing data to socket.
797
 
.Sp
798
 
This writes all still pending outgoing data for the internal write
799
 
buffer (see \fIsa_option\fR\|(3) and \f(CW\*(C`SA_BUFFER_WRITE\*(C'\fR) to the socket. This
800
 
internally maps to \fIwrite\fR\|(2).
801
 
.Sp
802
 
Example: \f(CW\*(C`sa_flush(sa);\*(C'\fR
803
 
.Sh "Socket Input/Output Operations (Datagram Communication)"
804
 
.IX Subsection "Socket Input/Output Operations (Datagram Communication)"
805
 
This \s-1API\s0 part provides I/O operations for datagram-oriented data
806
 
communication through the socket abstraction \f(CW\*(C`sa_t\*(C'\fR.
807
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_recv\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIraddr\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
808
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_recv\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIraddr\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
809
 
.IX Item "sa_rc_t sa_recv(sa_t *sa, sa_addr_t **raddr, char *buf, size_t buflen, size_t *bufdone);"
810
 
Receive a chunk of data from remote address via socket into own buffer.
811
 
.Sp
812
 
This receives from the remote address specified in \fIraddr\fR via the
813
 
socket up to a maximum of \fIbuflen\fR bytes into buffer \fIbuf\fR. The actual
814
 
number of received bytes is stored in \fIbufdone\fR. This internally maps
815
 
to \fIrecvfrom\fR\|(2).
816
 
.Sp
817
 
Example: \f(CW\*(C`char buf[1024]; size_t n; sa_recv(sa, buf, sizeof(buf), &n, saa);\*(C'\fR
818
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_send\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`, const char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
819
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_send\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`, const char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
820
 
.IX Item "sa_rc_t sa_send(sa_t *sa, sa_addr_t *raddr, const char *buf, size_t buflen, size_t *bufdone);"
821
 
Send a chunk of data to remote address via socket from own buffer.
822
 
.Sp
823
 
This sends to the remote address specified in \fIraddr\fR via the socket
824
 
\&\fIbuflen\fR bytes from buffer \fIbuf\fR. The actual number of sent bytes is
825
 
stored in \fIbufdone\fR. This internally maps to \fIsendto\fR\|(2).
826
 
.Sp
827
 
Example: \f(CW\*(C`sa_send(sa, buf, strlen(buf), NULL, saa);\*(C'\fR
828
 
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_sendf\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`, const char *\*(C'\fR\fIfmt\fR\f(CW\*(C`, ...);\*(C'" 4
829
 
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_sendf\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`, const char *\*(C'\fR\fIfmt\fR\f(CW\*(C`, ...);\*(C'\fR" 4
830
 
.IX Item "sa_rc_t sa_sendf(sa_t *sa, sa_addr_t *raddr, const char *fmt, ...);"
831
 
Send formatted data data to remote address via socket.
832
 
.Sp
833
 
This formats a string according to the \fIprintf\fR\|(3)\-style format
834
 
specification \fIfmt\fR and sends the result to the socket as a single
835
 
piece of data chunk. In case of a partial socket write, the not written
836
 
data of the formatted string is internally discarded.
837
 
.Sp
838
 
The underlying string formatting engine is just a minimal one and for
839
 
security and independence reasons intentionally not directly based on
840
 
s[n]\fIprintf\fR\|(3). It understands only the following format specifications:
841
 
"\f(CW\*(C`%%\*(C'\fR\*(L", \*(R"\f(CW%c\fR" (\f(CW\*(C`char\*(C'\fR), "\f(CW%s\fR" (\f(CW\*(C`char *\*(C'\fR) and "\f(CW%d\fR" (\f(CW\*(C`int\*(C'\fR)
842
 
without any precision and padding possibilities. It is intended for
843
 
minimal formatting only. If you need more sophisticated formatting, you
844
 
have to format first into an own buffer via s[n]\fIprintf\fR\|(3) and then send
845
 
this to the remote address via \fIsa_send\fR\|(3) instead.
846
 
.Sp
847
 
Example: \f(CW\*(C`sa_sendf(sa, saa, "%s=%d\en", cp, i);\*(C'\fR
848
 
.Sh "Socket Error Handling"
849
 
.IX Subsection "Socket Error Handling"
850
 
This \s-1API\s0 part provides error handling operations only.
851
 
.ie n .IP "\*(C`char *\*(C'\fR\fBsa_error\fR\f(CW\*(C`(sa_rc_t \*(C'\fR\fIrv\fR\f(CW\*(C`);\*(C'" 4
852
 
.el .IP "\f(CW\*(C`char *\*(C'\fR\fBsa_error\fR\f(CW\*(C`(sa_rc_t \*(C'\fR\fIrv\fR\f(CW\*(C`);\*(C'\fR" 4
853
 
.IX Item "char *sa_error(sa_rc_t rv);"
854
 
Return the string representation corresponding to the return code
855
 
value \fIrv\fR. The returned string has to be treated read-only by the
856
 
application and is not required to be deallocated.
857
 
.SH "SEE ALSO"
858
 
.IX Header "SEE ALSO"
859
 
.Sh "Standards"
860
 
.IX Subsection "Standards"
861
 
R. Gilligan, S. Thomson, J. Bound, W. Stevens:
862
 
\&\fI\*(L"Basic Socket Interface Extensions for IPv6\*(R"\fR,
863
 
\&\fB\s-1RFC\s0 2553\fR, March 1999.
864
 
.PP
865
 
W. Stevens:
866
 
\&\fI\*(L"Advanced Sockets \s-1API\s0 for IPv6\*(R"\fR,
867
 
\&\fB\s-1RFC\s0 2292\fR, February 1998.
868
 
.PP
869
 
R. Fielding, L. Masinter, T. Berners\-Lee:
870
 
\&\fI\*(L"Uniform Resource Identifiers: Generic Syntax\*(R"\fR,
871
 
\&\fB\s-1RFC\s0 2396\fR, August 1998.
872
 
.PP
873
 
R. Hinden, S. Deering:
874
 
\&\fI\*(L"\s-1IP\s0 Version 6 Addressing Architecture\*(R"\fR,
875
 
\&\fB\s-1RFC\s0 2373\fR, July 1998.
876
 
.PP
877
 
R. Hinden, B. Carpenter, L. Masinter:
878
 
\&\fI\*(L"Format for Literal IPv6 Addresses in \s-1URL\s0's\*(R"\fR,
879
 
\&\fB\s-1RFC\s0 2732\fR, December 1999.
880
 
.Sh "Papers"
881
 
.IX Subsection "Papers"
882
 
Stuart Sechrest:
883
 
\&\fI\*(L"An Introductory 4.4BSD Interprocess Communication Tutorial\*(R"\fR,
884
 
FreeBSD 4.4 (/usr/share/doc/psd/20.ipctut/).
885
 
.PP
886
 
Samuel J. Leffler, Robert S. Fabry, William N. Joy, Phil Lapsley:
887
 
\&\fI\*(L"An Advanced 4.4BSD Interprocess Communication Tutorial\*(R"\fR,
888
 
FreeBSD 4.4 (/usr/share/doc/psd/21.ipc/).
889
 
.PP
890
 
Craig Metz:
891
 
\&\fI\*(L"Protocol Independence Using the Sockets \s-1API\s0\*(R"\fR,
892
 
http://www.usenix.org/publications/library/proceedings/usenix2000/freenix/metzprotocol.html,
893
 
\&\s-1USENIX\s0 Annual Technical Conference, June 2000.
894
 
.Sh "Manual Pages"
895
 
.IX Subsection "Manual Pages"
896
 
\&\fIsocket\fR\|(2),
897
 
\&\fIaccept\fR\|(2),
898
 
\&\fIbind\fR\|(2),
899
 
\&\fIconnect\fR\|(2),
900
 
\&\fIgetpeername\fR\|(2),
901
 
\&\fIgetsockname\fR\|(2),
902
 
\&\fIgetsockopt\fR\|(2),
903
 
\&\fIioctl\fR\|(2),
904
 
\&\fIlisten\fR\|(2),
905
 
\&\fIread\fR\|(2),
906
 
\&\fIrecv\fR\|(2),
907
 
\&\fIselect\fR\|(2),
908
 
\&\fIsend\fR\|(2),
909
 
\&\fIshutdown\fR\|(2),
910
 
\&\fIsocketpair\fR\|(2),
911
 
\&\fIwrite\fR\|(2),
912
 
\&\fIgetprotoent\fR\|(3),
913
 
\&\fIprotocols\fR\|(4).
914
 
.SH "HISTORY"
915
 
.IX Header "HISTORY"
916
 
\&\fB\s-1OSSP\s0 sa\fR was invented in August 2001 by Ralf S. Engelschall
917
 
<rse@engelschall.com> under contract with Cable & Wireless
918
 
Germany <http://www.cw.com/de> for use inside the \s-1OSSP\s0 project.
919
 
Its creation was prompted by the requirement to implement an \s-1SMTP\s0
920
 
logging channel for \fB\s-1OSSP\s0 l2\fR (logging library). Its initial code was
921
 
derived from a predecessor sub-library originally written for socket
922
 
address abstraction inside \fB\s-1OSSP\s0 lmtp2nntp\fR.
923
 
.SH "AUTHOR"
924
 
.IX Header "AUTHOR"
925
 
.Vb 3
926
 
\& Ralf S. Engelschall
927
 
\& rse@engelschall.com
928
 
\& www.engelschall.com
929
 
.Ve