Use getsockname() from FreeBSD

This commit is contained in:
Sebastian Huber 2013-10-14 13:24:10 +02:00
parent 0beab1e86a
commit 8989c110f5
5 changed files with 86 additions and 89 deletions

View File

@ -1699,7 +1699,11 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize)
return (error); return (error);
} }
#ifndef __rtems__ #ifdef __rtems__
int
kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
socklen_t *alen);
#endif /* __rtems__ */
/* /*
* getsockname1() - Get socket name. * getsockname1() - Get socket name.
*/ */
@ -1738,6 +1742,28 @@ getsockname1(td, uap, compat)
error = copyout(&len, uap->alen, sizeof(len)); error = copyout(&len, uap->alen, sizeof(len));
return (error); return (error);
} }
#ifdef __rtems__
int
getsockname(int socket, struct sockaddr *__restrict address,
socklen_t *__restrict address_len)
{
struct thread *td = rtems_bsd_get_curthread_or_null();
struct getsockname_args ua = {
.fdes = socket,
.asa = address,
.alen = address_len
};
int error;
if (td != NULL) {
error = getsockname1(td, &ua);
} else {
error = ENOMEM;
}
return rtems_bsd_error_to_status_and_errno(error);
}
#endif /* __rtems__ */
int int
kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
@ -1780,6 +1806,7 @@ bad:
return (error); return (error);
} }
#ifndef __rtems__
int int
getsockname(td, uap) getsockname(td, uap)
struct thread *td; struct thread *td;

View File

@ -156,12 +156,12 @@ struct getpeername_args {
char asa_l_[PADL_(struct sockaddr *__restrict)]; struct sockaddr *__restrict asa; char asa_r_[PADR_(struct sockaddr *__restrict)]; char asa_l_[PADL_(struct sockaddr *__restrict)]; struct sockaddr *__restrict asa; char asa_r_[PADR_(struct sockaddr *__restrict)];
char alen_l_[PADL_(__socklen_t *__restrict)]; __socklen_t *__restrict alen; char alen_r_[PADR_(__socklen_t *__restrict)]; char alen_l_[PADL_(__socklen_t *__restrict)]; __socklen_t *__restrict alen; char alen_r_[PADR_(__socklen_t *__restrict)];
}; };
#ifndef __rtems__
struct getsockname_args { struct getsockname_args {
char fdes_l_[PADL_(int)]; int fdes; char fdes_r_[PADR_(int)]; char fdes_l_[PADL_(int)]; int fdes; char fdes_r_[PADR_(int)];
char asa_l_[PADL_(struct sockaddr *__restrict)]; struct sockaddr *__restrict asa; char asa_r_[PADR_(struct sockaddr *__restrict)]; char asa_l_[PADL_(struct sockaddr *__restrict)]; struct sockaddr *__restrict asa; char asa_r_[PADR_(struct sockaddr *__restrict)];
char alen_l_[PADL_(__socklen_t *__restrict)]; __socklen_t *__restrict alen; char alen_r_[PADR_(__socklen_t *__restrict)]; char alen_l_[PADL_(__socklen_t *__restrict)]; __socklen_t *__restrict alen; char alen_r_[PADR_(__socklen_t *__restrict)];
}; };
#ifndef __rtems__
struct access_args { struct access_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];

View File

@ -63,6 +63,8 @@ int connect(int, const struct sockaddr *, socklen_t);
int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict); int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict);
int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict);
int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict); int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict);
int listen(int, int); int listen(int, int);

View File

@ -619,93 +619,6 @@ done2:
return -1; return -1;
} }
int
kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
socklen_t *alen)
{
struct socket *so;
socklen_t len;
int error;
if (*alen < 0)
return (EINVAL);
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) {
error = EBADF;
return error;
}
*sa = NULL;
CURVNET_SET(so->so_vnet);
error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa);
CURVNET_RESTORE();
if (error)
goto bad;
if (*sa == NULL)
len = 0;
else
len = MIN(*alen, (*sa)->sa_len);
*alen = len;
#ifdef KTRACE
if (KTRPOINT(td, KTR_STRUCT))
ktrsockaddr(*sa);
#endif
bad:
if (error && *sa) {
free(*sa, M_SONAME);
*sa = NULL;
}
return (error);
}
static int
getsockname1(td, fdes, asa, alen, compat)
struct thread *td;
int fdes;
struct sockaddr * asa;
socklen_t * alen;
int compat;
{
struct sockaddr *sa;
socklen_t len;
int error;
error = copyin(alen, &len, sizeof(len));
if (error)
return (error);
error = kern_getsockname(td, fdes, &sa, &len);
if (error)
return (error);
if (len != 0) {
#ifdef COMPAT_OLDSOCK
if (compat)
((struct osockaddr *)sa)->sa_family = sa->sa_family;
#endif
error = copyout(sa, asa, (u_int)len);
}
free(sa, M_SONAME);
if (error == 0)
error = copyout(&len, alen, sizeof(len));
return (error);
}
int
getsockname (int s, struct sockaddr *name, socklen_t *namelen)
{
struct thread *td;
int error;
td = curthread;
error = getsockname1(td, s, name, namelen, 0);
if( error == 0 )
{
return error;
}
errno = error;
return -1;
}
/* /*
************************************************************************ ************************************************************************
* RTEMS I/O HANDLER ROUTINES * * RTEMS I/O HANDLER ROUTINES *

View File

@ -877,6 +877,60 @@ test_socket_getpeername(void)
assert(rtems_resource_snapshot_check(&snapshot)); assert(rtems_resource_snapshot_check(&snapshot));
} }
static void
no_mem_socket_getsockname(int fd)
{
struct sockaddr_in addr;
socklen_t addr_len;
int rv;
errno = 0;
addr_len = sizeof(addr);
rv = getsockname(fd, (struct sockaddr *) &addr, &addr_len);
assert(rv == -1);
assert(errno == ENOMEM);
}
static void
test_socket_getsockname(void)
{
rtems_resource_snapshot snapshot;
struct sockaddr_in addr;
struct sockaddr_in expected_addr;
socklen_t addr_len;
int sd;
int rv;
puts("test socket getsockname");
rtems_resource_snapshot_take(&snapshot);
sd = socket(PF_INET, SOCK_STREAM, 0);
assert(sd >= 0);
do_no_mem_test(no_mem_socket_getsockname, sd);
memset(&addr, 0xff, sizeof(addr));
addr_len = sizeof(addr);
rv = getsockname(sd, (struct sockaddr *) &addr, &addr_len);
assert(rv == 0);
memset(&expected_addr, 0, sizeof(expected_addr));
expected_addr.sin_len = sizeof(expected_addr);
expected_addr.sin_family = AF_INET;
assert(memcmp(&addr, &expected_addr, sizeof(addr)) == 0);
rv = close(sd);
assert(rv == 0);
errno = 0;
addr_len = sizeof(addr);
rv = getsockname(sd, (struct sockaddr *) &addr, &addr_len);
assert(rv == -1);
assert(errno == EBADF);
assert(rtems_resource_snapshot_check(&snapshot));
}
static void static void
test_main(void) test_main(void)
{ {
@ -892,6 +946,7 @@ test_main(void)
test_socket_accept(); test_socket_accept();
test_socket_getsockopt_and_setsockopt(); test_socket_getsockopt_and_setsockopt();
test_socket_getpeername(); test_socket_getpeername();
test_socket_getsockname();
puts("*** END OF " TEST_NAME " TEST ***"); puts("*** END OF " TEST_NAME " TEST ***");
exit(0); exit(0);