Index: ossp-pkg/sa/sa.c RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.c,v rcsdiff -q -kk '-r1.37' '-r1.38' -u '/v/ossp/cvs/ossp-pkg/sa/sa.c,v' 2>/dev/null --- sa.c 2001/10/31 11:45:35 1.37 +++ sa.c 2001/10/31 12:41:53 1.38 @@ -71,6 +71,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 { \ @@ -494,7 +499,7 @@ if (cpHost[0] == '[') { /* IPv6 address (see RFC2732) */ #ifndef AF_INET6 - return SA_ERR_ARG; + return SA_ERR_IMP; #else bIPv6 = TRUE; cpHost++; @@ -1056,6 +1061,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) { @@ -1918,6 +1978,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; Index: ossp-pkg/sa/sa.h RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.h,v rcsdiff -q -kk '-r1.23' '-r1.24' -u '/v/ossp/cvs/ossp-pkg/sa/sa.h,v' 2>/dev/null --- sa.h 2001/10/11 08:00:37 1.23 +++ sa.h 2001/10/31 12:41:53 1.24 @@ -107,15 +107,16 @@ /* return codes */ typedef enum { - 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 */ - SA_ERR_INT /* Internal Error */ + 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 */ + SA_ERR_IMP, /* Implementation Not Available */ + SA_ERR_INT /* Internal Error */ } sa_rc_t; /* list of timeouts */ @@ -133,6 +134,12 @@ SA_BUFFER_WRITE } sa_buffer_t; +/* list of options */ +typedef enum { + SA_OPTION_NAGLE, + SA_OPTION_NONBLOCK +} sa_option_t; + /* list of system calls */ typedef enum { SA_SYSCALL_CONNECT, @@ -163,6 +170,7 @@ sa_rc_t sa_type (sa_t *sa, sa_type_t type); sa_rc_t sa_timeout (sa_t *sa, sa_timeout_t id, long sec, long usec); sa_rc_t sa_buffer (sa_t *sa, sa_buffer_t id, size_t size); +sa_rc_t sa_option (sa_t *sa, sa_option_t id, ...); sa_rc_t sa_syscall (sa_t *sa, sa_syscall_t id, void (*fptr)(), void *fctx); /* socket connection operations */ Index: ossp-pkg/sa/sa.pod RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.pod,v rcsdiff -q -kk '-r1.14' '-r1.15' -u '/v/ossp/cvs/ossp-pkg/sa/sa.pod,v' 2>/dev/null --- sa.pod 2001/10/24 12:24:27 1.14 +++ sa.pod 2001/10/31 12:41:53 1.15 @@ -67,6 +67,7 @@ sa_type, sa_timeout, sa_buffer, +sa_option, sa_syscall. =item B: @@ -275,6 +276,8 @@ =item sa_rc_t B(sa_t *I, sa_buffer_t I, size_t I); +=item sa_rc_t B(sa_t *I, sa_option_t I, ...); + =item sa_rc_t B(sa_t *I, sa_syscall_t I, void (*I)(), void *I); =back