--- l2_ut_sa.c 2001/10/26 10:59:47 1.16
+++ l2_ut_sa.c 2001/10/31 21:26:11 1.17
@@ -69,6 +69,11 @@
#define ssize_t long
#endif
+/* backward compatibility for O_NONBLOCK */
+#if !defined(O_NONBLOCK) && defined(O_NDELAY)
+#define O_NONBLOCK O_NDELAY
+#endif
+
/* system call structure declaration macros */
#define SA_SC_DECLARE_0(rc_t, fn) \
struct { \
@@ -492,7 +497,7 @@
if (cpHost[0] == '[') {
/* IPv6 address (see RFC2732) */
#ifndef AF_INET6
- return SA_ERR_ARG;
+ return SA_ERR_IMP;
#else
bIPv6 = TRUE;
cpHost++;
@@ -607,6 +612,15 @@
if (saa == NULL || sabuf == NULL || salen == 0)
return SA_ERR_ARG;
+ /* make sure we import only supported addresses */
+ if (!( sabuf->sa_family == AF_LOCAL
+ || sabuf->sa_family == AF_INET
+#ifdef AF_INET6
+ || sabuf->sa_family == AF_INET6
+#endif
+ ))
+ return SA_ERR_USE;
+
/* create result address structure */
if (saa->saBuf != NULL)
free(saa->saBuf);
@@ -1054,6 +1068,61 @@
return SA_OK;
}
+/* configure socket option */
+sa_rc_t sa_option(sa_t *sa, sa_option_t id, ...)
+{
+ sa_rc_t rv;
+ va_list ap;
+
+ /* argument sanity check(s) */
+ if (sa == NULL)
+ return SA_ERR_ARG;
+
+ /* process option */
+ rv = SA_OK;
+ va_start(ap, id);
+ switch (id) {
+ case SA_OPTION_NAGLE: {
+ /* enable/disable Nagle's Algorithm (see RFC898) */
+#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
+ int mode = ((int)va_arg(ap, int) ? 1 : 0);
+ if (sa->fdSocket == -1) {
+ rv = SA_ERR_USE;
+ break;
+ }
+ if (setsockopt(sa->fdSocket, IPPROTO_TCP, TCP_NODELAY,
+ (void *)&mode, sizeof(mode)) < 0)
+ rv = SA_ERR_SYS;
+#else
+ rv = SA_ERR_IMP;
+#endif
+ break;
+ }
+ case SA_OPTION_NONBLOCK: {
+ /* enable/disable non-blocking I/O mode */
+ int flags;
+ int mode = (int)va_arg(ap, int);
+ if ((flags = fcntl(sa->fdSocket, F_GETFL, 0)) < 0) {
+ rv = SA_ERR_SYS;
+ break;
+ }
+ if (mode == 0)
+ flags &= ~(O_NONBLOCK);
+ else
+ flags |= O_NONBLOCK;
+ if (fcntl(sa->fdSocket, F_SETFL, flags) < 0)
+ rv = SA_ERR_SYS;
+ break;
+ }
+ default: {
+ rv = SA_ERR_ARG;
+ }
+ }
+ va_end(ap);
+
+ return rv;
+}
+
/* override system call */
sa_rc_t sa_syscall(sa_t *sa, sa_syscall_t id, void (*fptr)(), void *fctx)
{
@@ -1451,14 +1520,12 @@
if (sa->fdSocket == -1)
return SA_ERR_USE;
- /* trigger a write buffer flush */
- if (sa->nWriteLen > 0)
- sa_flush(sa);
-
/* perform read operation */
rv = SA_OK;
if (sa->nReadSize == 0) {
/* user-space unbuffered I/O */
+ if (sa->nWriteLen > 0)
+ sa_flush(sa);
res = sa_read_raw(sa, cpBuf, nBufReq);
if (res == 0)
rv = SA_ERR_EOF;
@@ -1487,6 +1554,8 @@
res += sa->nReadLen;
sa->nReadLen = 0;
}
+ if (sa->nWriteLen > 0)
+ sa_flush(sa);
if (nBufReq >= sa->nReadSize) {
/* buffer is too small at all, so read directly */
n = sa_read_raw(sa, cpBuf, nBufReq);
@@ -1916,6 +1985,7 @@
else if (rv == SA_ERR_EOF) sz = "End Of Communication";
else if (rv == SA_ERR_TMT) sz = "Communication Timeout";
else if (rv == SA_ERR_SYS) sz = "Operating System Error";
+ else if (rv == SA_ERR_IMP) sz = "Implementation Not Available";
else if (rv == SA_ERR_INT) sz = "Internal Error";
else sz = "Invalid Result Code";
return sz;
|