Use getsockopt() and setsockopt() from FreeBSD

This commit is contained in:
Sebastian Huber
2013-10-14 12:53:43 +02:00
parent 7c2b59c831
commit ac78dd2440
5 changed files with 182 additions and 137 deletions

View File

@@ -61,8 +61,12 @@ int bind(int, const struct sockaddr *, socklen_t);
int connect(int, const struct sockaddr *, socklen_t);
int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict);
int listen(int, int);
int setsockopt(int, int, int, const void *, socklen_t);
int shutdown(int, int);
int socket(int, int, int);

View File

@@ -619,140 +619,6 @@ done2:
return -1;
}
int
kern_setsockopt(td, s, level, name, val, valseg, valsize)
struct thread *td;
int s;
int level;
int name;
void *val;
enum uio_seg valseg;
socklen_t valsize;
{
int error;
struct socket *so;
struct sockopt sopt;
if (val == NULL && valsize != 0)
return (EFAULT);
if ((int)valsize < 0)
return (EINVAL);
sopt.sopt_dir = SOPT_SET;
sopt.sopt_level = level;
sopt.sopt_name = name;
sopt.sopt_val = val;
sopt.sopt_valsize = valsize;
switch (valseg) {
case UIO_USERSPACE:
sopt.sopt_td = td;
break;
case UIO_SYSSPACE:
sopt.sopt_td = NULL;
break;
default:
panic("kern_setsockopt called with bad valseg");
}
if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
error = EBADF;
return error;
}
CURVNET_SET(so->so_vnet);
error = sosetopt(so, &sopt);
CURVNET_RESTORE();
return(error);
}
int
setsockopt (int s, int level, int name, const void *val, socklen_t valsize)
{
struct thread *td;
int error;
td = curthread;
error = kern_setsockopt(td, s, level, name, val, UIO_USERSPACE, valsize);
if( error == 0 )
{
return error;
}
errno = error;
return -1;
}
int
kern_getsockopt(td, s, level, name, val, valseg, valsize)
struct thread *td;
int s;
int level;
int name;
void *val;
enum uio_seg valseg;
socklen_t *valsize;
{
int error;
struct socket *so;
struct sockopt sopt;
if (val == NULL)
*valsize = 0;
if ((int)*valsize < 0)
return (EINVAL);
sopt.sopt_dir = SOPT_GET;
sopt.sopt_level = level;
sopt.sopt_name = name;
sopt.sopt_val = val;
sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
switch (valseg) {
case UIO_USERSPACE:
sopt.sopt_td = td;
break;
case UIO_SYSSPACE:
sopt.sopt_td = NULL;
break;
default:
panic("kern_getsockopt called with bad valseg");
}
if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
error = EBADF;
return error;
}
CURVNET_SET(so->so_vnet);
error = sogetopt(so, &sopt);
CURVNET_RESTORE();
*valsize = sopt.sopt_valsize;
return (error);
}
int
getsockopt (int s, int level, int name, void *val, socklen_t *avalsize)
{
struct thread *td;
socklen_t valsize;
int error = 0;
td = curthread;
if (val) {
error = copyin(avalsize, &valsize, sizeof (valsize));
}
if( error == 0 )
{
error = kern_getsockopt(td, s, level, name, val, UIO_USERSPACE, &valsize);
if (error == 0)
error = copyout(&valsize, avalsize, sizeof (valsize));
}
if( error == 0 )
{
return error;
}
errno = error;
return -1;
}
int
kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
socklen_t *alen)