Index: kern/uipc_syscalls.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.15 diff -u -u -r1.15 uipc_syscalls.c --- kern/uipc_syscalls.c 19 Sep 2003 08:02:27 -0000 1.15 +++ kern/uipc_syscalls.c 28 Sep 2003 08:46:50 -0000 @@ -950,65 +950,96 @@ } /* - * setsockopt_args(int s, int level, int name, caddr_t val, int valsize) + * If sopt->sopt_td == NULL, then sopt->sopt_val is treated as an + * in kernel pointer instead of a userland pointer. This allows us + * to manipulate socket options in the emulation code. */ -/* ARGSUSED */ int -setsockopt(struct setsockopt_args *uap) +kern_setsockopt(int s, struct sockopt *sopt) { struct thread *td = curthread; struct proc *p = td->td_proc; struct file *fp; - struct sockopt sopt; int error; - if (uap->val == 0 && uap->valsize != 0) + if (sopt->sopt_val == 0 && sopt->sopt_valsize != 0) return (EFAULT); - if (uap->valsize < 0) + if (sopt->sopt_valsize < 0) return (EINVAL); - error = holdsock(p->p_fd, uap->s, &fp); + error = holdsock(p->p_fd, s, &fp); if (error) return (error); + error = sosetopt((struct socket *)fp->f_data, sopt); + fdrop(fp, td); + return (error); +} + +/* + * setsockopt_args(int s, int level, int name, caddr_t val, int valsize) + */ +int +setsockopt(struct setsockopt_args *uap) +{ + struct thread *td = curthread; + struct sockopt sopt; + int error; + sopt.sopt_dir = SOPT_SET; sopt.sopt_level = uap->level; sopt.sopt_name = uap->name; sopt.sopt_val = uap->val; sopt.sopt_valsize = uap->valsize; sopt.sopt_td = td; - error = sosetopt((struct socket *)fp->f_data, &sopt); - fdrop(fp, td); + + error = kern_setsockopt(uap->s, &sopt); return(error); } /* - * getsockopt_Args(int s, int level, int name, caddr_t val, int *avalsize) + * If sopt->sopt_td == NULL, then sopt->sopt_val is treated as an + * in kernel pointer instead of a userland pointer. This allows us + * to manipulate socket options in the emulation code. */ -/* ARGSUSED */ int -getsockopt(struct getsockopt_args *uap) +kern_getsockopt(int s, struct sockopt *sopt) { struct thread *td = curthread; struct proc *p = td->td_proc; - int valsize, error; - struct file *fp; - struct sockopt sopt; + struct file *fp; + int error; + + if (sopt->sopt_val == 0 && sopt->sopt_valsize != 0) + return (EFAULT); + if (sopt->sopt_valsize < 0) + return (EINVAL); - error = holdsock(p->p_fd, uap->s, &fp); + error = holdsock(p->p_fd, s, &fp); if (error) return (error); + + error = sogetopt((struct socket *)fp->f_data, sopt); + fdrop(fp, td); + return (error); +} + +/* + * getsockopt_Args(int s, int level, int name, caddr_t val, int *avalsize) + */ +int +getsockopt(struct getsockopt_args *uap) +{ + struct thread *td = curthread; + struct sockopt sopt; + int error, valsize; + if (uap->val) { - error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize, - sizeof (valsize)); - if (error) { - fdrop(fp, td); + error = copyin(uap->avalsize, &valsize, sizeof(valsize)); + if (error) return (error); - } - if (valsize < 0) { - fdrop(fp, td); + if (valsize < 0) return (EINVAL); - } } else { valsize = 0; } @@ -1017,16 +1048,14 @@ sopt.sopt_level = uap->level; sopt.sopt_name = uap->name; sopt.sopt_val = uap->val; - sopt.sopt_valsize = (size_t)valsize; /* checked non-negative above */ + sopt.sopt_valsize = valsize; sopt.sopt_td = td; - error = sogetopt((struct socket *)fp->f_data, &sopt); + error = kern_getsockopt(uap->s, &sopt); if (error == 0) { valsize = sopt.sopt_valsize; - error = copyout((caddr_t)&valsize, - (caddr_t)uap->avalsize, sizeof (valsize)); + error = copyout(&valsize, uap->avalsize, sizeof(valsize)); } - fdrop(fp, td); return (error); } Index: sys/kern_syscall.h =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/kern_syscall.h,v retrieving revision 1.2 diff -u -u -r1.2 kern_syscall.h --- sys/kern_syscall.h 19 Sep 2003 08:02:27 -0000 1.2 +++ sys/kern_syscall.h 28 Sep 2003 08:40:29 -0000 @@ -33,15 +33,18 @@ struct sockaddr; struct msghdr; +struct sockopt; int kern_accept(int s, struct sockaddr **name, int *namelen, int *res); int kern_bind(int s, struct sockaddr *sa); int kern_connect(int s, struct sockaddr *sa); int kern_listen(int s, int backlog); int kern_getpeername(int s, struct sockaddr **name, int *namelen); +int kern_getsockopt(int s, struct sockopt *sopt); int kern_getsockname(int s, struct sockaddr **name, int *namelen); int kern_recvmsg(int s, struct msghdr *mp, int *res); int kern_sendmsg(int s, struct msghdr *mp, int *res); +int kern_setsockopt(int s, struct sockopt *sopt); int kern_socketpair(int domain, int type, int protocol, int *sockv); #endif /* !_SYS_KERN_SYSCALL_H_ */