mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-13 09:49:16 +08:00
PIPE(2): Port to RTEMS
This commit is contained in:
parent
6959face72
commit
b1580fb039
271
freebsd/sys/kern/sys_pipe.c
Normal file → Executable file
271
freebsd/sys/kern/sys_pipe.c
Normal file → Executable file
@ -131,6 +131,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <vm/uma.h>
|
#include <vm/uma.h>
|
||||||
|
|
||||||
/* XXX */
|
/* XXX */
|
||||||
|
#ifdef __rtems__
|
||||||
|
static
|
||||||
|
#endif /* __rtems__ */
|
||||||
int do_pipe(struct thread *td, int fildes[2], int flags);
|
int do_pipe(struct thread *td, int fildes[2], int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -143,6 +146,7 @@ int do_pipe(struct thread *td, int fildes[2], int flags);
|
|||||||
/*
|
/*
|
||||||
* interfaces to the outside world
|
* interfaces to the outside world
|
||||||
*/
|
*/
|
||||||
|
#ifndef __rtems__
|
||||||
static fo_rdwr_t pipe_read;
|
static fo_rdwr_t pipe_read;
|
||||||
static fo_rdwr_t pipe_write;
|
static fo_rdwr_t pipe_write;
|
||||||
static fo_truncate_t pipe_truncate;
|
static fo_truncate_t pipe_truncate;
|
||||||
@ -165,6 +169,39 @@ static struct fileops pipeops = {
|
|||||||
.fo_chown = invfo_chown,
|
.fo_chown = invfo_chown,
|
||||||
.fo_flags = DFLAG_PASSABLE
|
.fo_flags = DFLAG_PASSABLE
|
||||||
};
|
};
|
||||||
|
#else /* __rtems__ */
|
||||||
|
#define PIPE_NODIRECT
|
||||||
|
#define PRIBIO (0)
|
||||||
|
|
||||||
|
static int rtems_bsd_pipe_open(rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
|
||||||
|
static int rtems_bsd_pipe_close(rtems_libio_t *iop);
|
||||||
|
static ssize_t rtems_bsd_pipe_read(rtems_libio_t *iop, void *buffer, size_t count);
|
||||||
|
static ssize_t rtems_bsd_pipe_write(rtems_libio_t *iop, const void *buffer, size_t count);
|
||||||
|
static int rtems_bsd_pipe_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer);
|
||||||
|
static int rtems_bsd_pipe_stat(const rtems_filesystem_location_info_t *loc, struct stat *buf);
|
||||||
|
static int rtems_bsd_pipe_fcntl(rtems_libio_t *iop, int cmd);
|
||||||
|
static int rtems_bsd_pipe_poll(rtems_libio_t *iop, int events);
|
||||||
|
int rtems_bsd_pipe_kqfilter(rtems_libio_t *iop, struct knote *kn);
|
||||||
|
|
||||||
|
static const rtems_filesystem_file_handlers_r pipeops = {
|
||||||
|
.open_h = rtems_bsd_pipe_open,
|
||||||
|
.close_h = rtems_bsd_pipe_close,
|
||||||
|
.read_h = rtems_bsd_pipe_read,
|
||||||
|
.write_h = rtems_bsd_pipe_write,
|
||||||
|
.ioctl_h = rtems_bsd_pipe_ioctl,
|
||||||
|
.lseek_h = rtems_filesystem_default_lseek,
|
||||||
|
.fstat_h = rtems_bsd_pipe_stat,
|
||||||
|
.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_bsd_pipe_fcntl,
|
||||||
|
.poll_h = rtems_bsd_pipe_poll,
|
||||||
|
.kqfilter_h = rtems_bsd_pipe_kqfilter
|
||||||
|
};
|
||||||
|
|
||||||
|
long maxpipekva; /* Limit on pipe KVA */
|
||||||
|
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
static void filt_pipedetach(struct knote *kn);
|
static void filt_pipedetach(struct knote *kn);
|
||||||
static int filt_piperead(struct knote *kn, long hint);
|
static int filt_piperead(struct knote *kn, long hint);
|
||||||
@ -266,7 +303,11 @@ pipe_zone_ctor(void *mem, int size, void *arg, int flags)
|
|||||||
*/
|
*/
|
||||||
rpipe = &pp->pp_rpipe;
|
rpipe = &pp->pp_rpipe;
|
||||||
bzero(rpipe, sizeof(*rpipe));
|
bzero(rpipe, sizeof(*rpipe));
|
||||||
|
#ifndef __rtems__
|
||||||
vfs_timestamp(&rpipe->pipe_ctime);
|
vfs_timestamp(&rpipe->pipe_ctime);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
rpipe->pipe_ctime.tv_sec = time(NULL);
|
||||||
|
#endif /* __rtems__ */
|
||||||
rpipe->pipe_atime = rpipe->pipe_mtime = rpipe->pipe_ctime;
|
rpipe->pipe_atime = rpipe->pipe_mtime = rpipe->pipe_ctime;
|
||||||
|
|
||||||
wpipe = &pp->pp_wpipe;
|
wpipe = &pp->pp_wpipe;
|
||||||
@ -336,7 +377,11 @@ kern_pipe(struct thread *td, int fildes[2])
|
|||||||
int
|
int
|
||||||
do_pipe(struct thread *td, int fildes[2], int flags)
|
do_pipe(struct thread *td, int fildes[2], int flags)
|
||||||
{
|
{
|
||||||
|
#ifndef __rtems__
|
||||||
struct filedesc *fdp = td->td_proc->p_fd;
|
struct filedesc *fdp = td->td_proc->p_fd;
|
||||||
|
#else /* __rtems__ */
|
||||||
|
struct filedesc *fdp = NULL;
|
||||||
|
#endif /* __rtems__ */
|
||||||
struct file *rf, *wf;
|
struct file *rf, *wf;
|
||||||
struct pipepair *pp;
|
struct pipepair *pp;
|
||||||
struct pipe *rpipe, *wpipe;
|
struct pipe *rpipe, *wpipe;
|
||||||
@ -422,6 +467,28 @@ sys_pipe(struct thread *td, struct pipe_args *uap)
|
|||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
int
|
||||||
|
pipe(int fildes[2])
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
error = sys_pipe(td, NULL);
|
||||||
|
} else {
|
||||||
|
error = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == 0) {
|
||||||
|
fildes[0] = td->td_retval[0];
|
||||||
|
fildes[1] = td->td_retval[1];
|
||||||
|
return error;
|
||||||
|
} else {
|
||||||
|
rtems_set_errno_and_return_minus_one(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate kva for pipe circular buffer, the space is pageable
|
* Allocate kva for pipe circular buffer, the space is pageable
|
||||||
@ -448,12 +515,17 @@ retry:
|
|||||||
size = cnt;
|
size = cnt;
|
||||||
|
|
||||||
size = round_page(size);
|
size = round_page(size);
|
||||||
|
#ifndef __rtems__
|
||||||
buffer = (caddr_t) vm_map_min(pipe_map);
|
buffer = (caddr_t) vm_map_min(pipe_map);
|
||||||
|
|
||||||
error = vm_map_find(pipe_map, NULL, 0,
|
error = vm_map_find(pipe_map, NULL, 0,
|
||||||
(vm_offset_t *) &buffer, size, 1,
|
(vm_offset_t *) &buffer, size, 1,
|
||||||
VM_PROT_ALL, VM_PROT_ALL, 0);
|
VM_PROT_ALL, VM_PROT_ALL, 0);
|
||||||
if (error != KERN_SUCCESS) {
|
if (error != KERN_SUCCESS) {
|
||||||
|
#else /* __rtems__ */
|
||||||
|
buffer = malloc(size, M_TEMP, M_WAITOK | M_ZERO);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
#endif /* __rtems__ */
|
||||||
if ((cpipe->pipe_buffer.buffer == NULL) &&
|
if ((cpipe->pipe_buffer.buffer == NULL) &&
|
||||||
(size > SMALL_PIPE_SIZE)) {
|
(size > SMALL_PIPE_SIZE)) {
|
||||||
size = SMALL_PIPE_SIZE;
|
size = SMALL_PIPE_SIZE;
|
||||||
@ -716,7 +788,11 @@ pipe_read(fp, uio, active_cred, flags, td)
|
|||||||
* Handle non-blocking mode operation or
|
* Handle non-blocking mode operation or
|
||||||
* wait for more data.
|
* wait for more data.
|
||||||
*/
|
*/
|
||||||
|
#ifndef __rtems__
|
||||||
if (fp->f_flag & FNONBLOCK) {
|
if (fp->f_flag & FNONBLOCK) {
|
||||||
|
#else /* __rtems__ */
|
||||||
|
if (rtems_bsd_libio_flags_to_fflag(fp->f_io.flags) & FNONBLOCK) {
|
||||||
|
#endif /* __rtems__ */
|
||||||
error = EAGAIN;
|
error = EAGAIN;
|
||||||
} else {
|
} else {
|
||||||
rpipe->pipe_state |= PIPE_WANTR;
|
rpipe->pipe_state |= PIPE_WANTR;
|
||||||
@ -736,7 +812,11 @@ locked_error:
|
|||||||
|
|
||||||
/* XXX: should probably do this before getting any locks. */
|
/* XXX: should probably do this before getting any locks. */
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
|
#ifndef __rtems__
|
||||||
vfs_timestamp(&rpipe->pipe_atime);
|
vfs_timestamp(&rpipe->pipe_atime);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
rpipe->pipe_atime.tv_sec = time(NULL);
|
||||||
|
#endif /* __rtems__ */
|
||||||
unlocked_error:
|
unlocked_error:
|
||||||
--rpipe->pipe_busy;
|
--rpipe->pipe_busy;
|
||||||
|
|
||||||
@ -762,6 +842,40 @@ unlocked_error:
|
|||||||
PIPE_UNLOCK(rpipe);
|
PIPE_UNLOCK(rpipe);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static ssize_t
|
||||||
|
rtems_bsd_pipe_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 = pipe_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__ */
|
||||||
|
|
||||||
#ifndef PIPE_NODIRECT
|
#ifndef PIPE_NODIRECT
|
||||||
/*
|
/*
|
||||||
@ -1189,7 +1303,11 @@ pipe_write(fp, uio, active_cred, flags, td)
|
|||||||
/*
|
/*
|
||||||
* don't block on non-blocking I/O
|
* don't block on non-blocking I/O
|
||||||
*/
|
*/
|
||||||
|
#ifndef __rtems__
|
||||||
if (fp->f_flag & FNONBLOCK) {
|
if (fp->f_flag & FNONBLOCK) {
|
||||||
|
#else /* __rtems__ */
|
||||||
|
if (rtems_bsd_libio_flags_to_fflag(fp->f_io.flags) & FNONBLOCK) {
|
||||||
|
#endif /* __rtems__ */
|
||||||
error = EAGAIN;
|
error = EAGAIN;
|
||||||
pipeunlock(wpipe);
|
pipeunlock(wpipe);
|
||||||
break;
|
break;
|
||||||
@ -1237,7 +1355,11 @@ pipe_write(fp, uio, active_cred, flags, td)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
|
#ifndef __rtems__
|
||||||
vfs_timestamp(&wpipe->pipe_mtime);
|
vfs_timestamp(&wpipe->pipe_mtime);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
wpipe->pipe_mtime.tv_sec = time(NULL);
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have something to offer,
|
* We have something to offer,
|
||||||
@ -1250,8 +1372,43 @@ pipe_write(fp, uio, active_cred, flags, td)
|
|||||||
PIPE_UNLOCK(rpipe);
|
PIPE_UNLOCK(rpipe);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static ssize_t
|
||||||
|
rtems_bsd_pipe_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 = pipe_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__ */
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
|
#ifndef __rtems__
|
||||||
static int
|
static int
|
||||||
pipe_truncate(fp, length, active_cred, td)
|
pipe_truncate(fp, length, active_cred, td)
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
@ -1262,6 +1419,7 @@ pipe_truncate(fp, length, active_cred, td)
|
|||||||
|
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we implement a very minimal set of ioctls for compatibility with sockets.
|
* we implement a very minimal set of ioctls for compatibility with sockets.
|
||||||
@ -1336,6 +1494,23 @@ pipe_ioctl(fp, cmd, data, active_cred, td)
|
|||||||
out_unlocked:
|
out_unlocked:
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static int
|
||||||
|
rtems_bsd_pipe_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer)
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
error = pipe_ioctl(fp, request, buffer, NULL, td);
|
||||||
|
} else {
|
||||||
|
error = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtems_bsd_error_to_status_and_errno(error);
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pipe_poll(fp, events, active_cred, td)
|
pipe_poll(fp, events, active_cred, td)
|
||||||
@ -1400,11 +1575,29 @@ locked_error:
|
|||||||
|
|
||||||
return (revents);
|
return (revents);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static int
|
||||||
|
rtems_bsd_pipe_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 = pipe_poll(fp, events, NULL, td);
|
||||||
|
} else {
|
||||||
|
error = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We shouldn't need locks here as we're doing a read and this should
|
* We shouldn't need locks here as we're doing a read and this should
|
||||||
* be a natural race.
|
* be a natural race.
|
||||||
*/
|
*/
|
||||||
|
#ifndef __rtems__
|
||||||
static int
|
static int
|
||||||
pipe_stat(fp, ub, active_cred, td)
|
pipe_stat(fp, ub, active_cred, td)
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
@ -1413,12 +1606,19 @@ pipe_stat(fp, ub, active_cred, td)
|
|||||||
struct thread *td;
|
struct thread *td;
|
||||||
{
|
{
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
#else /* __rtems__ */
|
||||||
|
static int
|
||||||
|
pipe_stat(struct pipe *pipe, struct stat *ub)
|
||||||
|
{
|
||||||
|
#endif /* __rtems__ */
|
||||||
int new_unr;
|
int new_unr;
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
int error;
|
int error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
pipe = fp->f_data;
|
pipe = fp->f_data;
|
||||||
|
#endif /* __rtems__ */
|
||||||
PIPE_LOCK(pipe);
|
PIPE_LOCK(pipe);
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
error = mac_pipe_check_stat(active_cred, pipe->pipe_pair);
|
error = mac_pipe_check_stat(active_cred, pipe->pipe_pair);
|
||||||
@ -1446,7 +1646,9 @@ pipe_stat(fp, ub, active_cred, td)
|
|||||||
}
|
}
|
||||||
PIPE_UNLOCK(pipe);
|
PIPE_UNLOCK(pipe);
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
bzero(ub, sizeof(*ub));
|
bzero(ub, sizeof(*ub));
|
||||||
|
#endif /* __rtems__ */
|
||||||
ub->st_mode = S_IFIFO;
|
ub->st_mode = S_IFIFO;
|
||||||
ub->st_blksize = PAGE_SIZE;
|
ub->st_blksize = PAGE_SIZE;
|
||||||
if (pipe->pipe_state & PIPE_DIRECTW)
|
if (pipe->pipe_state & PIPE_DIRECTW)
|
||||||
@ -1457,15 +1659,35 @@ pipe_stat(fp, ub, active_cred, td)
|
|||||||
ub->st_atim = pipe->pipe_atime;
|
ub->st_atim = pipe->pipe_atime;
|
||||||
ub->st_mtim = pipe->pipe_mtime;
|
ub->st_mtim = pipe->pipe_mtime;
|
||||||
ub->st_ctim = pipe->pipe_ctime;
|
ub->st_ctim = pipe->pipe_ctime;
|
||||||
|
#ifndef __rtems__
|
||||||
ub->st_uid = fp->f_cred->cr_uid;
|
ub->st_uid = fp->f_cred->cr_uid;
|
||||||
ub->st_gid = fp->f_cred->cr_gid;
|
ub->st_gid = fp->f_cred->cr_gid;
|
||||||
ub->st_dev = pipedev_ino;
|
ub->st_dev = pipedev_ino;
|
||||||
ub->st_ino = pipe->pipe_ino;
|
ub->st_ino = pipe->pipe_ino;
|
||||||
|
#else /* __rtems__ */
|
||||||
|
ub->st_uid = BSD_DEFAULT_UID;
|
||||||
|
ub->st_gid = BSD_DEFAULT_GID;
|
||||||
|
ub->st_dev = rtems_filesystem_make_dev_t(0xcc494cd6U, 0x1d970b4dU);
|
||||||
|
ub->st_ino = pipe->pipe_ino;
|
||||||
|
#endif /* __rtems__ */
|
||||||
/*
|
/*
|
||||||
* Left as 0: st_nlink, st_rdev, st_flags, st_gen.
|
* Left as 0: st_nlink, st_rdev, st_flags, st_gen.
|
||||||
*/
|
*/
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static int
|
||||||
|
rtems_bsd_pipe_stat(
|
||||||
|
const rtems_filesystem_location_info_t *loc,
|
||||||
|
struct stat *buf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
struct pipe *pipe = rtems_bsd_loc_to_f_data(loc);
|
||||||
|
int error = pipe_stat(pipe, buf);
|
||||||
|
|
||||||
|
return rtems_bsd_error_to_status_and_errno(error);
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
@ -1475,7 +1697,11 @@ pipe_close(fp, td)
|
|||||||
{
|
{
|
||||||
struct pipe *cpipe = fp->f_data;
|
struct pipe *cpipe = fp->f_data;
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
fp->f_ops = &badfileops;
|
fp->f_ops = &badfileops;
|
||||||
|
#else /* __rtems__ */
|
||||||
|
fp->f_io.pathinfo.handlers = &rtems_filesystem_handlers_default;
|
||||||
|
#endif /* __rtems__ */
|
||||||
fp->f_data = NULL;
|
fp->f_data = NULL;
|
||||||
funsetown(&cpipe->pipe_sigio);
|
funsetown(&cpipe->pipe_sigio);
|
||||||
pipeclose(cpipe);
|
pipeclose(cpipe);
|
||||||
@ -1492,9 +1718,13 @@ pipe_free_kmem(cpipe)
|
|||||||
|
|
||||||
if (cpipe->pipe_buffer.buffer != NULL) {
|
if (cpipe->pipe_buffer.buffer != NULL) {
|
||||||
atomic_subtract_long(&amountpipekva, cpipe->pipe_buffer.size);
|
atomic_subtract_long(&amountpipekva, cpipe->pipe_buffer.size);
|
||||||
|
#ifndef __rtems__
|
||||||
vm_map_remove(pipe_map,
|
vm_map_remove(pipe_map,
|
||||||
(vm_offset_t)cpipe->pipe_buffer.buffer,
|
(vm_offset_t)cpipe->pipe_buffer.buffer,
|
||||||
(vm_offset_t)cpipe->pipe_buffer.buffer + cpipe->pipe_buffer.size);
|
(vm_offset_t)cpipe->pipe_buffer.buffer + cpipe->pipe_buffer.size);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
free(cpipe->pipe_buffer.buffer, M_TEMP);
|
||||||
|
#endif /* __rtems__ */
|
||||||
cpipe->pipe_buffer.buffer = NULL;
|
cpipe->pipe_buffer.buffer = NULL;
|
||||||
}
|
}
|
||||||
#ifndef PIPE_NODIRECT
|
#ifndef PIPE_NODIRECT
|
||||||
@ -1626,6 +1856,15 @@ pipe_kqfilter(struct file *fp, struct knote *kn)
|
|||||||
PIPE_UNLOCK(cpipe);
|
PIPE_UNLOCK(cpipe);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
int
|
||||||
|
rtems_bsd_pipe_kqfilter(rtems_libio_t *iop, struct knote *kn)
|
||||||
|
{
|
||||||
|
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
||||||
|
|
||||||
|
return pipe_kqfilter(fp, kn);
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
filt_pipedetach(struct knote *kn)
|
filt_pipedetach(struct knote *kn)
|
||||||
@ -1687,3 +1926,35 @@ filt_pipewrite(struct knote *kn, long hint)
|
|||||||
PIPE_UNLOCK(rpipe);
|
PIPE_UNLOCK(rpipe);
|
||||||
return (kn->kn_data >= PIPE_BUF);
|
return (kn->kn_data >= PIPE_BUF);
|
||||||
}
|
}
|
||||||
|
#ifdef __rtems__
|
||||||
|
static int
|
||||||
|
rtems_bsd_pipe_open(rtems_libio_t *iop, const char *path, int oflag,
|
||||||
|
mode_t mode)
|
||||||
|
{
|
||||||
|
return rtems_bsd_error_to_status_and_errno(ENXIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rtems_bsd_pipe_close(rtems_libio_t *iop)
|
||||||
|
{
|
||||||
|
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
||||||
|
int error = pipe_close(fp, NULL);
|
||||||
|
|
||||||
|
return rtems_bsd_error_to_status_and_errno(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rtems_bsd_pipe_fcntl(rtems_libio_t *iop, int cmd)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
if (cmd == F_SETFL) {
|
||||||
|
struct file *fp = rtems_bsd_iop_to_fp(iop);
|
||||||
|
int nbio = iop->flags & LIBIO_FLAGS_NO_DELAY;
|
||||||
|
|
||||||
|
error = pipe_ioctl(fp, FIONBIO, &nbio, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtems_bsd_error_to_status_and_errno(error);
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
2
freebsd/sys/sys/pipe.h
Normal file → Executable file
2
freebsd/sys/sys/pipe.h
Normal file → Executable file
@ -78,7 +78,9 @@ struct pipemapping {
|
|||||||
vm_size_t cnt; /* number of chars in buffer */
|
vm_size_t cnt; /* number of chars in buffer */
|
||||||
vm_size_t pos; /* current position of transfer */
|
vm_size_t pos; /* current position of transfer */
|
||||||
int npages; /* number of pages */
|
int npages; /* number of pages */
|
||||||
|
#ifndef __rtems__
|
||||||
vm_page_t ms[PIPENPAGES]; /* pages in source process */
|
vm_page_t ms[PIPENPAGES]; /* pages in source process */
|
||||||
|
#endif /* __rtems__ */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -258,6 +258,7 @@ def base(mm):
|
|||||||
'sys/sys/_null.h',
|
'sys/sys/_null.h',
|
||||||
'sys/sys/osd.h',
|
'sys/sys/osd.h',
|
||||||
'sys/sys/pcpu.h',
|
'sys/sys/pcpu.h',
|
||||||
|
'sys/sys/pipe.h',
|
||||||
'sys/sys/priv.h',
|
'sys/sys/priv.h',
|
||||||
'sys/sys/proc.h',
|
'sys/sys/proc.h',
|
||||||
'sys/sys/protosw.h',
|
'sys/sys/protosw.h',
|
||||||
@ -348,6 +349,7 @@ def base(mm):
|
|||||||
'sys/kern/subr_uio.c',
|
'sys/kern/subr_uio.c',
|
||||||
'sys/kern/subr_unit.c',
|
'sys/kern/subr_unit.c',
|
||||||
'sys/kern/sys_generic.c',
|
'sys/kern/sys_generic.c',
|
||||||
|
'sys/kern/sys_pipe.c',
|
||||||
'sys/kern/uipc_accf.c',
|
'sys/kern/uipc_accf.c',
|
||||||
'sys/kern/uipc_domain.c',
|
'sys/kern/uipc_domain.c',
|
||||||
'sys/kern/uipc_mbuf2.c',
|
'sys/kern/uipc_mbuf2.c',
|
||||||
|
@ -836,6 +836,7 @@ def build(bld):
|
|||||||
'freebsd/sys/kern/subr_uio.c',
|
'freebsd/sys/kern/subr_uio.c',
|
||||||
'freebsd/sys/kern/subr_unit.c',
|
'freebsd/sys/kern/subr_unit.c',
|
||||||
'freebsd/sys/kern/sys_generic.c',
|
'freebsd/sys/kern/sys_generic.c',
|
||||||
|
'freebsd/sys/kern/sys_pipe.c',
|
||||||
'freebsd/sys/kern/sys_socket.c',
|
'freebsd/sys/kern/sys_socket.c',
|
||||||
'freebsd/sys/kern/uipc_accf.c',
|
'freebsd/sys/kern/uipc_accf.c',
|
||||||
'freebsd/sys/kern/uipc_domain.c',
|
'freebsd/sys/kern/uipc_domain.c',
|
||||||
|
29
rtemsbsd/sys/fs/devfs/devfs_devs.c
Normal file → Executable file
29
rtemsbsd/sys/fs/devfs/devfs_devs.c
Normal file → Executable file
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -45,8 +46,12 @@
|
|||||||
|
|
||||||
#include <rtems/imfs.h>
|
#include <rtems/imfs.h>
|
||||||
|
|
||||||
|
#define DEVFS_ROOTINO 2
|
||||||
|
|
||||||
const char rtems_cdev_directory[] = RTEMS_CDEV_DIRECTORY;
|
const char rtems_cdev_directory[] = RTEMS_CDEV_DIRECTORY;
|
||||||
|
|
||||||
|
struct unrhdr *devfs_inos;
|
||||||
|
|
||||||
static struct cdev *
|
static struct cdev *
|
||||||
devfs_imfs_get_context_by_iop(rtems_libio_t *iop)
|
devfs_imfs_get_context_by_iop(rtems_libio_t *iop)
|
||||||
{
|
{
|
||||||
@ -325,3 +330,27 @@ devfs_dev_exists(const char *name)
|
|||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ino_t
|
||||||
|
devfs_alloc_cdp_inode(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (alloc_unr(devfs_inos));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
devfs_free_cdp_inode(ino_t ino)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ino > 0)
|
||||||
|
free_unr(devfs_inos, ino);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
devfs_devs_init(void *junk __unused)
|
||||||
|
{
|
||||||
|
|
||||||
|
devfs_inos = new_unrhdr(DEVFS_ROOTINO + 1, INT_MAX, &devmtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
SYSINIT(devfs_devs, SI_SUB_DEVFS, SI_ORDER_FIRST, devfs_devs_init, NULL);
|
||||||
|
183
testsuite/selectpollkqueue01/test_main.c
Normal file → Executable file
183
testsuite/selectpollkqueue01/test_main.c
Normal file → Executable file
@ -55,7 +55,7 @@
|
|||||||
#include <rtems/libcsupport.h>
|
#include <rtems/libcsupport.h>
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
|
|
||||||
#define TEST_NAME "LIBBSD SELECT AND POLL AND KQUEUE 1"
|
#define TEST_NAME "LIBBSD SELECT AND POLL AND KQUEUE AND PIPE 1"
|
||||||
|
|
||||||
#define PRIO_MASTER 1
|
#define PRIO_MASTER 1
|
||||||
|
|
||||||
@ -71,6 +71,8 @@
|
|||||||
|
|
||||||
#define EVENT_SHUTDOWN RTEMS_EVENT_4
|
#define EVENT_SHUTDOWN RTEMS_EVENT_4
|
||||||
|
|
||||||
|
#define EVENT_CLOSE_PIPE RTEMS_EVENT_5
|
||||||
|
|
||||||
#define BUF_SIZE 4096
|
#define BUF_SIZE 4096
|
||||||
|
|
||||||
#define PORT 1234
|
#define PORT 1234
|
||||||
@ -88,6 +90,7 @@ typedef struct {
|
|||||||
int afd;
|
int afd;
|
||||||
int rfd;
|
int rfd;
|
||||||
int wfd;
|
int wfd;
|
||||||
|
int pfd[2];
|
||||||
struct sockaddr_in caddr;
|
struct sockaddr_in caddr;
|
||||||
rtems_id worker_task;
|
rtems_id worker_task;
|
||||||
} test_context;
|
} test_context;
|
||||||
@ -173,6 +176,8 @@ worker_task(rtems_task_argument arg)
|
|||||||
ssize_t n;
|
ssize_t n;
|
||||||
int rv;
|
int rv;
|
||||||
int cfd = ctx->cfd;
|
int cfd = ctx->cfd;
|
||||||
|
int rfd = ctx->pfd[0];
|
||||||
|
int wfd = ctx->pfd[1];
|
||||||
|
|
||||||
sc = rtems_event_receive(
|
sc = rtems_event_receive(
|
||||||
RTEMS_ALL_EVENTS,
|
RTEMS_ALL_EVENTS,
|
||||||
@ -236,6 +241,19 @@ worker_task(rtems_task_argument arg)
|
|||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((events & EVENT_CLOSE_PIPE) != 0) {
|
||||||
|
puts("worker: close pipe");
|
||||||
|
|
||||||
|
ctx->pfd[0] = -1;
|
||||||
|
ctx->pfd[1] = -1;
|
||||||
|
|
||||||
|
rv = close(wfd);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
rv = close(rfd);
|
||||||
|
assert(rv == 0);
|
||||||
|
}
|
||||||
|
|
||||||
if ((events & EVENT_SHUTDOWN) != 0) {
|
if ((events & EVENT_SHUTDOWN) != 0) {
|
||||||
puts("worker: shutdown");
|
puts("worker: shutdown");
|
||||||
|
|
||||||
@ -281,8 +299,13 @@ static void
|
|||||||
set_non_blocking(int fd, int enable)
|
set_non_blocking(int fd, int enable)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
int flags = fcntl(fd, F_GETFL, 0);
|
||||||
|
|
||||||
rv = ioctl(fd, FIONBIO, &enable);
|
if (enable) {
|
||||||
|
rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
} else {
|
||||||
|
rv = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
|
||||||
|
}
|
||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1003,6 +1026,157 @@ test_kqueue_user(test_context *ctx)
|
|||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_pipe_timeout(test_context *ctx)
|
||||||
|
{
|
||||||
|
struct pipe_poll_events
|
||||||
|
{
|
||||||
|
short event;
|
||||||
|
int rv;
|
||||||
|
};
|
||||||
|
const struct pipe_poll_events events[] = {
|
||||||
|
{ POLLIN, 0 },
|
||||||
|
{ POLLPRI, 0 },
|
||||||
|
{ POLLOUT, 1 },
|
||||||
|
{ POLLRDNORM, 0 },
|
||||||
|
{ POLLWRNORM, 1 },
|
||||||
|
{ POLLRDBAND, 0 },
|
||||||
|
{ POLLWRBAND, 0 },
|
||||||
|
{ POLLINIGNEOF, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int timeout = 100;
|
||||||
|
struct pollfd pfd;
|
||||||
|
size_t i;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
puts("test pipe timeout");
|
||||||
|
|
||||||
|
rv = pipe(ctx->pfd);
|
||||||
|
assert(rv == 0);
|
||||||
|
|
||||||
|
pfd.fd = ctx->pfd[1];
|
||||||
|
|
||||||
|
for (i = 0; i < nitems(events); ++i) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
pfd.events = events[i].event;
|
||||||
|
pfd.revents = 0;
|
||||||
|
|
||||||
|
rv = poll(&pfd, 1, timeout);
|
||||||
|
assert(rv == events[i].rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_pipe_read(test_context *ctx)
|
||||||
|
{
|
||||||
|
int rfd = ctx->pfd[0];
|
||||||
|
int wfd = ctx->pfd[1];
|
||||||
|
struct pollfd pfd = {
|
||||||
|
.fd = rfd,
|
||||||
|
.events = POLLIN
|
||||||
|
};
|
||||||
|
int timeout = -1;
|
||||||
|
int rv;
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
puts("test pipe read");
|
||||||
|
|
||||||
|
assert(rfd >= 0);
|
||||||
|
assert(wfd >= 0);
|
||||||
|
|
||||||
|
ctx->wfd = wfd;
|
||||||
|
ctx->wbuf = &msg[0];
|
||||||
|
ctx->wn = sizeof(msg);
|
||||||
|
send_events(ctx, EVENT_WRITE);
|
||||||
|
|
||||||
|
set_non_blocking(rfd, 1);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = read(rfd, &ctx->buf[0], sizeof(ctx->buf));
|
||||||
|
assert(n == -1);
|
||||||
|
assert(errno == EAGAIN);
|
||||||
|
|
||||||
|
rv = poll(&pfd, 1, timeout);
|
||||||
|
assert(rv == 1);
|
||||||
|
assert(pfd.revents == POLLIN);
|
||||||
|
|
||||||
|
n = read(rfd, &ctx->buf[0], sizeof(ctx->buf));
|
||||||
|
assert(n == (ssize_t) sizeof(msg));
|
||||||
|
assert(memcmp(&msg[0], &ctx->buf[0], sizeof(msg)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_pipe_write(test_context *ctx)
|
||||||
|
{
|
||||||
|
int rfd = ctx->pfd[0];
|
||||||
|
int wfd = ctx->pfd[1];
|
||||||
|
struct pollfd pfd = {
|
||||||
|
.fd = wfd,
|
||||||
|
.events = POLLOUT
|
||||||
|
};
|
||||||
|
int timeout = -1;
|
||||||
|
int rv;
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
puts("test pipe write");
|
||||||
|
|
||||||
|
assert(rfd >= 0);
|
||||||
|
assert(wfd >= 0);
|
||||||
|
|
||||||
|
ctx->rfd = rfd;
|
||||||
|
ctx->rbuf = &ctx->buf[0];
|
||||||
|
ctx->rn = sizeof(ctx->buf);
|
||||||
|
send_events(ctx, EVENT_READ);
|
||||||
|
|
||||||
|
set_non_blocking(wfd, 1);
|
||||||
|
|
||||||
|
do {
|
||||||
|
errno = 0;
|
||||||
|
n = write(wfd, &ctx->buf[0], sizeof(ctx->buf));
|
||||||
|
if (n == -1) {
|
||||||
|
assert(errno == EAGAIN);
|
||||||
|
}
|
||||||
|
} while (n > 0);
|
||||||
|
|
||||||
|
rv = poll(&pfd, 1, timeout);
|
||||||
|
assert(rv == 1);
|
||||||
|
assert(pfd.revents == POLLOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_pipe_close(test_context *ctx)
|
||||||
|
{
|
||||||
|
int rfd = ctx->pfd[0];
|
||||||
|
int wfd = ctx->pfd[1];
|
||||||
|
struct pollfd pfd = {
|
||||||
|
.fd = rfd,
|
||||||
|
.events = POLLIN
|
||||||
|
};
|
||||||
|
int timeout = -1;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
puts("test pipe close");
|
||||||
|
|
||||||
|
assert(ctx->pfd[0] >= 0);
|
||||||
|
assert(ctx->pfd[1] >= 0);
|
||||||
|
|
||||||
|
send_events(ctx, EVENT_CLOSE_PIPE);
|
||||||
|
|
||||||
|
set_non_blocking(rfd, 0);
|
||||||
|
|
||||||
|
assert(ctx->pfd[0] >= 0);
|
||||||
|
assert(ctx->pfd[1] >= 0);
|
||||||
|
|
||||||
|
rv = poll(&pfd, 1, timeout);
|
||||||
|
assert(rv == 1);
|
||||||
|
assert(pfd.revents == (POLLIN | POLLHUP));
|
||||||
|
|
||||||
|
assert(ctx->pfd[0] == -1);
|
||||||
|
assert(ctx->pfd[1] == -1);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_main(void)
|
test_main(void)
|
||||||
{
|
{
|
||||||
@ -1034,6 +1208,11 @@ test_main(void)
|
|||||||
test_kqueue_close(ctx);
|
test_kqueue_close(ctx);
|
||||||
test_kqueue_user(ctx);
|
test_kqueue_user(ctx);
|
||||||
|
|
||||||
|
test_pipe_timeout(ctx);
|
||||||
|
test_pipe_read(ctx);
|
||||||
|
test_pipe_write(ctx);
|
||||||
|
test_pipe_close(ctx);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user