From 468b08e5530412e0e54d0e8a91d9708e93ef0340 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 11 Oct 2013 16:44:48 +0200 Subject: [PATCH] Use bind() from FreeBSD --- freebsd/sys/kern/uipc_syscalls.c | 30 ++++++++ freebsd/sys/sys/sysproto.h | 6 ++ .../include/machine/rtems-bsd-syscall-api.h | 2 + rtemsbsd/rtems/rtems-bsd-syscalls.c | 75 ------------------- testsuite/syscalls01/test_main.c | 71 ++++++++++++++++++ 5 files changed, 109 insertions(+), 75 deletions(-) diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c index 451b4b18..1e96598f 100644 --- a/freebsd/sys/kern/uipc_syscalls.c +++ b/freebsd/sys/kern/uipc_syscalls.c @@ -271,6 +271,12 @@ socket(int domain, int type, int protocol) /* ARGSUSED */ int bind(td, uap) +#else /* __rtems__ */ +static int kern_bind(struct thread *, int, struct sockaddr *); + +static int +rtems_bsd_bind(td, uap) +#endif /* __rtems__ */ struct thread *td; struct bind_args /* { int s; @@ -288,6 +294,27 @@ bind(td, uap) free(sa, M_SONAME); return (error); } +#ifdef __rtems__ +int +bind(int socket, const struct sockaddr *address, socklen_t address_len) +{ + struct thread *td = rtems_bsd_get_curthread_or_null(); + struct bind_args ua = { + .s = socket, + .name = (caddr_t) address, + .namelen = address_len + }; + int error; + + if (td != NULL) { + error = rtems_bsd_bind(td, &ua); + } else { + error = ENOMEM; + } + + return rtems_bsd_error_to_status_and_errno(error); +} +#endif /* __rtems__ */ int kern_bind(td, fd, sa) @@ -317,6 +344,7 @@ kern_bind(td, fd, sa) return (error); } +#ifndef __rtems__ /* ARGSUSED */ int listen(td, uap) @@ -1763,6 +1791,7 @@ sockargs(mp, buf, buflen, type) } return (error); } +#endif /* __rtems__ */ int getsockaddr(namp, uaddr, len) @@ -1792,6 +1821,7 @@ getsockaddr(namp, uaddr, len) return (error); } +#ifndef __rtems__ #include struct sendfile_sync { diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index d22197b2..1eb46fc1 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -366,11 +366,17 @@ struct getpriority_args { char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)]; char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)]; }; +#endif /* __rtems__ */ struct bind_args { char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)]; char name_l_[PADL_(caddr_t)]; caddr_t name; char name_r_[PADR_(caddr_t)]; +#ifndef __rtems__ char namelen_l_[PADL_(int)]; int namelen; char namelen_r_[PADR_(int)]; +#else /* __rtems__ */ + 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)]; diff --git a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h index acc75a03..c96da481 100644 --- a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h +++ b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h @@ -55,6 +55,8 @@ int pselect(int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +int bind(int, const struct sockaddr *, socklen_t); + int shutdown(int, int); int socket(int, int, int); diff --git a/rtemsbsd/rtems/rtems-bsd-syscalls.c b/rtemsbsd/rtems/rtems-bsd-syscalls.c index d628b21a..c1412581 100644 --- a/rtemsbsd/rtems/rtems-bsd-syscalls.c +++ b/rtemsbsd/rtems/rtems-bsd-syscalls.c @@ -159,86 +159,11 @@ sockargs(mp, buf, buflen, type) return (error); } -int -getsockaddr(namp, uaddr, len) - struct sockaddr **namp; - caddr_t uaddr; - size_t len; -{ - struct sockaddr *sa; - int error; - - if (len > SOCK_MAXADDRLEN) - return (ENAMETOOLONG); - if (len < offsetof(struct sockaddr, sa_data[0])) - return (EINVAL); - sa = malloc(len, M_SONAME, M_WAITOK); - error = copyin(uaddr, sa, len); - if (error) { - free(sa, M_SONAME); - } else { -#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN - if (sa->sa_family == 0 && sa->sa_len < AF_MAX) - sa->sa_family = sa->sa_len; -#endif - sa->sa_len = len; - *namp = sa; - } - return (error); -} - /* ********************************************************************* * BSD-style entry points * ********************************************************************* */ -int -kern_bind(td, fd, sa) - struct thread *td; - int fd; - struct sockaddr *sa; -{ - struct socket *so; - int error; - - if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { - error = EBADF; - return (error); - } -#ifdef KTRACE - if (KTRPOINT(td, KTR_STRUCT)) - ktrsockaddr(sa); -#endif -#ifdef MAC - error = mac_socket_check_bind(td->td_ucred, so, sa); - if (error == 0) -#endif - error = sobind(so, sa, td); - return (error); -} - -int -bind (int s, struct sockaddr *name, int namelen) -{ - struct thread *td; - struct sockaddr *sa; - int error; - - error = getsockaddr(&sa, name, namelen); - if( error == 0 ) - { - td = curthread; - error = kern_bind(td, s, sa); - free(sa, M_SONAME); - } - if( error == 0 ) - { - return error; - } - errno = error; - return -1; -} - int kern_connect(td, fd, sa) struct thread *td; diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c index 6f8dfcbf..6ea212a2 100644 --- a/testsuite/syscalls01/test_main.c +++ b/testsuite/syscalls01/test_main.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -216,6 +217,18 @@ static socket_test socket_tests[] = { { AF_IEEE80211, SOCK_DGRAM, 0, EPROTONOSUPPORT } }; +static void +init_addr(struct sockaddr_in *addr) +{ + int ok; + + memset(addr, 0, sizeof(*addr)); + addr->sin_family = AF_INET; + addr->sin_port = htons(1234); + ok = inet_aton("127.0.0.1", &addr->sin_addr); + assert(ok != 0); +} + static void no_mem_task(rtems_task_argument arg) { @@ -444,6 +457,63 @@ test_socket_fstat_and_shutdown(void) assert(rtems_resource_snapshot_check(&snapshot)); } +static void +no_mem_socket_bind(int fd) +{ + struct sockaddr_in addr; + int rv; + + errno = 0; + rv = bind(fd, (const struct sockaddr *) &addr, sizeof(addr)); + assert(rv == -1); + assert(errno == ENOMEM); +} + +static void +test_socket_bind(void) +{ + rtems_resource_snapshot snapshot; + struct sockaddr_in addr; + int sd; + int rv; + + puts("test socket bind"); + + rtems_resource_snapshot_take(&snapshot); + + init_addr(&addr); + + sd = socket(PF_INET, SOCK_DGRAM, 0); + assert(sd >= 0); + + do_no_mem_test(no_mem_socket_bind, sd); + + errno = 0; + rv = bind(sd, (const struct sockaddr *) &addr, SOCK_MAXADDRLEN + 1); + assert(rv == -1); + assert(errno == ENAMETOOLONG); + + errno = 0; + rv = bind(sd, (const struct sockaddr *) &addr, 0); + assert(rv == -1); + assert(errno == EINVAL); + + errno = 0; + rv = bind(sd, (const struct sockaddr *) &addr, sizeof(addr)); + assert(rv == -1); + assert(errno == EADDRNOTAVAIL); + + rv = close(sd); + assert(rv == 0); + + errno = 0; + rv = bind(sd, (struct sockaddr *) &addr, sizeof(addr)); + assert(rv == -1); + assert(errno == EBADF); + + assert(rtems_resource_snapshot_check(&snapshot)); +} + static void test_main(void) { @@ -452,6 +522,7 @@ test_main(void) test_socket_unsupported_ops(); test_socket_fstat_and_shutdown(); + test_socket_bind(); puts("*** END OF " TEST_NAME " TEST ***"); exit(0);