mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-23 23:47:16 +08:00
Use socket read() and write() from FreeBSD
This commit is contained in:
parent
8989c110f5
commit
ec702abace
@ -71,8 +71,10 @@ struct fileops socketops = {
|
|||||||
};
|
};
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
#ifndef __rtems__
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
|
#ifdef __rtems__
|
||||||
|
static
|
||||||
|
#endif /* __rtems__ */
|
||||||
int
|
int
|
||||||
soo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
|
soo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
|
||||||
int flags, struct thread *td)
|
int flags, struct thread *td)
|
||||||
@ -90,8 +92,45 @@ soo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
|
|||||||
CURVNET_RESTORE();
|
CURVNET_RESTORE();
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static ssize_t
|
||||||
|
rtems_bsd_soo_read(rtems_libio_t *iop, void *buffer, size_t count)
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
||||||
|
struct iovec iov = {
|
||||||
|
.iov_base = buffer,
|
||||||
|
.iov_len = count
|
||||||
|
};
|
||||||
|
struct uio auio = {
|
||||||
|
.uio_iov = &iov,
|
||||||
|
.uio_iovcnt = 1,
|
||||||
|
.uio_offset = 0,
|
||||||
|
.uio_resid = count,
|
||||||
|
.uio_segflg = UIO_USERSPACE,
|
||||||
|
.uio_rw = UIO_READ,
|
||||||
|
.uio_td = td
|
||||||
|
};
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
error = soo_read(fp, &auio, NULL, 0, NULL);
|
||||||
|
} else {
|
||||||
|
error = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == 0) {
|
||||||
|
return (count - auio.uio_resid);
|
||||||
|
} else {
|
||||||
|
rtems_set_errno_and_return_minus_one(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
|
#ifdef __rtems__
|
||||||
|
static
|
||||||
|
#endif /* __rtems__ */
|
||||||
int
|
int
|
||||||
soo_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
|
soo_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
|
||||||
int flags, struct thread *td)
|
int flags, struct thread *td)
|
||||||
@ -106,13 +145,52 @@ soo_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
|
|||||||
#endif
|
#endif
|
||||||
error = sosend(so, 0, uio, 0, 0, 0, uio->uio_td);
|
error = sosend(so, 0, uio, 0, 0, 0, uio->uio_td);
|
||||||
if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) {
|
if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) {
|
||||||
|
#ifndef __rtems__
|
||||||
PROC_LOCK(uio->uio_td->td_proc);
|
PROC_LOCK(uio->uio_td->td_proc);
|
||||||
tdksignal(uio->uio_td, SIGPIPE, NULL);
|
tdksignal(uio->uio_td, SIGPIPE, NULL);
|
||||||
PROC_UNLOCK(uio->uio_td->td_proc);
|
PROC_UNLOCK(uio->uio_td->td_proc);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
/* FIXME: Determine if we really want to use signals */
|
||||||
|
#endif /* __rtems__ */
|
||||||
}
|
}
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static ssize_t
|
||||||
|
rtems_bsd_soo_write(rtems_libio_t *iop, const void *buffer, size_t count)
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
||||||
|
struct iovec iov = {
|
||||||
|
.iov_base = __DECONST(void *, buffer),
|
||||||
|
.iov_len = count
|
||||||
|
};
|
||||||
|
struct uio auio = {
|
||||||
|
.uio_iov = &iov,
|
||||||
|
.uio_iovcnt = 1,
|
||||||
|
.uio_offset = 0,
|
||||||
|
.uio_resid = count,
|
||||||
|
.uio_segflg = UIO_USERSPACE,
|
||||||
|
.uio_rw = UIO_WRITE,
|
||||||
|
.uio_td = td
|
||||||
|
};
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
error = soo_write(fp, &auio, NULL, 0, NULL);
|
||||||
|
} else {
|
||||||
|
error = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == 0) {
|
||||||
|
return (count - auio.uio_resid);
|
||||||
|
} else {
|
||||||
|
rtems_set_errno_and_return_minus_one(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
int
|
int
|
||||||
soo_truncate(struct file *fp, off_t length, struct ucred *active_cred,
|
soo_truncate(struct file *fp, off_t length, struct ucred *active_cred,
|
||||||
struct thread *td)
|
struct thread *td)
|
||||||
@ -132,10 +210,6 @@ soo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred,
|
|||||||
struct socket *so = fp->f_data;
|
struct socket *so = fp->f_data;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
#ifdef __rtems__
|
|
||||||
if (td == NULL)
|
|
||||||
return (ENOMEM);
|
|
||||||
#endif /* __rtems__ */
|
|
||||||
CURVNET_SET(so->so_vnet);
|
CURVNET_SET(so->so_vnet);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case FIONBIO:
|
case FIONBIO:
|
||||||
@ -239,7 +313,13 @@ rtems_bsd_soo_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer)
|
|||||||
{
|
{
|
||||||
struct thread *td = rtems_bsd_get_curthread_or_null();
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
||||||
int error = soo_ioctl(fp, request, buffer, NULL, td);
|
int error;
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
error = soo_ioctl(fp, request, buffer, NULL, td);
|
||||||
|
} else {
|
||||||
|
error = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
return rtems_bsd_error_to_status_and_errno(error);
|
return rtems_bsd_error_to_status_and_errno(error);
|
||||||
}
|
}
|
||||||
@ -363,8 +443,8 @@ rtems_bsd_soo_close(rtems_libio_t *iop)
|
|||||||
const rtems_filesystem_file_handlers_r socketops = {
|
const rtems_filesystem_file_handlers_r socketops = {
|
||||||
.open_h = rtems_filesystem_default_open,
|
.open_h = rtems_filesystem_default_open,
|
||||||
.close_h = rtems_bsd_soo_close,
|
.close_h = rtems_bsd_soo_close,
|
||||||
.read_h = rtems_filesystem_default_read,
|
.read_h = rtems_bsd_soo_read,
|
||||||
.write_h = rtems_filesystem_default_write,
|
.write_h = rtems_bsd_soo_write,
|
||||||
.ioctl_h = rtems_bsd_soo_ioctl,
|
.ioctl_h = rtems_bsd_soo_ioctl,
|
||||||
.lseek_h = rtems_filesystem_default_lseek,
|
.lseek_h = rtems_filesystem_default_lseek,
|
||||||
.fstat_h = rtems_bsd_soo_stat,
|
.fstat_h = rtems_bsd_soo_stat,
|
||||||
|
@ -618,127 +618,3 @@ done2:
|
|||||||
errno = error;
|
errno = error;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
************************************************************************
|
|
||||||
* RTEMS I/O HANDLER ROUTINES *
|
|
||||||
************************************************************************
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
rtems_bsdnet_close (rtems_libio_t *iop)
|
|
||||||
{
|
|
||||||
struct socket *so;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
if ((so = iop->data1) == NULL) {
|
|
||||||
errno = EBADF;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
error = soclose (so);
|
|
||||||
if (error) {
|
|
||||||
errno = error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, size_t count)
|
|
||||||
{
|
|
||||||
return recv (iop->data0, buffer, count, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, size_t count)
|
|
||||||
{
|
|
||||||
return send (iop->data0, buffer, count, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
so_ioctl (rtems_libio_t *iop, struct socket *so, uint32_t command, void *buffer)
|
|
||||||
{
|
|
||||||
switch (command) {
|
|
||||||
case FIONBIO:
|
|
||||||
SOCK_LOCK(so);
|
|
||||||
if (*(int *)buffer) {
|
|
||||||
iop->flags |= O_NONBLOCK;
|
|
||||||
so->so_state |= SS_NBIO;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
iop->flags &= ~O_NONBLOCK;
|
|
||||||
so->so_state &= ~SS_NBIO;
|
|
||||||
}
|
|
||||||
SOCK_UNLOCK(so);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case FIONREAD:
|
|
||||||
*(int *)buffer = so->so_rcv.sb_cc;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IOCGROUP(command) == 'i')
|
|
||||||
return ifioctl (so, command, buffer, NULL);
|
|
||||||
if (IOCGROUP(command) == 'r')
|
|
||||||
return rtioctl (command, buffer, NULL);
|
|
||||||
return (*so->so_proto->pr_usrreqs->pru_control)(so, command, buffer, 0, curthread);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rtems_bsdnet_ioctl (rtems_libio_t *iop, uint32_t command, void *buffer)
|
|
||||||
{
|
|
||||||
struct socket *so;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
if ((so = iop->data1) == NULL) {
|
|
||||||
errno = EBADF;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
error = so_ioctl (iop, so, command, buffer);
|
|
||||||
if (error) {
|
|
||||||
errno = error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rtems_bsdnet_fcntl (int cmd, rtems_libio_t *iop)
|
|
||||||
{
|
|
||||||
struct socket *so;
|
|
||||||
|
|
||||||
if (cmd == F_SETFL) {
|
|
||||||
if ((so = iop->data1) == NULL) {
|
|
||||||
return EBADF;
|
|
||||||
}
|
|
||||||
SOCK_LOCK(so);
|
|
||||||
if (iop->flags & LIBIO_FLAGS_NO_DELAY)
|
|
||||||
so->so_state |= SS_NBIO;
|
|
||||||
else
|
|
||||||
so->so_state &= ~SS_NBIO;
|
|
||||||
SOCK_UNLOCK(so);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
|
||||||
{
|
|
||||||
sp->st_mode = S_IFSOCK;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const rtems_filesystem_file_handlers_r socket_handlers = {
|
|
||||||
rtems_filesystem_default_open, /* open */
|
|
||||||
rtems_bsdnet_close, /* close */
|
|
||||||
rtems_bsdnet_read, /* read */
|
|
||||||
rtems_bsdnet_write, /* write */
|
|
||||||
rtems_bsdnet_ioctl, /* ioctl */
|
|
||||||
rtems_filesystem_default_lseek, /* lseek */
|
|
||||||
rtems_bsdnet_fstat, /* fstat */
|
|
||||||
rtems_filesystem_default_fchmod, /* fchmod */
|
|
||||||
rtems_filesystem_default_ftruncate, /* ftruncate */
|
|
||||||
rtems_filesystem_default_fsync_or_fdatasync, /* fsync */
|
|
||||||
rtems_filesystem_default_fsync_or_fdatasync, /* fdatasync */
|
|
||||||
rtems_bsdnet_fcntl, /* fcntl */
|
|
||||||
rtems_filesystem_default_rmnod /* rmnod */
|
|
||||||
};
|
|
||||||
|
@ -931,6 +931,71 @@ test_socket_getsockname(void)
|
|||||||
assert(rtems_resource_snapshot_check(&snapshot));
|
assert(rtems_resource_snapshot_check(&snapshot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
no_mem_socket_read_and_write(int fd)
|
||||||
|
{
|
||||||
|
ssize_t n;
|
||||||
|
char buf[1];
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = read(fd, &buf[0], sizeof(buf));
|
||||||
|
assert(n == -1);
|
||||||
|
assert(errno == ENOMEM);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = write(fd, &buf[0], sizeof(buf));
|
||||||
|
assert(n == -1);
|
||||||
|
assert(errno == ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_socket_read_and_write(void)
|
||||||
|
{
|
||||||
|
rtems_resource_snapshot snapshot;
|
||||||
|
int sd;
|
||||||
|
int rv;
|
||||||
|
ssize_t n;
|
||||||
|
char buf[1];
|
||||||
|
int enable = 1;
|
||||||
|
|
||||||
|
puts("test socket read and write");
|
||||||
|
|
||||||
|
rtems_resource_snapshot_take(&snapshot);
|
||||||
|
|
||||||
|
sd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
assert(sd >= 0);
|
||||||
|
|
||||||
|
rv = ioctl(sd, FIONBIO, &enable);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
do_no_mem_test(no_mem_socket_read_and_write, sd);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = read(sd, &buf[0], sizeof(buf));
|
||||||
|
assert(n == -1);
|
||||||
|
assert(errno == EAGAIN);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = write(sd, &buf[0], sizeof(buf));
|
||||||
|
assert(n == -1);
|
||||||
|
assert(errno == EDESTADDRREQ);
|
||||||
|
|
||||||
|
rv = close(sd);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = read(sd, &buf[0], sizeof(buf));
|
||||||
|
assert(n == -1);
|
||||||
|
assert(errno == EBADF);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = write(sd, &buf[0], sizeof(buf));
|
||||||
|
assert(n == -1);
|
||||||
|
assert(errno == EBADF);
|
||||||
|
|
||||||
|
assert(rtems_resource_snapshot_check(&snapshot));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_main(void)
|
test_main(void)
|
||||||
{
|
{
|
||||||
@ -947,6 +1012,7 @@ test_main(void)
|
|||||||
test_socket_getsockopt_and_setsockopt();
|
test_socket_getsockopt_and_setsockopt();
|
||||||
test_socket_getpeername();
|
test_socket_getpeername();
|
||||||
test_socket_getsockname();
|
test_socket_getsockname();
|
||||||
|
test_socket_read_and_write();
|
||||||
|
|
||||||
puts("*** END OF " TEST_NAME " TEST ***");
|
puts("*** END OF " TEST_NAME " TEST ***");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user