mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-23 23:47:16 +08:00
Use select() from FreeBSD
This commit is contained in:
parent
0967858024
commit
facf9dcea6
@ -94,9 +94,7 @@ static int pollrescan(struct thread *);
|
|||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
static int selscan(struct thread *, fd_mask **, fd_mask **, int);
|
static int selscan(struct thread *, fd_mask **, fd_mask **, int);
|
||||||
static int selrescan(struct thread *, fd_mask **, fd_mask **);
|
static int selrescan(struct thread *, fd_mask **, fd_mask **);
|
||||||
#ifndef __rtems__
|
|
||||||
static void selfdalloc(struct thread *, void *);
|
static void selfdalloc(struct thread *, void *);
|
||||||
#endif /* __rtems__ */
|
|
||||||
static void selfdfree(struct seltd *, struct selfd *);
|
static void selfdfree(struct seltd *, struct selfd *);
|
||||||
#ifndef __rtems__
|
#ifndef __rtems__
|
||||||
static int dofileread(struct thread *, int, struct file *, struct uio *,
|
static int dofileread(struct thread *, int, struct file *, struct uio *,
|
||||||
@ -851,9 +849,7 @@ int
|
|||||||
kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
|
kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
|
||||||
fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits)
|
fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits)
|
||||||
{
|
{
|
||||||
#ifndef __rtems__
|
|
||||||
struct filedesc *fdp;
|
struct filedesc *fdp;
|
||||||
#endif /* __rtems__ */
|
|
||||||
/*
|
/*
|
||||||
* The magic 2048 here is chosen to be just enough for FD_SETSIZE
|
* The magic 2048 here is chosen to be just enough for FD_SETSIZE
|
||||||
* infds with the new FD_SETSIZE of 1024, and more than enough for
|
* infds with the new FD_SETSIZE of 1024, and more than enough for
|
||||||
@ -866,10 +862,6 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
|
|||||||
int error, timo;
|
int error, timo;
|
||||||
u_int nbufbytes, ncpbytes, ncpubytes, nfdbits;
|
u_int nbufbytes, ncpbytes, ncpubytes, nfdbits;
|
||||||
|
|
||||||
#ifdef __rtems__
|
|
||||||
if (td == NULL)
|
|
||||||
return (ENOMEM);
|
|
||||||
#endif /* __rtems__ */
|
|
||||||
if (nd < 0)
|
if (nd < 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
#ifndef __rtems__
|
#ifndef __rtems__
|
||||||
@ -877,6 +869,7 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
|
|||||||
if (nd > fdp->fd_lastfile + 1)
|
if (nd > fdp->fd_lastfile + 1)
|
||||||
nd = fdp->fd_lastfile + 1;
|
nd = fdp->fd_lastfile + 1;
|
||||||
#else /* __rtems__ */
|
#else /* __rtems__ */
|
||||||
|
(void) fdp;
|
||||||
if (nd > rtems_libio_number_iops)
|
if (nd > rtems_libio_number_iops)
|
||||||
nd = rtems_libio_number_iops;
|
nd = rtems_libio_number_iops;
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
@ -1019,12 +1012,18 @@ done:
|
|||||||
}
|
}
|
||||||
#ifdef __rtems__
|
#ifdef __rtems__
|
||||||
int
|
int
|
||||||
select(int nfds, fd_set *restrict readfds, fd_set *__restrict writefds, fd_set
|
select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,
|
||||||
*__restrict errorfds, struct timeval *__restrict timeout)
|
struct timeval *timeout)
|
||||||
{
|
{
|
||||||
struct thread *td = rtems_bsd_get_curthread_or_null();
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
int error = kern_select(td, nfds, readfds, writefds, errorfds, timeout,
|
int error;
|
||||||
NFDBITS);
|
|
||||||
|
if (td != NULL) {
|
||||||
|
error = kern_select(td, nfds, readfds, writefds, errorfds,
|
||||||
|
timeout, NFDBITS);
|
||||||
|
} else {
|
||||||
|
error = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
return td->td_retval[0];
|
return td->td_retval[0];
|
||||||
@ -1033,7 +1032,7 @@ select(int nfds, fd_set *restrict readfds, fd_set *__restrict writefds, fd_set
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
#ifndef __rtems__
|
|
||||||
/*
|
/*
|
||||||
* Convert a select bit set to poll flags.
|
* Convert a select bit set to poll flags.
|
||||||
*
|
*
|
||||||
@ -1099,7 +1098,6 @@ selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events)
|
|||||||
|
|
||||||
return (n);
|
return (n);
|
||||||
}
|
}
|
||||||
#endif /* __rtems__ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Traverse the list of fds attached to this thread's seltd and check for
|
* Traverse the list of fds attached to this thread's seltd and check for
|
||||||
@ -1108,7 +1106,6 @@ selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events)
|
|||||||
static int
|
static int
|
||||||
selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
|
selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
|
||||||
{
|
{
|
||||||
#ifndef __rtems__
|
|
||||||
struct filedesc *fdp;
|
struct filedesc *fdp;
|
||||||
struct selinfo *si;
|
struct selinfo *si;
|
||||||
struct seltd *stp;
|
struct seltd *stp;
|
||||||
@ -1118,7 +1115,11 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
|
|||||||
fd_mask bit;
|
fd_mask bit;
|
||||||
int fd, ev, n, idx;
|
int fd, ev, n, idx;
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
fdp = td->td_proc->p_fd;
|
fdp = td->td_proc->p_fd;
|
||||||
|
#else /* __rtems__ */
|
||||||
|
fdp = NULL;
|
||||||
|
#endif /* __rtems__ */
|
||||||
stp = td->td_sel;
|
stp = td->td_sel;
|
||||||
n = 0;
|
n = 0;
|
||||||
STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) {
|
STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) {
|
||||||
@ -1140,9 +1141,6 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
|
|||||||
stp->st_flags = 0;
|
stp->st_flags = 0;
|
||||||
td->td_retval[0] = n;
|
td->td_retval[0] = n;
|
||||||
return (0);
|
return (0);
|
||||||
#else /* __rtems__ */
|
|
||||||
return (ENOMEM);
|
|
||||||
#endif /* __rtems__ */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1155,14 +1153,17 @@ selscan(td, ibits, obits, nfd)
|
|||||||
fd_mask **ibits, **obits;
|
fd_mask **ibits, **obits;
|
||||||
int nfd;
|
int nfd;
|
||||||
{
|
{
|
||||||
#ifndef __rtems__
|
|
||||||
struct filedesc *fdp;
|
struct filedesc *fdp;
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
fd_mask bit;
|
fd_mask bit;
|
||||||
int ev, flags, end, fd;
|
int ev, flags, end, fd;
|
||||||
int n, idx;
|
int n, idx;
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
fdp = td->td_proc->p_fd;
|
fdp = td->td_proc->p_fd;
|
||||||
|
#else /* __rtems__ */
|
||||||
|
fdp = NULL;
|
||||||
|
#endif /* __rtems__ */
|
||||||
n = 0;
|
n = 0;
|
||||||
for (idx = 0, fd = 0; fd < nfd; idx++) {
|
for (idx = 0, fd = 0; fd < nfd; idx++) {
|
||||||
end = imin(fd + NFDBITS, nfd);
|
end = imin(fd + NFDBITS, nfd);
|
||||||
@ -1183,9 +1184,6 @@ selscan(td, ibits, obits, nfd)
|
|||||||
|
|
||||||
td->td_retval[0] = n;
|
td->td_retval[0] = n;
|
||||||
return (0);
|
return (0);
|
||||||
#else /* __rtems__ */
|
|
||||||
return (ENOMEM);
|
|
||||||
#endif /* __rtems__ */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __rtems__
|
#ifndef __rtems__
|
||||||
@ -1466,6 +1464,7 @@ selsocket(struct socket *so, int events, struct timeval *tvp, struct thread *td)
|
|||||||
error = 0;
|
error = 0;
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Preallocate two selfds associated with 'cookie'. Some fo_poll routines
|
* Preallocate two selfds associated with 'cookie'. Some fo_poll routines
|
||||||
@ -1486,7 +1485,6 @@ selfdalloc(struct thread *td, void *cookie)
|
|||||||
stp->st_free2->sf_td = stp;
|
stp->st_free2->sf_td = stp;
|
||||||
stp->st_free2->sf_cookie = cookie;
|
stp->st_free2->sf_cookie = cookie;
|
||||||
}
|
}
|
||||||
#endif /* __rtems__ */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
selfdfree(struct seltd *stp, struct selfd *sfp)
|
selfdfree(struct seltd *stp, struct selfd *sfp)
|
||||||
|
@ -325,7 +325,9 @@ rtems_bsd_soo_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer)
|
|||||||
}
|
}
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
#ifndef __rtems__
|
#ifdef __rtems__
|
||||||
|
static
|
||||||
|
#endif /* __rtems__ */
|
||||||
int
|
int
|
||||||
soo_poll(struct file *fp, int events, struct ucred *active_cred,
|
soo_poll(struct file *fp, int events, struct ucred *active_cred,
|
||||||
struct thread *td)
|
struct thread *td)
|
||||||
@ -338,7 +340,27 @@ soo_poll(struct file *fp, int events, struct ucred *active_cred,
|
|||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef __rtems__
|
||||||
return (sopoll(so, events, fp->f_cred, td));
|
return (sopoll(so, events, fp->f_cred, td));
|
||||||
|
#else /* __rtems__ */
|
||||||
|
return (sopoll(so, events, NULL, td));
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static int
|
||||||
|
rtems_bsd_soo_poll(rtems_libio_t *iop, int events)
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
error = soo_poll(fp, events, NULL, td);
|
||||||
|
} else {
|
||||||
|
error = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
@ -451,6 +473,7 @@ const rtems_filesystem_file_handlers_r socketops = {
|
|||||||
.ftruncate_h = rtems_filesystem_default_ftruncate,
|
.ftruncate_h = rtems_filesystem_default_ftruncate,
|
||||||
.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
|
.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
|
||||||
.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
|
.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
|
||||||
.fcntl_h = rtems_filesystem_default_fcntl
|
.fcntl_h = rtems_filesystem_default_fcntl,
|
||||||
|
.poll_h = rtems_bsd_soo_poll
|
||||||
};
|
};
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
|
@ -408,7 +408,6 @@ fo_ioctl(fp, com, data, active_cred, td)
|
|||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __rtems__
|
|
||||||
static __inline int
|
static __inline int
|
||||||
fo_poll(fp, events, active_cred, td)
|
fo_poll(fp, events, active_cred, td)
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
@ -417,9 +416,17 @@ fo_poll(fp, events, active_cred, td)
|
|||||||
struct thread *td;
|
struct thread *td;
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
return ((*fp->f_ops->fo_poll)(fp, events, active_cred, td));
|
return ((*fp->f_ops->fo_poll)(fp, events, active_cred, td));
|
||||||
|
#else /* __rtems__ */
|
||||||
|
(void) active_cred;
|
||||||
|
(void) td;
|
||||||
|
|
||||||
|
return ((*fp->f_io.pathinfo.handlers->poll_h)(&fp->f_io, events));
|
||||||
|
#endif /* __rtems__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
static __inline int
|
static __inline int
|
||||||
fo_stat(fp, sb, active_cred, td)
|
fo_stat(fp, sb, active_cred, td)
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -1206,6 +1207,79 @@ test_socket_recv_and_recvfrom_and_recvmsg(void)
|
|||||||
assert(rtems_resource_snapshot_check(&snapshot));
|
assert(rtems_resource_snapshot_check(&snapshot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
no_mem_socket_select(int fd)
|
||||||
|
{
|
||||||
|
struct fd_set set;
|
||||||
|
int nfds;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
FD_ZERO(&set);
|
||||||
|
FD_SET(fd, &set);
|
||||||
|
nfds = fd + 1;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
rv = select(nfds, &set, NULL, NULL, NULL);
|
||||||
|
assert(rv == -1);
|
||||||
|
assert(errno == ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_socket_select(void)
|
||||||
|
{
|
||||||
|
rtems_resource_snapshot snapshot;
|
||||||
|
struct fd_set set;
|
||||||
|
int nfds;
|
||||||
|
int sd;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
puts("test socket select");
|
||||||
|
|
||||||
|
sd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
assert(sd >= 0);
|
||||||
|
|
||||||
|
rv = close(sd);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
FD_ZERO(&set);
|
||||||
|
FD_SET(sd, &set);
|
||||||
|
nfds = sd + 1;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
rv = select(nfds, &set, NULL, NULL, NULL);
|
||||||
|
assert(rv == -1);
|
||||||
|
assert(errno == EBADF);
|
||||||
|
|
||||||
|
rtems_resource_snapshot_take(&snapshot);
|
||||||
|
|
||||||
|
sd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
assert(sd >= 0);
|
||||||
|
|
||||||
|
do_no_mem_test(no_mem_socket_select, sd);
|
||||||
|
|
||||||
|
FD_ZERO(&set);
|
||||||
|
nfds = -1;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
rv = select(nfds, &set, NULL, NULL, NULL);
|
||||||
|
assert(rv == -1);
|
||||||
|
assert(errno == EINVAL);
|
||||||
|
|
||||||
|
rv = close(sd);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
FD_ZERO(&set);
|
||||||
|
FD_SET(sd, &set);
|
||||||
|
nfds = sd + 1;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
rv = select(nfds, &set, NULL, NULL, NULL);
|
||||||
|
assert(rv == -1);
|
||||||
|
assert(errno == EBADF);
|
||||||
|
|
||||||
|
assert(rtems_resource_snapshot_check(&snapshot));
|
||||||
|
}
|
||||||
|
|
||||||
static const char prog_name[] = "prog";
|
static const char prog_name[] = "prog";
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1412,6 +1486,7 @@ test_main(void)
|
|||||||
test_socket_read_and_write();
|
test_socket_read_and_write();
|
||||||
test_socket_send_and_sendto_and_sendmsg();
|
test_socket_send_and_sendto_and_sendmsg();
|
||||||
test_socket_recv_and_recvfrom_and_recvmsg();
|
test_socket_recv_and_recvfrom_and_recvmsg();
|
||||||
|
test_socket_select();
|
||||||
|
|
||||||
test_bsd_program();
|
test_bsd_program();
|
||||||
test_warn();
|
test_warn();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user