mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-06-29 18:20:14 +08:00
Use getsockopt() and setsockopt() from FreeBSD
This commit is contained in:
parent
7c2b59c831
commit
ac78dd2440
@ -1486,10 +1486,18 @@ shutdown(int socket, int how)
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
#ifndef __rtems__
|
||||
/* ARGSUSED */
|
||||
#ifndef __rtems__
|
||||
int
|
||||
setsockopt(td, uap)
|
||||
#else /* __rtems__ */
|
||||
static int
|
||||
kern_setsockopt( struct thread *td, int s, int level, int name, void *val,
|
||||
enum uio_seg valseg, socklen_t valsize);
|
||||
|
||||
static int
|
||||
rtems_bsd_setsockopt(td, uap)
|
||||
#endif /* __rtems__ */
|
||||
struct thread *td;
|
||||
struct setsockopt_args /* {
|
||||
int s;
|
||||
@ -1503,6 +1511,30 @@ setsockopt(td, uap)
|
||||
return (kern_setsockopt(td, uap->s, uap->level, uap->name,
|
||||
uap->val, UIO_USERSPACE, uap->valsize));
|
||||
}
|
||||
#ifdef __rtems__
|
||||
int
|
||||
setsockopt(int socket, int level, int option_name, const void *option_value,
|
||||
socklen_t option_len)
|
||||
{
|
||||
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||
struct setsockopt_args ua = {
|
||||
.s = socket,
|
||||
.level = level,
|
||||
.name = option_name,
|
||||
.val = __DECONST(void *, option_value),
|
||||
.valsize = option_len
|
||||
};
|
||||
int error;
|
||||
|
||||
if (td != NULL) {
|
||||
error = rtems_bsd_setsockopt(td, &ua);
|
||||
} else {
|
||||
error = ENOMEM;
|
||||
}
|
||||
|
||||
return rtems_bsd_error_to_status_and_errno(error);
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
int
|
||||
kern_setsockopt(td, s, level, name, val, valseg, valsize)
|
||||
@ -1553,8 +1585,17 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
#ifndef __rtems__
|
||||
int
|
||||
getsockopt(td, uap)
|
||||
#else /* __rtems__ */
|
||||
static int
|
||||
kern_getsockopt( struct thread *td, int s, int level, int name, void *val,
|
||||
enum uio_seg valseg, socklen_t *valsize);
|
||||
|
||||
static int
|
||||
rtems_bsd_getsockopt(td, uap)
|
||||
#endif /* __rtems__ */
|
||||
struct thread *td;
|
||||
struct getsockopt_args /* {
|
||||
int s;
|
||||
@ -1580,6 +1621,30 @@ getsockopt(td, uap)
|
||||
error = copyout(&valsize, uap->avalsize, sizeof (valsize));
|
||||
return (error);
|
||||
}
|
||||
#ifdef __rtems__
|
||||
int
|
||||
getsockopt(int socket, int level, int option_name, void *__restrict
|
||||
option_value, socklen_t *__restrict option_len)
|
||||
{
|
||||
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||
struct getsockopt_args ua = {
|
||||
.s = socket,
|
||||
.level = level,
|
||||
.name = option_name,
|
||||
.val = (caddr_t) option_value,
|
||||
.avalsize = option_len
|
||||
};
|
||||
int error;
|
||||
|
||||
if (td != NULL) {
|
||||
error = rtems_bsd_getsockopt(td, &ua);
|
||||
} else {
|
||||
error = ENOMEM;
|
||||
}
|
||||
|
||||
return rtems_bsd_error_to_status_and_errno(error);
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/*
|
||||
* Kernel version of getsockopt.
|
||||
@ -1634,6 +1699,7 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize)
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef __rtems__
|
||||
/*
|
||||
* getsockname1() - Get socket name.
|
||||
*/
|
||||
|
@ -382,15 +382,17 @@ struct bind_args {
|
||||
char namelen_l_[PADL_(__socklen_t)]; __socklen_t namelen; char namelen_r_[PADR_(__socklen_t)];
|
||||
#endif /* __rtems__ */
|
||||
};
|
||||
#ifndef __rtems__
|
||||
struct setsockopt_args {
|
||||
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
|
||||
char level_l_[PADL_(int)]; int level; char level_r_[PADR_(int)];
|
||||
char name_l_[PADL_(int)]; int name; char name_r_[PADR_(int)];
|
||||
char val_l_[PADL_(caddr_t)]; caddr_t val; char val_r_[PADR_(caddr_t)];
|
||||
#ifndef __rtems__
|
||||
char valsize_l_[PADL_(int)]; int valsize; char valsize_r_[PADR_(int)];
|
||||
};
|
||||
#else /* __rtems__ */
|
||||
char valsize_l_[PADL_(__socklen_t)]; __socklen_t valsize; char valsize_r_[PADR_(__socklen_t)];
|
||||
#endif /* __rtems__ */
|
||||
};
|
||||
struct listen_args {
|
||||
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
|
||||
char backlog_l_[PADL_(int)]; int backlog; char backlog_r_[PADR_(int)];
|
||||
@ -404,13 +406,19 @@ struct getrusage_args {
|
||||
char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)];
|
||||
char rusage_l_[PADL_(struct rusage *)]; struct rusage * rusage; char rusage_r_[PADR_(struct rusage *)];
|
||||
};
|
||||
#endif /* __rtems__ */
|
||||
struct getsockopt_args {
|
||||
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
|
||||
char level_l_[PADL_(int)]; int level; char level_r_[PADR_(int)];
|
||||
char name_l_[PADL_(int)]; int name; char name_r_[PADR_(int)];
|
||||
char val_l_[PADL_(caddr_t)]; caddr_t val; char val_r_[PADR_(caddr_t)];
|
||||
#ifndef __rtems__
|
||||
char avalsize_l_[PADL_(int *)]; int * avalsize; char avalsize_r_[PADR_(int *)];
|
||||
#else /* __rtems__ */
|
||||
char avalsize_l_[PADL_(__socklen_t *)]; __socklen_t * avalsize; char avalsize_r_[PADR_(__socklen_t *)];
|
||||
#endif /* __rtems__ */
|
||||
};
|
||||
#ifndef __rtems__
|
||||
struct readv_args {
|
||||
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
|
||||
char iovp_l_[PADL_(struct iovec *)]; struct iovec * iovp; char iovp_r_[PADR_(struct iovec *)];
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -727,6 +727,106 @@ test_socket_accept(void)
|
||||
assert(rtems_resource_snapshot_check(&snapshot));
|
||||
}
|
||||
|
||||
static void
|
||||
no_mem_socket_getsockopt_and_setsockopt(int fd)
|
||||
{
|
||||
int rv;
|
||||
int optval;
|
||||
socklen_t optlen;
|
||||
|
||||
errno = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, &optlen);
|
||||
assert(rv == -1);
|
||||
assert(errno == ENOMEM);
|
||||
|
||||
errno = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen);
|
||||
assert(rv == -1);
|
||||
assert(errno == ENOMEM);
|
||||
}
|
||||
|
||||
static void
|
||||
test_socket_getsockopt_and_setsockopt(void)
|
||||
{
|
||||
rtems_resource_snapshot snapshot;
|
||||
int optval;
|
||||
socklen_t optlen;
|
||||
int sd;
|
||||
int rv;
|
||||
|
||||
puts("test socket getsockopt and setsockopt");
|
||||
|
||||
rtems_resource_snapshot_take(&snapshot);
|
||||
|
||||
sd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
assert(sd >= 0);
|
||||
|
||||
do_no_mem_test(no_mem_socket_getsockopt_and_setsockopt, sd);
|
||||
|
||||
errno = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = getsockopt(sd, SOL_SOCKET, -1, &optval, &optlen);
|
||||
assert(rv == -1);
|
||||
assert(errno == ENOPROTOOPT);
|
||||
|
||||
errno = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = setsockopt(sd, SOL_SOCKET, -1, &optval, optlen);
|
||||
assert(rv == -1);
|
||||
assert(errno == ENOPROTOOPT);
|
||||
|
||||
errno = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = getsockopt(sd, -1, SO_REUSEADDR, &optval, &optlen);
|
||||
assert(rv == -1);
|
||||
assert(errno == EINVAL);
|
||||
|
||||
errno = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = setsockopt(sd, -1, SO_REUSEADDR, &optval, optlen);
|
||||
assert(rv == -1);
|
||||
assert(errno == EINVAL);
|
||||
|
||||
optval = -1;
|
||||
optlen = sizeof(optval);
|
||||
rv = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, &optlen);
|
||||
assert(rv == 0);
|
||||
assert(optval == 0);
|
||||
assert(optlen == sizeof(optval));
|
||||
|
||||
optval = 1;
|
||||
optlen = sizeof(optval);
|
||||
rv = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen);
|
||||
assert(rv == 0);
|
||||
|
||||
optval = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, &optlen);
|
||||
assert(rv == 0);
|
||||
assert(optval != 0);
|
||||
assert(optlen == sizeof(optval));
|
||||
|
||||
rv = close(sd);
|
||||
assert(rv == 0);
|
||||
|
||||
errno = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, &optlen);
|
||||
assert(rv == -1);
|
||||
assert(errno == EBADF);
|
||||
|
||||
errno = 0;
|
||||
optval = 0;
|
||||
optlen = sizeof(optval);
|
||||
rv = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen);
|
||||
assert(rv == -1);
|
||||
assert(errno == EBADF);
|
||||
|
||||
assert(rtems_resource_snapshot_check(&snapshot));
|
||||
}
|
||||
|
||||
static void
|
||||
test_main(void)
|
||||
{
|
||||
@ -740,6 +840,7 @@ test_main(void)
|
||||
test_socket_connect();
|
||||
test_socket_listen();
|
||||
test_socket_accept();
|
||||
test_socket_getsockopt_and_setsockopt();
|
||||
|
||||
puts("*** END OF " TEST_NAME " TEST ***");
|
||||
exit(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user