From 6676de488afe2d184eb277d207767fb50ba63261 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 14 Oct 2013 09:48:56 +0200 Subject: [PATCH] Use connect() from FreeBSD --- freebsd/sys/kern/uipc_syscalls.c | 31 ++++++- freebsd/sys/sys/sysproto.h | 6 +- .../include/machine/rtems-bsd-syscall-api.h | 2 + rtemsbsd/rtems/rtems-bsd-syscalls.c | 80 ------------------- testsuite/syscalls01/test_main.c | 58 ++++++++++++++ 5 files changed, 95 insertions(+), 82 deletions(-) diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c index 1e96598f..e4ec4baa 100644 --- a/freebsd/sys/kern/uipc_syscalls.c +++ b/freebsd/sys/kern/uipc_syscalls.c @@ -608,10 +608,17 @@ oaccept(td, uap) return (accept1(td, uap, 1)); } #endif /* COMPAT_OLDSOCK */ +#endif /* __rtems__ */ /* ARGSUSED */ +#ifndef __rtems__ int -connect(td, uap) +#else /* __rtems__ */ +static int kern_connect(struct thread *, int, struct sockaddr *); + +static int +rtems_bsd_connect(td, uap) +#endif /* __rtems__ */ struct thread *td; struct connect_args /* { int s; @@ -630,6 +637,27 @@ connect(td, uap) free(sa, M_SONAME); return (error); } +#ifdef __rtems__ +int +connect(int socket, const struct sockaddr *address, socklen_t address_len) +{ + struct thread *td = rtems_bsd_get_curthread_or_null(); + struct connect_args ua = { + .s = socket, + .name = (caddr_t) address, + .namelen = address_len + }; + int error; + + if (td != NULL) { + error = rtems_bsd_connect(td, &ua); + } else { + error = ENOMEM; + } + + return rtems_bsd_error_to_status_and_errno(error); +} +#endif /* __rtems__ */ int @@ -693,6 +721,7 @@ done1: return (error); } +#ifndef __rtems__ int kern_socketpair(struct thread *td, int domain, int type, int protocol, int *rsv) diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index 1eb46fc1..93aa23b6 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -356,12 +356,16 @@ struct socket_args { char type_l_[PADL_(int)]; int type; char type_r_[PADR_(int)]; char protocol_l_[PADL_(int)]; int protocol; char protocol_r_[PADR_(int)]; }; -#ifndef __rtems__ struct connect_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 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)]; diff --git a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h index c96da481..01d95894 100644 --- a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h +++ b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h @@ -57,6 +57,8 @@ int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); int bind(int, const struct sockaddr *, socklen_t); +int connect(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 c1412581..641e55c3 100644 --- a/rtemsbsd/rtems/rtems-bsd-syscalls.c +++ b/rtemsbsd/rtems/rtems-bsd-syscalls.c @@ -164,86 +164,6 @@ sockargs(mp, buf, buflen, type) * BSD-style entry points * ********************************************************************* */ -int -kern_connect(td, fd, sa) - struct thread *td; - int fd; - struct sockaddr *sa; -{ - struct socket *so; - int error; - int interrupted = 0; - - if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { - error = EBADF; - return (error); - } - - if (so->so_state & SS_ISCONNECTING) { - error = EALREADY; - goto done1; - } -#ifdef KTRACE - if (KTRPOINT(td, KTR_STRUCT)) - ktrsockaddr(sa); -#endif -#ifdef MAC - error = mac_socket_check_connect(td->td_ucred, so, sa); - if (error) - goto bad; -#endif - error = soconnect(so, sa, td); - if (error) - goto bad; - if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { - error = EINPROGRESS; - goto done1; - } - SOCK_LOCK(so); - while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { - error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH, - "connec", 0); - if (error) { - if (error == EINTR || error == ERESTART) - interrupted = 1; - break; - } - } - if (error == 0) { - error = so->so_error; - so->so_error = 0; - } - SOCK_UNLOCK(so); -bad: - if (!interrupted) - so->so_state &= ~SS_ISCONNECTING; - if (error == ERESTART) - error = EINTR; -done1: - return (error); -} - -int -connect (int s, struct sockaddr *name, int namelen) -{ - int error; - struct sockaddr *sa; - struct thread *td; - - error = getsockaddr(&sa, name, namelen); - if (error == 0) - { - td = curthread; - error = kern_connect(td, s, sa); - free(sa, M_SONAME); - } - if( error == 0 ) - { - return error; - } - errno = error; - return -1; -} int listen (int s, int backlog) diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c index c86d687d..b34c5fd5 100644 --- a/testsuite/syscalls01/test_main.c +++ b/testsuite/syscalls01/test_main.c @@ -565,6 +565,63 @@ test_socket_bind(void) assert(rtems_resource_snapshot_check(&snapshot)); } +static void +no_mem_socket_connect(int fd) +{ + struct sockaddr_in addr; + int rv; + + errno = 0; + rv = connect(fd, (const struct sockaddr *) &addr, sizeof(addr)); + assert(rv == -1); + assert(errno == ENOMEM); +} + +static void +test_socket_connect(void) +{ + rtems_resource_snapshot snapshot; + struct sockaddr_in addr; + int sd; + int rv; + + puts("test socket connect"); + + 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_connect, sd); + + errno = 0; + rv = connect(sd, (const struct sockaddr *) &addr, SOCK_MAXADDRLEN + 1); + assert(rv == -1); + assert(errno == ENAMETOOLONG); + + errno = 0; + rv = connect(sd, (const struct sockaddr *) &addr, 0); + assert(rv == -1); + assert(errno == EINVAL); + + errno = 0; + rv = connect(sd, (const struct sockaddr *) &addr, sizeof(addr)); + assert(rv == -1); + assert(errno == ENETUNREACH); + + rv = close(sd); + assert(rv == 0); + + errno = 0; + rv = connect(sd, (struct sockaddr *) &addr, sizeof(addr)); + assert(rv == -1); + assert(errno == EBADF); + + assert(rtems_resource_snapshot_check(&snapshot)); +} + static void test_main(void) { @@ -575,6 +632,7 @@ test_main(void) test_socket_fstat_and_shutdown(); test_socket_ioctl(); test_socket_bind(); + test_socket_connect(); puts("*** END OF " TEST_NAME " TEST ***"); exit(0);