mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-22 05:07:19 +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__ */
|
||||
static int selscan(struct thread *, fd_mask **, fd_mask **, int);
|
||||
static int selrescan(struct thread *, fd_mask **, fd_mask **);
|
||||
#ifndef __rtems__
|
||||
static void selfdalloc(struct thread *, void *);
|
||||
#endif /* __rtems__ */
|
||||
static void selfdfree(struct seltd *, struct selfd *);
|
||||
#ifndef __rtems__
|
||||
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,
|
||||
fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits)
|
||||
{
|
||||
#ifndef __rtems__
|
||||
struct filedesc *fdp;
|
||||
#endif /* __rtems__ */
|
||||
/*
|
||||
* 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
|
||||
@ -866,10 +862,6 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
|
||||
int error, timo;
|
||||
u_int nbufbytes, ncpbytes, ncpubytes, nfdbits;
|
||||
|
||||
#ifdef __rtems__
|
||||
if (td == NULL)
|
||||
return (ENOMEM);
|
||||
#endif /* __rtems__ */
|
||||
if (nd < 0)
|
||||
return (EINVAL);
|
||||
#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)
|
||||
nd = fdp->fd_lastfile + 1;
|
||||
#else /* __rtems__ */
|
||||
(void) fdp;
|
||||
if (nd > rtems_libio_number_iops)
|
||||
nd = rtems_libio_number_iops;
|
||||
#endif /* __rtems__ */
|
||||
@ -1019,12 +1012,18 @@ done:
|
||||
}
|
||||
#ifdef __rtems__
|
||||
int
|
||||
select(int nfds, fd_set *restrict readfds, fd_set *__restrict writefds, fd_set
|
||||
*__restrict errorfds, struct timeval *__restrict timeout)
|
||||
select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,
|
||||
struct timeval *timeout)
|
||||
{
|
||||
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||
int error = kern_select(td, nfds, readfds, writefds, errorfds, timeout,
|
||||
NFDBITS);
|
||||
int error;
|
||||
|
||||
if (td != NULL) {
|
||||
error = kern_select(td, nfds, readfds, writefds, errorfds,
|
||||
timeout, NFDBITS);
|
||||
} else {
|
||||
error = ENOMEM;
|
||||
}
|
||||
|
||||
if (error == 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__ */
|
||||
#ifndef __rtems__
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/*
|
||||
* 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
|
||||
selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
|
||||
{
|
||||
#ifndef __rtems__
|
||||
struct filedesc *fdp;
|
||||
struct selinfo *si;
|
||||
struct seltd *stp;
|
||||
@ -1118,7 +1115,11 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
|
||||
fd_mask bit;
|
||||
int fd, ev, n, idx;
|
||||
|
||||
#ifndef __rtems__
|
||||
fdp = td->td_proc->p_fd;
|
||||
#else /* __rtems__ */
|
||||
fdp = NULL;
|
||||
#endif /* __rtems__ */
|
||||
stp = td->td_sel;
|
||||
n = 0;
|
||||
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;
|
||||
td->td_retval[0] = n;
|
||||
return (0);
|
||||
#else /* __rtems__ */
|
||||
return (ENOMEM);
|
||||
#endif /* __rtems__ */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1155,14 +1153,17 @@ selscan(td, ibits, obits, nfd)
|
||||
fd_mask **ibits, **obits;
|
||||
int nfd;
|
||||
{
|
||||
#ifndef __rtems__
|
||||
struct filedesc *fdp;
|
||||
struct file *fp;
|
||||
fd_mask bit;
|
||||
int ev, flags, end, fd;
|
||||
int n, idx;
|
||||
|
||||
#ifndef __rtems__
|
||||
fdp = td->td_proc->p_fd;
|
||||
#else /* __rtems__ */
|
||||
fdp = NULL;
|
||||
#endif /* __rtems__ */
|
||||
n = 0;
|
||||
for (idx = 0, fd = 0; fd < nfd; idx++) {
|
||||
end = imin(fd + NFDBITS, nfd);
|
||||
@ -1183,9 +1184,6 @@ selscan(td, ibits, obits, nfd)
|
||||
|
||||
td->td_retval[0] = n;
|
||||
return (0);
|
||||
#else /* __rtems__ */
|
||||
return (ENOMEM);
|
||||
#endif /* __rtems__ */
|
||||
}
|
||||
|
||||
#ifndef __rtems__
|
||||
@ -1466,6 +1464,7 @@ selsocket(struct socket *so, int events, struct timeval *tvp, struct thread *td)
|
||||
error = 0;
|
||||
return (error);
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/*
|
||||
* 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_cookie = cookie;
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
static void
|
||||
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__ */
|
||||
|
||||
#ifndef __rtems__
|
||||
#ifdef __rtems__
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
soo_poll(struct file *fp, int events, struct ucred *active_cred,
|
||||
struct thread *td)
|
||||
@ -338,7 +340,27 @@ soo_poll(struct file *fp, int events, struct ucred *active_cred,
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
#ifndef __rtems__
|
||||
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__ */
|
||||
|
||||
@ -451,6 +473,7 @@ const rtems_filesystem_file_handlers_r socketops = {
|
||||
.ftruncate_h = rtems_filesystem_default_ftruncate,
|
||||
.fsync_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__ */
|
||||
|
@ -408,7 +408,6 @@ fo_ioctl(fp, com, data, active_cred, td)
|
||||
#endif /* __rtems__ */
|
||||
}
|
||||
|
||||
#ifndef __rtems__
|
||||
static __inline int
|
||||
fo_poll(fp, events, active_cred, td)
|
||||
struct file *fp;
|
||||
@ -417,9 +416,17 @@ fo_poll(fp, events, active_cred, td)
|
||||
struct thread *td;
|
||||
{
|
||||
|
||||
#ifndef __rtems__
|
||||
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
|
||||
fo_stat(fp, sb, active_cred, td)
|
||||
struct file *fp;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/filio.h>
|
||||
#include <netinet/in.h>
|
||||
@ -1206,6 +1207,79 @@ test_socket_recv_and_recvfrom_and_recvmsg(void)
|
||||
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 int
|
||||
@ -1412,6 +1486,7 @@ test_main(void)
|
||||
test_socket_read_and_write();
|
||||
test_socket_send_and_sendto_and_sendmsg();
|
||||
test_socket_recv_and_recvfrom_and_recvmsg();
|
||||
test_socket_select();
|
||||
|
||||
test_bsd_program();
|
||||
test_warn();
|
||||
|
Loading…
x
Reference in New Issue
Block a user