version get/set send/recv timeout setsockopt.

This commit is contained in:
christos 2009-01-14 18:09:00 +00:00
parent 68648215f2
commit 6d87d90fe9

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_socket.c,v 1.178 2008/12/07 20:58:46 pooka Exp $ */
/* $NetBSD: uipc_socket.c,v 1.179 2009/01/14 18:09:00 christos Exp $ */
/*-
* Copyright (c) 2002, 2007, 2008 The NetBSD Foundation, Inc.
@ -63,8 +63,9 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.178 2008/12/07 20:58:46 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.179 2009/01/14 18:09:00 christos Exp $");
#include "opt_compat_netbsd.h"
#include "opt_sock_counters.h"
#include "opt_sosend_loan.h"
#include "opt_mbuftrace.h"
@ -92,6 +93,12 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.178 2008/12/07 20:58:46 pooka Exp
#include <sys/mutex.h>
#include <sys/condvar.h>
#ifdef COMPAT_50
#include <compat/sys/time.h>
#define SO_OSNDTIMEO 0x1005
#define SO_ORCVTIMEO 0x1006
#endif
#include <uvm/uvm.h>
MALLOC_DEFINE(M_SOOPTS, "soopts", "socket options");
@ -1576,11 +1583,11 @@ sorflush(struct socket *so)
static int
sosetopt1(struct socket *so, const struct sockopt *sopt)
{
int error, optval;
int error = 0, optval, opt;
struct linger l;
struct timeval tv;
switch (sopt->sopt_name) {
switch ((opt = sopt->sopt_name)) {
case SO_ACCEPTFILTER:
error = accept_filt_setopt(so, sopt);
@ -1618,9 +1625,9 @@ sosetopt1(struct socket *so, const struct sockopt *sopt)
if (error)
break;
if (optval)
so->so_options |= sopt->sopt_name;
so->so_options |= opt;
else
so->so_options &= ~sopt->sopt_name;
so->so_options &= ~opt;
break;
case SO_SNDBUF:
@ -1641,7 +1648,7 @@ sosetopt1(struct socket *so, const struct sockopt *sopt)
break;
}
switch (sopt->sopt_name) {
switch (opt) {
case SO_SNDBUF:
if (sbreserve(&so->so_snd, (u_long)optval, so) == 0) {
error = ENOBUFS;
@ -1678,9 +1685,22 @@ sosetopt1(struct socket *so, const struct sockopt *sopt)
}
break;
#ifdef COMPAT_50
case SO_OSNDTIMEO:
case SO_ORCVTIMEO: {
struct timeval50 otv;
error = sockopt_get(sopt, &otv, sizeof(otv));
timeval50_to_timeval(&otv, &tv);
opt = opt == SO_OSNDTIMEO ? SO_SNDTIMEO : SO_RCVTIMEO;
error = 1;
/*FALLTHROUGH*/
}
#endif /* COMPAT_50 */
case SO_SNDTIMEO:
case SO_RCVTIMEO:
error = sockopt_get(sopt, &tv, sizeof(tv));
if (error)
error = sockopt_get(sopt, &tv, sizeof(tv));
solock(so);
if (error)
break;
@ -1694,7 +1714,7 @@ sosetopt1(struct socket *so, const struct sockopt *sopt)
if (optval == 0 && tv.tv_usec != 0)
optval = 1;
switch (sopt->sopt_name) {
switch (opt) {
case SO_SNDTIMEO:
so->so_snd.sb_timeo = optval;
break;
@ -1767,11 +1787,11 @@ so_setsockopt(struct lwp *l, struct socket *so, int level, int name,
static int
sogetopt1(struct socket *so, struct sockopt *sopt)
{
int error, optval;
int error, optval, opt;
struct linger l;
struct timeval tv;
switch (sopt->sopt_name) {
switch ((opt = sopt->sopt_name)) {
case SO_ACCEPTFILTER:
error = accept_filt_getopt(so, sopt);
@ -1793,8 +1813,7 @@ sogetopt1(struct socket *so, struct sockopt *sopt)
case SO_BROADCAST:
case SO_OOBINLINE:
case SO_TIMESTAMP:
error = sockopt_setint(sopt,
(so->so_options & sopt->sopt_name) ? 1 : 0);
error = sockopt_setint(sopt, (so->so_options & opt) ? 1 : 0);
break;
case SO_TYPE:
@ -1822,9 +1841,25 @@ sogetopt1(struct socket *so, struct sockopt *sopt)
error = sockopt_setint(sopt, so->so_rcv.sb_lowat);
break;
#ifdef COMPAT_50
case SO_OSNDTIMEO:
case SO_ORCVTIMEO: {
struct timeval50 otv;
optval = (opt == SO_OSNDTIMEO ?
so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
otv.tv_sec = optval / hz;
otv.tv_usec = (optval % hz) * tick;
error = sockopt_set(sopt, &otv, sizeof(otv));
break;
}
#endif /* COMPAT_50 */
case SO_SNDTIMEO:
case SO_RCVTIMEO:
optval = (sopt->sopt_name == SO_SNDTIMEO ?
optval = (opt == SO_SNDTIMEO ?
so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
tv.tv_sec = optval / hz;