mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-10-16 01:02:07 +08:00
Use getpeername() from FreeBSD
This commit is contained in:
@@ -1799,7 +1799,13 @@ ogetsockname(td, uap)
|
||||
return (getsockname1(td, uap, 1));
|
||||
}
|
||||
#endif /* COMPAT_OLDSOCK */
|
||||
#endif /* __rtems__ */
|
||||
|
||||
#ifdef __rtems__
|
||||
static int
|
||||
kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
|
||||
socklen_t *alen);
|
||||
#endif /* __rtems__ */
|
||||
/*
|
||||
* getpeername1() - Get name of peer for connected socket.
|
||||
*/
|
||||
@@ -1838,6 +1844,28 @@ getpeername1(td, uap, compat)
|
||||
error = copyout(&len, uap->alen, sizeof(len));
|
||||
return (error);
|
||||
}
|
||||
#ifdef __rtems__
|
||||
int
|
||||
getpeername(int socket, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len)
|
||||
{
|
||||
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||
struct getpeername_args ua = {
|
||||
.fdes = socket,
|
||||
.asa = address,
|
||||
.alen = address_len
|
||||
};
|
||||
int error;
|
||||
|
||||
if (td != NULL) {
|
||||
error = getpeername1(td, &ua);
|
||||
} else {
|
||||
error = ENOMEM;
|
||||
}
|
||||
|
||||
return rtems_bsd_error_to_status_and_errno(error);
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
int
|
||||
kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
|
||||
@@ -1885,6 +1913,7 @@ done:
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef __rtems__
|
||||
int
|
||||
getpeername(td, uap)
|
||||
struct thread *td;
|
||||
|
@@ -151,12 +151,12 @@ struct accept_args {
|
||||
char name_l_[PADL_(struct sockaddr *__restrict)]; struct sockaddr *__restrict name; char name_r_[PADR_(struct sockaddr *__restrict)];
|
||||
char anamelen_l_[PADL_(__socklen_t *__restrict)]; __socklen_t *__restrict anamelen; char anamelen_r_[PADR_(__socklen_t *__restrict)];
|
||||
};
|
||||
#ifndef __rtems__
|
||||
struct getpeername_args {
|
||||
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 alen_l_[PADL_(__socklen_t *__restrict)]; __socklen_t *__restrict alen; char alen_r_[PADR_(__socklen_t *__restrict)];
|
||||
};
|
||||
#ifndef __rtems__
|
||||
struct getsockname_args {
|
||||
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)];
|
||||
|
@@ -61,6 +61,8 @@ int bind(int, const struct sockaddr *, socklen_t);
|
||||
|
||||
int connect(int, const struct sockaddr *, socklen_t);
|
||||
|
||||
int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict);
|
||||
|
||||
int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict);
|
||||
|
||||
int listen(int, int);
|
||||
|
@@ -619,98 +619,6 @@ done2:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
kern_getpeername(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;
|
||||
}
|
||||
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
|
||||
error = ENOTCONN;
|
||||
goto done;
|
||||
}
|
||||
*sa = NULL;
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(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;
|
||||
}
|
||||
done:
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
getpeername1(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_getpeername(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
|
||||
getpeername (int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
struct thread *td;
|
||||
int error;
|
||||
|
||||
td = curthread;
|
||||
error = getpeername1(td, s, name, namelen, 0);
|
||||
if( error == 0 )
|
||||
{
|
||||
return error;
|
||||
}
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
|
||||
socklen_t *alen)
|
||||
|
@@ -827,6 +827,56 @@ test_socket_getsockopt_and_setsockopt(void)
|
||||
assert(rtems_resource_snapshot_check(&snapshot));
|
||||
}
|
||||
|
||||
static void
|
||||
no_mem_socket_getpeername(int fd)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len;
|
||||
int rv;
|
||||
|
||||
errno = 0;
|
||||
addr_len = sizeof(addr);
|
||||
rv = getpeername(fd, (struct sockaddr *) &addr, &addr_len);
|
||||
assert(rv == -1);
|
||||
assert(errno == ENOMEM);
|
||||
}
|
||||
|
||||
static void
|
||||
test_socket_getpeername(void)
|
||||
{
|
||||
rtems_resource_snapshot snapshot;
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len;
|
||||
int sd;
|
||||
int rv;
|
||||
|
||||
puts("test socket getpeername");
|
||||
|
||||
rtems_resource_snapshot_take(&snapshot);
|
||||
|
||||
sd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
assert(sd >= 0);
|
||||
|
||||
do_no_mem_test(no_mem_socket_getpeername, sd);
|
||||
|
||||
errno = 0;
|
||||
addr_len = sizeof(addr);
|
||||
rv = getpeername(sd, (struct sockaddr *) &addr, &addr_len);
|
||||
assert(rv == -1);
|
||||
assert(errno == ENOTCONN);
|
||||
|
||||
rv = close(sd);
|
||||
assert(rv == 0);
|
||||
|
||||
errno = 0;
|
||||
addr_len = sizeof(addr);
|
||||
rv = getpeername(sd, (struct sockaddr *) &addr, &addr_len);
|
||||
assert(rv == -1);
|
||||
assert(errno == EBADF);
|
||||
|
||||
assert(rtems_resource_snapshot_check(&snapshot));
|
||||
}
|
||||
|
||||
static void
|
||||
test_main(void)
|
||||
{
|
||||
@@ -841,6 +891,7 @@ test_main(void)
|
||||
test_socket_listen();
|
||||
test_socket_accept();
|
||||
test_socket_getsockopt_and_setsockopt();
|
||||
test_socket_getpeername();
|
||||
|
||||
puts("*** END OF " TEST_NAME " TEST ***");
|
||||
exit(0);
|
||||
|
Reference in New Issue
Block a user