From d1558f38f75a0680dae2fc25b46a89b4a149346f Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 16 Nov 2015 09:51:44 +0100 Subject: SOCKETPAIR(2): Port to RTEMS --- freebsd/sys/kern/uipc_syscalls.c | 36 +++++++++++++++++- freebsd/sys/sys/sysproto.h | 2 +- rtemsbsd/include/machine/rtems-bsd-syscall-api.h | 2 + testsuite/syscalls01/test_main.c | 48 ++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 2 deletions(-) diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c index 44804b38..5b57df89 100644 --- a/freebsd/sys/kern/uipc_syscalls.c +++ b/freebsd/sys/kern/uipc_syscalls.c @@ -815,12 +815,13 @@ done1: return (error); } -#ifndef __rtems__ int kern_socketpair(struct thread *td, int domain, int type, int protocol, int *rsv) { +#ifndef __rtems__ struct filedesc *fdp = td->td_proc->p_fd; +#endif /* __rtems__ */ struct file *fp1, *fp2; struct socket *so1, *so2; int fd, error, oflag, fflag; @@ -829,10 +830,12 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol, oflag = 0; fflag = 0; +#ifndef __rtems__ if ((type & SOCK_CLOEXEC) != 0) { type &= ~SOCK_CLOEXEC; oflag |= O_CLOEXEC; } +#endif /* __rtems__ */ if ((type & SOCK_NONBLOCK) != 0) { type &= ~SOCK_NONBLOCK; fflag |= FNONBLOCK; @@ -898,22 +901,53 @@ free1: return (error); } +#ifdef __rtems__ +static +#endif /* __rtems__ */ int sys_socketpair(struct thread *td, struct socketpair_args *uap) { +#ifndef __rtems__ int error, sv[2]; +#else /* __rtems__ */ + int error; + int *sv = uap->rsv; +#endif /* __rtems__ */ error = kern_socketpair(td, uap->domain, uap->type, uap->protocol, sv); if (error) return (error); +#ifndef __rtems__ error = copyout(sv, uap->rsv, 2 * sizeof(int)); if (error) { (void)kern_close(td, sv[0]); (void)kern_close(td, sv[1]); } +#endif /* __rtems__ */ return (error); } +#ifdef __rtems__ +int +socketpair(int domain, int type, int protocol, int *socket_vector) +{ + struct thread *td = rtems_bsd_get_curthread_or_null(); + struct socketpair_args ua = { + .domain = domain, + .type = type, + .protocol = protocol, + .rsv = socket_vector + }; + int error; + + if (td != NULL) { + error = sys_socketpair(td, &ua); + } else { + error = ENOMEM; + } + + return rtems_bsd_error_to_status_and_errno(error); +} #endif /* __rtems__ */ #ifdef __rtems__ diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index 5af3b62c..479eeb4c 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -481,13 +481,13 @@ struct shutdown_args { char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)]; char how_l_[PADL_(int)]; int how; char how_r_[PADR_(int)]; }; -#ifndef __rtems__ struct socketpair_args { char domain_l_[PADL_(int)]; int domain; char domain_r_[PADR_(int)]; char type_l_[PADL_(int)]; int type; char type_r_[PADR_(int)]; char protocol_l_[PADL_(int)]; int protocol; char protocol_r_[PADR_(int)]; char rsv_l_[PADL_(int *)]; int * rsv; char rsv_r_[PADR_(int *)]; }; +#ifndef __rtems__ struct mkdir_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)]; diff --git a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h index 18b7016b..08dd2c01 100644 --- a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h +++ b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h @@ -98,6 +98,8 @@ int shutdown(int, int); int socket(int, int, int); +int socketpair(int, int, int, int *); + int sysctl(const int *, u_int, void *, size_t *, const void *, size_t); int sysctlbyname(const char *, void *, size_t *, const void *, size_t); diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c index e11c8334..19763236 100644 --- a/testsuite/syscalls01/test_main.c +++ b/testsuite/syscalls01/test_main.c @@ -1359,6 +1359,53 @@ test_socket_poll(void) assert(rtems_resource_snapshot_check(&snapshot)); } +static void +no_mem_socket_pair(int fd) +{ + int sd[2]; + int rv; + + errno = 0; + rv = socketpair(PF_UNIX, SOCK_DGRAM, 0, &sd[0]); + assert(rv == -1); + assert(errno == ENOMEM); +} + +static void +test_socket_pair(void) +{ + rtems_resource_snapshot snapshot; + int sd[2]; + int rv; + char in[] = { 'x' }; + char out[] = { 'o' }; + ssize_t n; + + puts("test socket pair"); + + rtems_resource_snapshot_take(&snapshot); + + rv = socketpair(PF_UNIX, SOCK_DGRAM, 0, &sd[0]); + assert(rv == 0); + + n = write(sd[0], &out[0], sizeof(out)); + assert(n == (ssize_t)sizeof(out)); + + n = read(sd[1], &in[0], sizeof(in)); + assert(n == (ssize_t)sizeof(in)); + + assert(memcmp(&in[0], &out[0], sizeof(in)) == 0); + + rv = close(sd[0]); + assert(rv == 0); + + rv = close(sd[1]); + assert(rv == 0); + + do_no_mem_test(no_mem_socket_pair, -1); + + assert(rtems_resource_snapshot_check(&snapshot)); +} static void test_kqueue_unsupported_ops(void) @@ -1754,6 +1801,7 @@ test_main(void) test_socket_recv_and_recvfrom_and_recvmsg(); test_socket_select(); test_socket_poll(); + test_socket_pair(); test_kqueue_unsupported_ops(); test_kqueue_fstat(); -- cgit v1.2.3