diff --git a/Makefile b/Makefile index 828d51e9..2d7d113f 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,6 @@ LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-timesupport.c LIB_C_FILES += rtemsbsd/rtems/rtems-kvm.c LIB_C_FILES += rtemsbsd/rtems/rtems-net-setup.c LIB_C_FILES += rtemsbsd/rtems/rtems-syslog-initialize.c -LIB_C_FILES += rtemsbsd/rtems/rtems-syspoll.c LIB_C_FILES += rtemsbsd/rtems/rtems-uthread_kevent.c LIB_C_FILES += rtemsbsd/rtems/rtems-uthread_kqueue.c LIB_C_FILES += rtemsbsd/rtems/syslog.c diff --git a/freebsd-to-rtems.py b/freebsd-to-rtems.py index bce2c7c0..ebb1c1e9 100755 --- a/freebsd-to-rtems.py +++ b/freebsd-to-rtems.py @@ -646,7 +646,6 @@ rtems.addRTEMSSourceFiles( 'rtems/rtems-kvm.c', 'rtems/rtems-net-setup.c', 'rtems/rtems-syslog-initialize.c', - 'rtems/rtems-syspoll.c', 'rtems/rtems-uthread_kevent.c', 'rtems/rtems-uthread_kqueue.c', 'rtems/syslog.c', diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c index b7185d5b..b0201d68 100644 --- a/freebsd/sys/kern/sys_generic.c +++ b/freebsd/sys/kern/sys_generic.c @@ -86,12 +86,10 @@ static MALLOC_DEFINE(M_SELECT, "select", "select() buffer"); MALLOC_DEFINE(M_IOV, "iov", "large iov's"); #endif /* __rtems__ */ -#ifndef __rtems__ static int pollout(struct thread *, struct pollfd *, struct pollfd *, u_int); static int pollscan(struct thread *, struct pollfd *, u_int); static int pollrescan(struct thread *); -#endif /* __rtems__ */ static int selscan(struct thread *, fd_mask **, fd_mask **, int); static int selrescan(struct thread *, fd_mask **, fd_mask **); static void selfdalloc(struct thread *, void *); @@ -1186,7 +1184,6 @@ selscan(td, ibits, obits, nfd) return (0); } -#ifndef __rtems__ #ifndef _SYS_SYSPROTO_H_ struct poll_args { struct pollfd *fds; @@ -1194,8 +1191,13 @@ struct poll_args { int timeout; }; #endif +#ifndef __rtems__ int poll(td, uap) +#else /* __rtems__ */ +static int +rtems_bsd_poll(td, uap) +#endif /* __rtems__ */ struct thread *td; struct poll_args *uap; { @@ -1207,7 +1209,11 @@ poll(td, uap) size_t ni; nfds = uap->nfds; +#ifndef __rtems__ if (nfds > maxfilesperproc && nfds > FD_SETSIZE) +#else /* __rtems__ */ + if (nfds > rtems_libio_number_iops) +#endif /* __rtems__ */ return (EINVAL); ni = nfds * sizeof(struct pollfd); if (ni > sizeof(smallbits)) @@ -1271,6 +1277,31 @@ out: free(bits, M_TEMP); return (error); } +#ifdef __rtems__ +int +poll(struct pollfd fds[], nfds_t nfds, int timeout) +{ + struct thread *td = rtems_bsd_get_curthread_or_null(); + struct poll_args ua = { + .fds = &fds[0], + .nfds = nfds, + .timeout = timeout + }; + int error; + + if (td != NULL) { + error = rtems_bsd_poll(td, &ua); + } else { + error = ENOMEM; + } + + if (error == 0) { + return td->td_retval[0]; + } else { + rtems_set_errno_and_return_minus_one(error); + } +} +#endif /* __rtems__ */ static int pollrescan(struct thread *td) @@ -1285,7 +1316,11 @@ pollrescan(struct thread *td) int n; n = 0; +#ifndef __rtems__ fdp = td->td_proc->p_fd; +#else /* __rtems__ */ + fdp = NULL; +#endif /* __rtems__ */ stp = td->td_sel; FILEDESC_SLOCK(fdp); STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) { @@ -1295,7 +1330,11 @@ pollrescan(struct thread *td) /* If the selinfo wasn't cleared the event didn't fire. */ if (si != NULL) continue; +#ifndef __rtems__ fp = fdp->fd_ofiles[fd->fd]; +#else /* __rtems__ */ + fp = fget_unlocked(fdp, fd->fd); +#endif /* __rtems__ */ if (fp == NULL) { fd->revents = POLLNVAL; n++; @@ -1347,20 +1386,32 @@ pollscan(td, fds, nfd) struct pollfd *fds; u_int nfd; { +#ifndef __rtems__ struct filedesc *fdp = td->td_proc->p_fd; +#else /* __rtems__ */ + struct filedesc *fdp = NULL; +#endif /* __rtems__ */ int i; struct file *fp; int n = 0; FILEDESC_SLOCK(fdp); for (i = 0; i < nfd; i++, fds++) { +#ifndef __rtems__ if (fds->fd >= fdp->fd_nfiles) { +#else /* __rtems__ */ + if (fds->fd >= rtems_libio_number_iops) { +#endif /* __rtems__ */ fds->revents = POLLNVAL; n++; } else if (fds->fd < 0) { fds->revents = 0; } else { +#ifndef __rtems__ fp = fdp->fd_ofiles[fds->fd]; +#else /* __rtems__ */ + fp = fget_unlocked(fdp, fds->fd); +#endif /* __rtems__ */ if (fp == NULL) { fds->revents = POLLNVAL; n++; @@ -1389,6 +1440,7 @@ pollscan(td, fds, nfd) return (0); } +#ifndef __rtems__ /* * OpenBSD poll system call. * diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index 548bb337..c8e8d636 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -682,11 +682,13 @@ struct futimes_args { struct getpgid_args { char pid_l_[PADL_(pid_t)]; pid_t pid; char pid_r_[PADR_(pid_t)]; }; +#endif /* __rtems__ */ struct poll_args { char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)]; char nfds_l_[PADL_(u_int)]; u_int nfds; char nfds_r_[PADR_(u_int)]; char timeout_l_[PADL_(int)]; int timeout; char timeout_r_[PADR_(int)]; }; +#ifndef __rtems__ struct semget_args { char key_l_[PADL_(key_t)]; key_t key; char key_r_[PADR_(key_t)]; char nsems_l_[PADL_(int)]; int nsems; char nsems_r_[PADR_(int)]; diff --git a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h index d96f1793..f3031a25 100644 --- a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h +++ b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h @@ -45,6 +45,7 @@ #define _RTEMS_BSD_MACHINE_RTEMS_BSD_SYSCALL_API_H_ #include +#include #include #include #include @@ -70,6 +71,8 @@ int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict); int listen(int, int); +int poll(struct pollfd _pfd[], nfds_t _nfds, int _timeout); + ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict); ssize_t recvmsg(int, struct msghdr *, int); diff --git a/rtemsbsd/rtems/rtems-syspoll.c b/rtemsbsd/rtems/rtems-syspoll.c deleted file mode 100644 index 33e05006..00000000 --- a/rtemsbsd/rtems/rtems-syspoll.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include -#include -#include - -struct poll_args { - struct pollfd *fds; - u_int nfds; - int timeout; -}; - -int kern_poll( struct thread *td, struct poll_args *uap ); - - -int -__sys_poll(struct pollfd *fds, unsigned nfds, int timeout) -{ - struct poll_args uap; - struct thread *td = rtems_get_curthread(); - - uap.fds = fds; - uap.nfds = nfds; - uap.timeout = timeout; - - kern_poll(td, &uap); - - return -1; -} diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c index 7e4db14a..6c0f257e 100644 --- a/testsuite/syscalls01/test_main.c +++ b/testsuite/syscalls01/test_main.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include #include +#include #include #include #include @@ -1280,6 +1282,78 @@ test_socket_select(void) assert(rtems_resource_snapshot_check(&snapshot)); } +static void +no_mem_socket_poll(int fd) +{ + struct pollfd pfd; + int timeout = -1; + int rv; + + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + + errno = 0; + rv = poll(&pfd, 1, timeout); + assert(rv == -1); + assert(errno == ENOMEM); +} + +static void +test_socket_poll(void) +{ + rtems_resource_snapshot snapshot; + struct pollfd pfd; + int timeout = -1; + int sd; + int rv; + + puts("test socket poll"); + + sd = socket(PF_INET, SOCK_DGRAM, 0); + assert(sd >= 0); + + rv = close(sd); + assert(rv == 0); + + pfd.fd = sd; + pfd.events = POLLIN; + pfd.revents = 0; + + rv = poll(&pfd, 1, timeout); + assert(rv == 1); + assert(pfd.revents == POLLNVAL); + + rtems_resource_snapshot_take(&snapshot); + + sd = socket(PF_INET, SOCK_DGRAM, 0); + assert(sd >= 0); + + do_no_mem_test(no_mem_socket_poll, sd); + + pfd.fd = sd; + pfd.events = POLLIN; + pfd.revents = 0; + + errno = 0; + rv = poll(NULL, UINT_MAX, timeout); + assert(rv == -1); + assert(errno == EINVAL); + + rv = close(sd); + assert(rv == 0); + + pfd.fd = sd; + pfd.events = POLLIN; + pfd.revents = 0; + + rv = poll(&pfd, 1, timeout); + assert(rv == 1); + assert(pfd.revents == POLLNVAL); + + assert(rtems_resource_snapshot_check(&snapshot)); +} + static const char prog_name[] = "prog"; static int @@ -1487,6 +1561,7 @@ test_main(void) test_socket_send_and_sendto_and_sendmsg(); test_socket_recv_and_recvfrom_and_recvmsg(); test_socket_select(); + test_socket_poll(); test_bsd_program(); test_warn();