From 8989c110f525c8dda381dba90f502635fc29883a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 14 Oct 2013 13:24:10 +0200 Subject: [PATCH] Use getsockname() from FreeBSD --- freebsd/sys/kern/uipc_syscalls.c | 29 ++++++- freebsd/sys/sys/sysproto.h | 2 +- .../include/machine/rtems-bsd-syscall-api.h | 2 + rtemsbsd/rtems/rtems-bsd-syscalls.c | 87 ------------------- testsuite/syscalls01/test_main.c | 55 ++++++++++++ 5 files changed, 86 insertions(+), 89 deletions(-) diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c index 249bc2b7..d5f97bb4 100644 --- a/freebsd/sys/kern/uipc_syscalls.c +++ b/freebsd/sys/kern/uipc_syscalls.c @@ -1699,7 +1699,11 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize) 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. */ @@ -1738,6 +1742,28 @@ getsockname1(td, uap, compat) error = copyout(&len, uap->alen, sizeof(len)); 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 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, @@ -1780,6 +1806,7 @@ bad: return (error); } +#ifndef __rtems__ int getsockname(td, uap) struct thread *td; diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index a053d5d2..15a65b5f 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -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 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)]; char alen_l_[PADL_(__socklen_t *__restrict)]; __socklen_t *__restrict alen; char alen_r_[PADR_(__socklen_t *__restrict)]; }; +#ifndef __rtems__ struct access_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; diff --git a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h index a75968b2..5d872c1d 100644 --- a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h +++ b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h @@ -63,6 +63,8 @@ int connect(int, const struct sockaddr *, socklen_t); 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 listen(int, int); diff --git a/rtemsbsd/rtems/rtems-bsd-syscalls.c b/rtemsbsd/rtems/rtems-bsd-syscalls.c index 69a25f62..7dabea87 100644 --- a/rtemsbsd/rtems/rtems-bsd-syscalls.c +++ b/rtemsbsd/rtems/rtems-bsd-syscalls.c @@ -619,93 +619,6 @@ done2: 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 * diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c index ce626467..939ca451 100644 --- a/testsuite/syscalls01/test_main.c +++ b/testsuite/syscalls01/test_main.c @@ -877,6 +877,60 @@ test_socket_getpeername(void) 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 test_main(void) { @@ -892,6 +946,7 @@ test_main(void) test_socket_accept(); test_socket_getsockopt_and_setsockopt(); test_socket_getpeername(); + test_socket_getsockname(); puts("*** END OF " TEST_NAME " TEST ***"); exit(0);