diff options
Diffstat (limited to 'rtemsbsd/rtems/rtems-bsd-libio.c')
-rw-r--r-- | rtemsbsd/rtems/rtems-bsd-libio.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/rtemsbsd/rtems/rtems-bsd-libio.c b/rtemsbsd/rtems/rtems-bsd-libio.c new file mode 100644 index 00000000..bb38594c --- /dev/null +++ b/rtemsbsd/rtems/rtems-bsd-libio.c @@ -0,0 +1,193 @@ +/** + * @file + * + * @ingroup rtems_bsd_rtems + * + * @brief TODO. + */ + +/* + * Copyright 2020 Chris Johns. All Rights Reserved. + * + * Contemporary Software + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/rtems-bsd-kernel-space.h> + +#include <sys/param.h> +#include <sys/filedesc.h> +#include <sys/proc.h> +#include <sys/vnode.h> + +#include <machine/rtems-bsd-libio.h> + +#include <rtems/libio.h> + +rtems_libio_t * +rtems_bsd_libio_iop_allocate(void) +{ + rtems_libio_t *iop = rtems_libio_allocate(); + if (iop != NULL) { + iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry; + rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo); + } + return iop; +} + +int +rtems_bsd_libio_iop_allocate_with_file( + struct thread *td, int fd, const rtems_filesystem_file_handlers_r *ops) +{ + rtems_libio_t *iop = rtems_bsd_libio_iop_allocate(); + int iofd = -1; + if (iop != NULL) { + int error = rtems_bsd_libio_iop_set_bsd_fd(td, fd, iop, ops); + /* + * The fp is held and needs to be dropped and that drops the + * iop. + */ + if (error == 0) { + rtems_libio_iop_hold(iop); + iofd = rtems_libio_iop_to_descriptor(iop); + } else { + rtems_libio_free(iop); + } + } + return iofd; +} + +int +rtems_bsd_libio_iop_set_bsd_fd(struct thread *td, int fd, rtems_libio_t *iop, + const rtems_filesystem_file_handlers_r *ops) +{ + struct filedesc *fdp = td->td_proc->p_fd; + int error; + FILEDESC_XLOCK(fdp); + if (fd < fdp->fd_nfiles) { + struct file *fp = fget_locked(fdp, fd); + if (fp != NULL) { + rtems_bsd_libio_iop_set_bsd_file(iop, fp); + rtems_libio_iop_flags_set(iop, + LIBIO_FLAGS_OPEN | + rtems_bsd_libio_fflag_to_flags(fp->f_flag)); + if (ops != NULL) + iop->pathinfo.handlers = ops; + rtems_bsd_libio_iop_set_bsd_descriptor(iop, fd); + error = 0; + } else { + error = EBADF; + } + } else { + error = EBADF; + } + FILEDESC_XUNLOCK(fdp); + return error; +} + +void +rtems_bsd_libio_loc_set_vnode( + rtems_filesystem_location_info_t *loc, struct vnode *vp) +{ + struct vnode *old = loc->node_access; + int hc = 0; + int rc = 0; + if (vp != NULL) { + hc = vp->v_holdcnt; + rc = vrefcnt(vp); + } + int old_hc = 0; + int old_rc = 0; + if (old != NULL) { + old_hc = old->v_holdcnt; + old_rc = vrefcnt(old); + } + if (vp != old) { + if (old != NULL) + vrele(old); + if (vp != NULL) + VREF(vp); + loc->node_access = vp; + } + int new_hc = 0; + int new_rc = 0; + if (vp != NULL) { + new_hc = vp->v_holdcnt; + new_rc = vrefcnt(vp); + } + int old_new_hc = 0; + int old_new_rc = 0; + if (old != NULL) { + old_new_hc = old->v_holdcnt; + old_new_rc = vrefcnt(old); + } + if (RTEMS_BSD_DESCRIP_TRACE || true) + printf( + "bsd: lio: set-vode loc=%p vn=%p (%d/%d)->(%d/%d) old=%p (%d/%d)->(%d/%d)\n", + loc, vp, hc, rc, new_hc, new_rc, old, old_hc, old_rc, + old_new_hc, old_new_rc); +} + +void +rtems_bsd_libio_loc_set_vnode_dir( + rtems_filesystem_location_info_t *loc, struct vnode *dvp) +{ + struct vnode *old = loc->node_access_2; + int hc = 0; + int rc = 0; + if (dvp != NULL) { + hc = dvp->v_holdcnt; + rc = vrefcnt(dvp); + } + int old_hc = 0; + int old_rc = 0; + if (old != NULL) { + old_hc = old->v_holdcnt; + old_rc = vrefcnt(old); + } + if (dvp != old) { + if (old != NULL) + vrele(old); + if (dvp != NULL) + VREF(dvp); + loc->node_access_2 = dvp; + } + int new_hc = 0; + int new_rc = 0; + if (dvp != NULL) { + new_hc = dvp->v_holdcnt; + new_rc = vrefcnt(dvp); + } + int old_new_hc = 0; + int old_new_rc = 0; + if (old != NULL) { + old_new_hc = old->v_holdcnt; + old_new_rc = vrefcnt(old); + } + if (RTEMS_BSD_DESCRIP_TRACE) + printf( + "bsd: lio: set-vode-dir loc=%p vn=%p (%d/%d)->(%d/%d) old=%p (%d/%d)->(%d/%d)\n", + loc, dvp, hc, rc, new_hc, new_rc, old, old_hc, old_rc, + old_new_hc, old_new_rc); +} |