[libbsd 09/22] Remove FreeBSD file descriptors

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Jun 24 06:33:37 UTC 2022


Remove FreeBSD file descriptors due to performance and code complexity reasons.

Update #4475.
---
 freebsd/sys/kern/kern_descrip.c               |  58 +--
 freebsd/sys/kern/kern_event.c                 | 121 ++---
 freebsd/sys/kern/sys_generic.c                | 136 ++++--
 freebsd/sys/kern/uipc_socket.c                |  24 +
 freebsd/sys/kern/uipc_syscalls.c              |  16 +
 freebsd/sys/kern/vfs_cache.c                  |   2 +
 freebsd/sys/kern/vfs_lookup.c                 |   4 +
 freebsd/sys/kern/vfs_mount.c                  |   2 +
 freebsd/sys/kern/vfs_subr.c                   |   4 +
 freebsd/sys/kern/vfs_syscalls.c               |  18 +
 freebsd/sys/opencrypto/cryptodev.c            |  11 +-
 freebsd/sys/sys/file.h                        |  98 +++-
 freebsd/sys/sys/filedesc.h                    |  89 +++-
 freebsd/sys/sys/namei.h                       |   2 +
 freebsd/sys/sys/proc.h                        |   2 +-
 freebsd/sys/sys/socketvar.h                   |  15 +-
 freebsd/sys/sys/syscallsubr.h                 |   5 +
 libbsd.py                                     |   1 +
 .../machine/rtems-bsd-kernel-namespace.h      |  18 -
 .../include/machine/rtems-bsd-kernel-space.h  |   5 -
 rtemsbsd/include/machine/rtems-bsd-libio.h    | 196 +-------
 rtemsbsd/rtems/rtems-bsd-libio.c              |  61 ---
 rtemsbsd/rtems/rtems-bsd-syscall-api.c        | 462 ++++++++----------
 rtemsbsd/rtems/rtems-kernel-fget.c            |  79 +++
 rtemsbsd/rtems/rtems-kernel-init.c            |   7 +-
 25 files changed, 713 insertions(+), 723 deletions(-)
 create mode 100644 rtemsbsd/rtems/rtems-kernel-fget.c

diff --git a/freebsd/sys/kern/kern_descrip.c b/freebsd/sys/kern/kern_descrip.c
index ddc50633..e32201c9 100644
--- a/freebsd/sys/kern/kern_descrip.c
+++ b/freebsd/sys/kern/kern_descrip.c
@@ -76,7 +76,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/syscallsubr.h>
 #include <sys/sysctl.h>
 #include <sys/sysproto.h>
-#include <rtems/bsd/sys/unistd.h>
+#include <sys/unistd.h>
 #include <sys/user.h>
 #include <sys/vnode.h>
 #ifdef KTRACE
@@ -92,6 +92,7 @@ __FBSDID("$FreeBSD$");
 
 #include <ddb/ddb.h>
 
+#ifndef __rtems__
 static MALLOC_DEFINE(M_FILEDESC, "filedesc", "Open file descriptor table");
 static MALLOC_DEFINE(M_FILEDESC_TO_LEADER, "filedesc_to_leader",
     "file desc to leader structures");
@@ -362,7 +363,6 @@ sys_getdtablesize(struct thread *td, struct getdtablesize_args *uap)
 	return (0);
 }
 
-#ifndef __rtems__
 /*
  * Duplicate a file descriptor to a particular value.
  *
@@ -526,7 +526,6 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 		tmp = arg;
 		error = kern_dup(td, FDDUP_FIXED, FDDUP_FLAG_CLOEXEC, fd, tmp);
 		break;
-#endif /* __rtems__ */
 
 	case F_GETFD:
 		error = EBADF;
@@ -551,6 +550,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 		}
 		FILEDESC_XUNLOCK(fdp);
 		break;
+#endif /* __rtems__ */
 
 	case F_GETFL:
 		error = fget_fcntl(td, fd, &cap_fcntl_rights, F_GETFL, &fp);
@@ -813,6 +813,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 	return (error);
 }
 
+#ifndef __rtems__
 static int
 getmaxfd(struct thread *td)
 {
@@ -820,7 +821,6 @@ getmaxfd(struct thread *td)
 	return (min((int)lim_cur(td, RLIMIT_NOFILE), maxfilesperproc));
 }
 
-#ifndef __rtems__
 /*
  * Common code for dup, dup2, fcntl(F_DUPFD) and fcntl(F_DUP2FD).
  */
@@ -1182,7 +1182,6 @@ fgetown(struct sigio **sigiop)
 	SIGIO_UNLOCK();
 	return (pgid);
 }
-#endif /* __rtems__ */
 
 /*
  * Function drops the filedesc lock on return.
@@ -1273,7 +1272,6 @@ kern_close(struct thread *td, int fd)
 	return (closefp(fdp, fd, fp, td, 1));
 }
 
-#ifndef __rtems__
 /*
  * Close open file descriptors.
  */
@@ -1309,7 +1307,6 @@ sys_closefrom(struct thread *td, struct closefrom_args *uap)
 	FILEDESC_SUNLOCK(fdp);
 	return (0);
 }
-#endif /* __rtems__ */
 
 #if defined(COMPAT_43)
 /*
@@ -1436,7 +1433,6 @@ freebsd11_nfstat(struct thread *td, struct freebsd11_nfstat_args *uap)
 }
 #endif /* COMPAT_FREEBSD11 */
 
-#ifndef __rtems__
 /*
  * Return pathconf information about a file descriptor.
  */
@@ -1493,7 +1489,6 @@ out:
 	fdrop(fp, td);
 	return (error);
 }
-#endif /* __rtems__ */
 
 /*
  * Initialize filecaps structure.
@@ -1628,7 +1623,6 @@ static void
 filecaps_validate(const struct filecaps *fcaps, const char *func)
 {
 
-#ifndef __rtems__
 	KASSERT(cap_rights_is_valid(&fcaps->fc_rights),
 	    ("%s: invalid rights", func));
 	KASSERT((fcaps->fc_fcntls & ~CAP_FCNTL_ALL) == 0,
@@ -1642,7 +1636,6 @@ filecaps_validate(const struct filecaps *fcaps, const char *func)
 	KASSERT(fcaps->fc_nioctls == 0 ||
 	    cap_rights_is_set(&fcaps->fc_rights, CAP_IOCTL),
 	    ("%s: ioctls without CAP_IOCTL", func));
-#endif /* __rtems__ */
 }
 
 static void
@@ -1891,12 +1884,10 @@ falloc_noinstall(struct thread *td, struct file **resultfp)
 	    priv_check(td, PRIV_MAXFILES) != 0) ||
 	    openfiles_new >= maxfiles) {
 		atomic_subtract_int(&openfiles, 1);
-#ifndef __rtems__
 		if (ppsratecheck(&lastfail, &curfail, 1)) {
 			printf("kern.maxfiles limit exceeded by uid %i, (%s) "
 			    "please see tuning(7).\n", td->td_ucred->cr_ruid, td->td_proc->p_comm);
 		}
-#endif /* __rtems__ */
 		return (ENFILE);
 	}
 	fp = uma_zalloc(file_zone, M_WAITOK);
@@ -2050,7 +2041,6 @@ fdshare(struct filedesc *fdp)
 	return (fdp);
 }
 
-#ifndef __rtems__
 /*
  * Unshare a filedesc structure, if necessary by making a copy
  */
@@ -2404,7 +2394,6 @@ fdsetugidsafety(struct thread *td)
 		}
 	}
 }
-#endif /* __rtems__ */
 
 /*
  * If a specific file object occupies a specific file descriptor, close the
@@ -2427,7 +2416,6 @@ fdclose(struct thread *td, struct file *fp, int idx)
 		FILEDESC_XUNLOCK(fdp);
 }
 
-#ifndef __rtems__
 /*
  * Close any files on exec?
  */
@@ -2453,7 +2441,6 @@ fdcloseexec(struct thread *td)
 		}
 	}
 }
-#endif /* __rtems__ */
 
 /*
  * It is unsafe for set[ug]id processes to be started with file
@@ -2522,7 +2509,6 @@ closef(struct file *fp, struct thread *td)
 	 */
 	if (fp->f_type == DTYPE_VNODE && td != NULL) {
 		vp = fp->f_vnode;
-#ifndef __rtems__
 		if ((td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) {
 			lf.l_whence = SEEK_SET;
 			lf.l_start = 0;
@@ -2531,7 +2517,6 @@ closef(struct file *fp, struct thread *td)
 			(void) VOP_ADVLOCK(vp, (caddr_t)td->td_proc->p_leader,
 			    F_UNLCK, &lf, F_POSIX);
 		}
-#endif /* __rtems__ */
 		fdtol = td->td_proc->p_fdtol;
 		if (fdtol != NULL) {
 			/*
@@ -2543,10 +2528,8 @@ closef(struct file *fp, struct thread *td)
 			for (fdtol = fdtol->fdl_next;
 			    fdtol != td->td_proc->p_fdtol;
 			    fdtol = fdtol->fdl_next) {
-#ifndef __rtems__
 				if ((fdtol->fdl_leader->p_flag &
 				    P_ADVLOCK) == 0)
-#endif /* __rtems__ */
 					continue;
 				fdtol->fdl_holdcount++;
 				FILEDESC_XUNLOCK(fdp);
@@ -2746,18 +2729,6 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 		*seqp = seq;
 #endif
 	}
-#ifdef __rtems__
-	if (fp->f_io != NULL) {
-		rtems_libio_iop_hold(fp->f_io);
-		if (RTEMS_BSD_DESCRIP_TRACE)
-			printf("bsd:  fb: fget_unlocked: iop=%p %d (%d)  fp=%p (%d) by %p\n",
-			       fp->f_io, fp->f_io->data0, fp->f_io->flags >> 12,
-			       fp, fp->f_count, __builtin_return_address(0));
-	} else if (RTEMS_BSD_DESCRIP_TRACE) {
-		printf("bsd:  fb: fget_unlocked: iop=NULL -1 (0) fp=%p (%d) by %p\n",
-		       fp, fp->f_count, __builtin_return_address(0));
-	}
-#endif /* __rtems__ */
 	return (0);
 }
 
@@ -2802,13 +2773,11 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags,
 		if ((fp->f_flag & flags) == 0)
 			error = EBADF;
 		break;
-#ifndef __rtems__
 	case FEXEC:
 	    	if ((fp->f_flag & (FREAD | FEXEC)) == 0 ||
 		    ((fp->f_flag & FWRITE) != 0))
 			error = EBADF;
 		break;
-#endif /* __rtems__ */
 	case 0:
 		break;
 	default:
@@ -2831,7 +2800,6 @@ fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
 	return (_fget(td, fd, fpp, 0, rightsp, NULL));
 }
 
-#ifndef __rtems__
 int
 fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp, u_char *maxprotp,
     struct file **fpp)
@@ -2866,7 +2834,6 @@ fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp, u_char *maxprotp,
 #endif
 	return (error);
 }
-#endif /* __rtems__ */
 
 int
 fget_read(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
@@ -2986,14 +2953,12 @@ fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp
 	return (_fgetvp(td, fd, FREAD, rightsp, vpp));
 }
 
-#ifndef __rtems__
 int
 fgetvp_exec(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp)
 {
 
 	return (_fgetvp(td, fd, FEXEC, rightsp, vpp));
 }
-#endif /* __rtems__ */
 
 #ifdef notyet
 int
@@ -3021,15 +2986,12 @@ _fdrop(struct file *fp, struct thread *td)
 	error = fo_close(fp, td);
 	atomic_subtract_int(&openfiles, 1);
 	crfree(fp->f_cred);
-#ifndef __rtems__
 	free(fp->f_advice, M_FADVISE);
-#endif /* __rtems__ */
 	uma_zfree(file_zone, fp);
 
 	return (error);
 }
 
-#ifndef __rtems__
 /*
  * Apply an advisory lock on a file descriptor.
  *
@@ -3248,7 +3210,6 @@ pwd_chroot(struct thread *td, struct vnode *vp)
 	vrele(oldvp);
 	return (0);
 }
-#endif /* __rtems__ */
 
 void
 pwd_chdir(struct thread *td, struct vnode *vp)
@@ -3273,7 +3234,6 @@ pwd_chdir(struct thread *td, struct vnode *vp)
 void
 mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
 {
-#ifndef __rtems__
 	struct filedesc *fdp;
 	struct prison *pr;
 	struct proc *p;
@@ -3334,7 +3294,6 @@ mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
 	sx_sunlock(&allprison_lock);
 	while (nrele--)
 		vrele(olddp);
-#endif /* __rtems__ */
 }
 
 struct filedesc_to_leader *
@@ -3362,7 +3321,6 @@ filedesc_to_leader_alloc(struct filedesc_to_leader *old, struct filedesc *fdp, s
 	return (fdtol);
 }
 
-#ifndef __rtems__
 static int
 sysctl_kern_proc_nfds(SYSCTL_HANDLER_ARGS)
 {
@@ -3861,7 +3819,6 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_OFILEDESC, ofiledesc,
     CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc_ofiledesc,
     "Process ofiledesc entries");
 #endif	/* COMPAT_FREEBSD7 */
-#endif /* __rtems__ */
 
 int
 vntype_to_kinfo(int vtype)
@@ -3892,7 +3849,6 @@ vntype_to_kinfo(int vtype)
 	return (KF_VTYPE_UNKNOWN);
 }
 
-#ifndef __rtems__
 static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc,
     CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc_filedesc,
     "Process filedesc entries");
@@ -3964,7 +3920,6 @@ sysctl_kern_proc_cwd(SYSCTL_HANDLER_ARGS)
 
 static SYSCTL_NODE(_kern_proc, KERN_PROC_CWD, cwd, CTLFLAG_RD|CTLFLAG_MPSAFE,
     sysctl_kern_proc_cwd, "Process current working directory");
-#endif /* __rtems__ */
 
 #ifdef DDB
 /*
@@ -4113,13 +4068,10 @@ filelistinit(void *dummy)
 	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
 	mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF);
 }
-#ifndef __rtems__
 SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL);
-#else /* __rtems__ */
-SYSINIT(select_sub_lock, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL);
-#endif /* __rtems__ */
 
 /*-------------------------------------------------------------------*/
+#endif /* __rtems__ */
 
 static int
 badfo_readwrite(struct file *fp, struct uio *uio, struct ucred *active_cred,
diff --git a/freebsd/sys/kern/kern_event.c b/freebsd/sys/kern/kern_event.c
index 1c79ace8..f5682b03 100644
--- a/freebsd/sys/kern/kern_event.c
+++ b/freebsd/sys/kern/kern_event.c
@@ -396,12 +396,7 @@ filt_fileattach(struct knote *kn)
 #ifndef __rtems__
 	return (fo_kqfilter(kn->kn_fp, kn));
 #else /* __rtems__ */
-	if ((kn->kn_status & KN_FP_IS_IOP) == 0) {
-		return (fo_kqfilter(kn->kn_fp, kn));
-	} else {
-		rtems_libio_t* iop = (rtems_libio_t*) kn->kn_fp;
-		return ((*iop->pathinfo.handlers->kqfilter_h)(iop, kn));
-	}
+	return ((*kn->kn_fp->pathinfo.handlers->kqfilter_h)(kn->kn_fp, kn));
 #endif /* __rtems__ */
 }
 
@@ -412,7 +407,7 @@ kqueue_kqfilter(struct file *fp, struct knote *kn)
 #ifndef __rtems__
 	struct kqueue *kq = kn->kn_fp->f_data;
 #else /* __rtems__ */
-	struct kqueue *kq = rtems_bsd_libio_knote_to_kq(kn);
+	struct kqueue *kq = rtems_bsd_knote_to_file(kn);
 #endif /* __rtems__ */
 
 	if (kn->kn_filter != EVFILT_READ)
@@ -431,7 +426,7 @@ filt_kqdetach(struct knote *kn)
 #ifndef __rtems__
 	struct kqueue *kq = kn->kn_fp->f_data;
 #else /* __rtems__ */
-	struct kqueue *kq = rtems_bsd_libio_knote_to_kq(kn);
+	struct kqueue *kq = rtems_bsd_knote_to_file(kn);
 #endif /* __rtems__ */
 
 	knlist_remove(&kq->kq_sel.si_note, kn, 0);
@@ -444,7 +439,7 @@ filt_kqueue(struct knote *kn, long hint)
 #ifndef __rtems__
 	struct kqueue *kq = kn->kn_fp->f_data;
 #else /* __rtems__ */
-	struct kqueue *kq = rtems_bsd_libio_knote_to_kq(kn);
+	struct kqueue *kq = rtems_bsd_knote_to_file(kn);
 #endif /* __rtems__ */
 
 	kn->kn_data = kq->kq_count;
@@ -1041,11 +1036,17 @@ kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
 	kq->kq_cred = crhold(cred);
 
 	FILEDESC_XLOCK(fdp);
+#ifndef __rtems__
 	TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
+#else /* __rtems__ */
+	TAILQ_INSERT_HEAD(&fd_kqlist, kq, kq_list);
+#endif /* __rtems__ */
 	FILEDESC_XUNLOCK(fdp);
 
 	finit(fp, FREAD | FWRITE, DTYPE_KQUEUE, kq, &kqueueops);
+#ifndef __rtems__
 	fdrop(fp, td);
+#endif /* __rtems__ */
 
 	td->td_retval[0] = fd;
 	return (0);
@@ -1425,9 +1426,11 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td,
     int mflag)
 {
 	struct filterops *fops;
+#ifndef __rtems__
 	struct file *fp;
-#ifdef __rtems__
-	rtems_libio_t* iop = NULL;
+#else /* __rtems__ */
+	rtems_libio_t *fp;
+	struct file *bsd_fp;
 #endif /* __rtems__ */
 	struct knote *kn, *tkn;
 	struct knlist *knl;
@@ -1463,22 +1466,26 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td,
 findkn:
 	if (fops->f_isfd) {
 		KASSERT(td != NULL, ("td is NULL"));
+#ifndef __rtems__
 		if (kev->ident > INT_MAX)
 			error = EBADF;
 		else
-#ifndef __rtems__
 			error = fget(td, kev->ident, &cap_event_rights, &fp);
 #else /* __rtems__ */
-		{
-			int ffd = rtems_bsd_libio_iop_hold(kev->ident, &iop);
-			if (ffd < 0)
+		if ((uint32_t)kev->ident < rtems_libio_number_iops) {
+			unsigned int flags;
+
+			fp = rtems_libio_iop((int)kev->ident);
+			flags = rtems_libio_iop_hold(fp);
+
+			if ((flags & LIBIO_FLAGS_OPEN) != 0) {
+				error = 0;
+			} else {
+				rtems_libio_iop_drop(fp);
 				error = EBADF;
-			else {
-				if (iop == NULL)
-					error = fget(td, ffd, &cap_event_rights, &fp);
-				else
-					fp = NULL;
 			}
+		} else {
+			error = EBADF;
 		}
 #endif /* __rtems__ */
 		if (error)
@@ -1486,19 +1493,13 @@ findkn:
 
 		if ((kev->flags & EV_ADD) == EV_ADD && kqueue_expand(kq, fops,
 		    kev->ident, M_NOWAIT) != 0) {
-#ifndef __rtems__
 			/* try again */
+#ifndef __rtems__
 			fdrop(fp, td);
-			fp = NULL;
 #else /* __rtems__ */
-			if (fp != NULL) {
-				fdrop(fp, td);
-				fp = NULL;
-			} else if (iop != NULL) {
-				rtems_libio_iop_drop(iop);
-				iop = NULL;
-			}
+			rtems_libio_iop_drop(fp);
 #endif /* __rtems__ */
+			fp = NULL;
 			error = kqueue_expand(kq, fops, kev->ident, mflag);
 			if (error)
 				goto done;
@@ -1508,7 +1509,8 @@ findkn:
 #ifndef __rtems__
 		if (fp->f_type == DTYPE_KQUEUE) {
 #else /* __rtems__ */
-		if (fp != NULL && fp->f_type == DTYPE_KQUEUE) {
+		bsd_fp = rtems_bsd_iop_to_file(fp);
+		if (bsd_fp != NULL && bsd_fp->f_type == DTYPE_KQUEUE) {
 #endif /* __rtems__ */
 			/*
 			 * If we add some intelligence about what we are doing,
@@ -1517,7 +1519,11 @@ findkn:
 			 * getting both the knlist lock and the kq lock since
 			 * they are the same thing.
 			 */
+#ifndef __rtems__
 			if (fp->f_data == kq) {
+#else /* __rtems__ */
+			if (bsd_fp->f_data == kq) {
+#endif /* __rtems__ */
 				error = EINVAL;
 				goto done;
 			}
@@ -1579,15 +1585,13 @@ findkn:
 		kq->kq_state |= KQ_FLUXWAIT;
 		msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqflxwt", 0);
 		if (fp != NULL) {
+#ifndef __rtems__
 			fdrop(fp, td);
+#else /* __rtems__ */
+			rtems_libio_iop_drop(fp);
+#endif /* __rtems__ */
 			fp = NULL;
 		}
-#ifdef __rtems__
-		if (iop != NULL) {
-			rtems_libio_iop_drop(iop);
-			iop = NULL;
-		}
-#endif /* __rtems__ */
 		goto findkn;
 	}
 
@@ -1603,17 +1607,7 @@ findkn:
 				error = ENOMEM;
 				goto done;
 			}
-#ifndef __rtems__
 			kn->kn_fp = fp;
-#else /* __rtems__ */
-			if (fp != NULL) {
-				kn->kn_fp = fp;
-				kn->kn_status = 0;
-			} else if (iop != NULL) {
-				rtems_bsd_libio_iop_to_knote(kn, iop);
-				kn->kn_status = KN_FP_IS_IOP;
-			}
-#endif /* __rtems__ */
 			kn->kn_kq = kq;
 			kn->kn_fop = fops;
 			/*
@@ -1622,9 +1616,6 @@ findkn:
 			 */
 			fops = NULL;
 			fp = NULL;
-#ifdef __rtems__
-			iop = NULL;
-#endif /* __rtems__ */
 
 			kn->kn_sfflags = kev->fflags;
 			kn->kn_sdata = kev->data;
@@ -1633,11 +1624,7 @@ findkn:
 			kn->kn_kevent = *kev;
 			kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE |
 			    EV_ENABLE | EV_DISABLE | EV_FORCEONESHOT);
-#ifndef __rtems__
 			kn->kn_status = KN_DETACHED;
-#else /* __rtems__ */
-			kn->kn_status |= KN_DETACHED;
-#endif /* __rtems__ */
 			if ((kev->flags & EV_DISABLE) != 0)
 				kn->kn_status |= KN_DISABLED;
 			kn_enter_flux(kn);
@@ -1729,10 +1716,10 @@ done:
 	if (filedesc_unlock)
 		FILEDESC_XUNLOCK(td->td_proc->p_fd);
 	if (fp != NULL)
+#ifndef __rtems__
 		fdrop(fp, td);
-#ifdef __rtems__
-	if (iop != NULL)
-		rtems_libio_iop_drop(iop);
+#else /* __rtems__ */
+		rtems_libio_iop_drop(fp);
 #endif /* __rtems__ */
 	knote_free(tkn);
 	if (fops != NULL)
@@ -2269,7 +2256,9 @@ static int
 kqueue_close(struct file *fp, struct thread *td)
 {
 	struct kqueue *kq = fp->f_data;
+#ifndef __rtems__
 	struct filedesc *fdp;
+#endif /* __rtems__ */
 	int error;
 	int filedesc_unlock;
 
@@ -2277,6 +2266,7 @@ kqueue_close(struct file *fp, struct thread *td)
 		return error;
 	kqueue_drain(kq, td);
 
+#ifndef __rtems__
 	/*
 	 * We could be called due to the knote_drop() doing fdrop(),
 	 * called from kqueue_register().  In this case the global
@@ -2293,6 +2283,12 @@ kqueue_close(struct file *fp, struct thread *td)
 	TAILQ_REMOVE(&fdp->fd_kqlist, kq, kq_list);
 	if (filedesc_unlock)
 		FILEDESC_XUNLOCK(fdp);
+#else /* __rtems__ */
+	(void)filedesc_unlock;
+	rtems_libio_lock();
+	TAILQ_REMOVE(&fd_kqlist, kq, kq_list);
+	rtems_libio_unlock();
+#endif /* __rtems__ */
 
 	kqueue_destroy(kq);
 	chgkqcnt(kq->kq_cred->cr_ruidinfo, -1, 0);
@@ -2674,18 +2670,26 @@ again:		/* need to reacquire lock since we have dropped it */
 void
 knote_fdclose(struct thread *td, int fd)
 {
+#ifndef __rtems__
 	struct filedesc *fdp = td->td_proc->p_fd;
+#endif /* __rtems__ */
 	struct kqueue *kq;
 	struct knote *kn;
 	int influx;
 
+#ifndef __rtems__
 	FILEDESC_XLOCK_ASSERT(fdp);
+#endif /* __rtems__ */
 
 	/*
 	 * We shouldn't have to worry about new kevents appearing on fd
 	 * since filedesc is locked.
 	 */
+#ifndef __rtems__
 	TAILQ_FOREACH(kq, &fdp->fd_kqlist, kq_list) {
+#else /* __rtems__ */
+	TAILQ_FOREACH(kq, &fd_kqlist, kq_list) {
+#endif /* __rtems__ */
 		KQ_LOCK(kq);
 
 again:
@@ -2773,10 +2777,7 @@ knote_drop_detached(struct knote *kn, struct thread *td)
 #ifndef __rtems__
 		fdrop(kn->kn_fp, td);
 #else /* __rtems__ */
-		if ((kn->kn_status & KN_FP_IS_IOP) == 0)
-		fdrop(kn->kn_fp, td);
-		else
-			rtems_libio_iop_drop((rtems_libio_t*) kn->kn_fp);
+		rtems_libio_iop_drop(kn->kn_fp);
 #endif /* __rtems__ */
 		kn->kn_fp = NULL;
 	}
diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c
index 827380ce..1e5351a7 100644
--- a/freebsd/sys/kern/sys_generic.c
+++ b/freebsd/sys/kern/sys_generic.c
@@ -805,12 +805,14 @@ kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data)
 	}
 
 	switch (com) {
+#ifndef __rtems__
 	case FIONCLEX:
 		fdp->fd_ofiles[fd].fde_flags &= ~UF_EXCLOSE;
 		goto out;
 	case FIOCLEX:
 		fdp->fd_ofiles[fd].fde_flags |= UF_EXCLOSE;
 		goto out;
+#endif /* __rtems__ */
 	case FIONBIO:
 		if ((tmp = *(int *)data))
 			atomic_set_int(&fp->f_flag, FNONBLOCK);
@@ -1236,23 +1238,73 @@ selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events)
 	return (n);
 }
 
+#ifndef __rtems__
 static __inline int
 getselfd_cap(struct filedesc *fdp, int fd, struct file **fpp)
 {
-#ifdef __rtems__
+
+	return (fget_unlocked(fdp, fd, &cap_event_rights, fpp, NULL));
+}
+#else /* __rtems__ */
+static int
+getselfd_cap(struct filedesc *fdp, int fd, rtems_libio_t **fpp)
+{
 	rtems_libio_t *iop;
-	int ffd = rtems_bsd_libio_iop_hold(fd, &iop);
-	if (ffd < 0)
-		return EBADF;
-	if (iop != NULL) {
-		*fpp = NULL;
-		return 0;
+	unsigned int actual_flags;
+
+	(void)fdp;
+
+	if ((uint32_t)fd >= rtems_libio_number_iops) {
+		return (EBADF);
 	}
-	fd = ffd;
-#endif /* __rtems__ */
 
-	return (fget_unlocked(fdp, fd, &cap_event_rights, fpp, NULL));
+	iop = rtems_libio_iop(fd);
+	actual_flags = rtems_libio_iop_hold(iop);
+
+	if ((actual_flags & LIBIO_FLAGS_OPEN) != LIBIO_FLAGS_OPEN) {
+		rtems_libio_iop_drop(iop);
+		return (EBADF);
+	}
+
+	*fpp = iop;
+	return (0);
+}
+
+static inline rtems_libio_t *
+rtems_bsd_get_file_for_poll(int fd)
+{
+	rtems_libio_t *iop;
+	unsigned int actual_flags;
+
+	if ((uint32_t)fd >= rtems_libio_number_iops) {
+		return (NULL);
+	}
+
+	iop = rtems_libio_iop(fd);
+	actual_flags = rtems_libio_iop_hold(iop);
+
+	if ((actual_flags & LIBIO_FLAGS_OPEN) != LIBIO_FLAGS_OPEN) {
+		rtems_libio_iop_drop(iop);
+		return (NULL);
+	}
+
+	return (iop);
+}
+
+static inline int
+rtems_bsd_fo_poll(rtems_libio_t *iop, int events, struct ucred *active_cred,
+    struct thread *td)
+{
+	int error;
+
+	(void)active_cred;
+	(void)td;
+
+	error = ((*iop->pathinfo.handlers->poll_h)(iop, events));
+	rtems_libio_iop_drop(iop);
+	return (error);
 }
+#endif /* __rtems__ */
 
 /*
  * Traverse the list of fds attached to this thread's seltd and check for
@@ -1266,7 +1318,11 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
 	struct seltd *stp;
 	struct selfd *sfp;
 	struct selfd *sfn;
+#ifndef __rtems__
 	struct file *fp;
+#else /* __rtems__ */
+	rtems_libio_t *fp;
+#endif /* __rtems__ */
 	fd_mask bit;
 	int fd, ev, n, idx;
 	int error;
@@ -1290,10 +1346,8 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
 		ev = fo_poll(fp, selflags(ibits, idx, bit), td->td_ucred, td);
 		fdrop(fp, td);
 #else /* __rtems__ */
-		ev = rtems_bsd_libio_fo_poll(fd, fp, selflags(ibits, idx, bit),
-					     td->td_ucred, td);
-		if (fp != NULL)
-			fdrop(fp, td);
+		ev = rtems_bsd_fo_poll(fp, selflags(ibits, idx, bit),
+		    td->td_ucred, td);
 #endif /* __rtems__ */
 		if (ev != 0)
 			n += selsetbits(ibits, obits, idx, bit, ev);
@@ -1311,7 +1365,11 @@ static int
 selscan(struct thread *td, fd_mask **ibits, fd_mask **obits, int nfd)
 {
 	struct filedesc *fdp;
+#ifndef __rtems__
 	struct file *fp;
+#else /* __rtems__ */
+	rtems_libio_t *fp;
+#endif /* __rtems__ */
 	fd_mask bit;
 	int ev, flags, end, fd;
 	int n, idx;
@@ -1334,11 +1392,8 @@ selscan(struct thread *td, fd_mask **ibits, fd_mask **obits, int nfd)
 			ev = fo_poll(fp, flags, td->td_ucred, td);
 			fdrop(fp, td);
 #else /* __rtems__ */
-			ev = rtems_bsd_libio_fo_poll(fd, fp,
-						     selflags(ibits, idx, bit),
-						     td->td_ucred, td);
-			if (fp != NULL)
-				fdrop(fp, td);
+			ev = rtems_bsd_fo_poll(fp, flags, td->td_ucred,
+			    td);
 #endif /* __rtems__ */
 			if (ev != 0)
 				n += selsetbits(ibits, obits, idx, bit, ev);
@@ -1507,7 +1562,11 @@ pollrescan(struct thread *td)
 	struct selfd *sfn;
 	struct selinfo *si;
 	struct filedesc *fdp;
+#ifndef __rtems__
 	struct file *fp;
+#else /* __rtems__ */
+	rtems_libio_t *fp;
+#endif /* __rtems__ */
 	struct pollfd *fd;
 	int n;
 
@@ -1524,24 +1583,15 @@ pollrescan(struct thread *td)
 			continue;
 #ifndef __rtems__
 		fp = fdp->fd_ofiles[fd->fd].fde_file;
+#else /* __rtems__ */
+		fp = rtems_bsd_get_file_for_poll(fd->fd);
+#endif /* __rtems__ */
 #ifdef CAPABILITIES
 		if (fp == NULL ||
 		    cap_check(cap_rights(fdp, fd->fd), &cap_event_rights) != 0)
 #else
 		if (fp == NULL)
 #endif
-#else /* __rtems__ */
-		rtems_libio_t* iop;
-		int ffd = rtems_bsd_libio_iop_hold(fd->fd, &iop);
-		if (ffd >= 0) {
-			if (iop == NULL) {
-				fp = fdp->fd_ofiles[ffd].fde_file;
-			} else {
-				fp = NULL;
-			}
-		}
-		else
-#endif /* __rtems__ */
 		{
 			fd->revents = POLLNVAL;
 			n++;
@@ -1555,7 +1605,8 @@ pollrescan(struct thread *td)
 #ifndef __rtems__
 		fd->revents = fo_poll(fp, fd->events, td->td_ucred, td);
 #else /* __rtems__ */
-		fd->revents = rtems_bsd_libio_fo_poll(ffd, fp, fd->events, td->td_ucred, td);
+		fd->revents = rtems_bsd_fo_poll(fp, fd->events, td->td_ucred,
+		    td);
 #endif /* __rtems__ */
 		if (fd->revents != 0)
 			n++;
@@ -1592,7 +1643,11 @@ static int
 pollscan(struct thread *td, struct pollfd *fds, u_int nfd)
 {
 	struct filedesc *fdp = td->td_proc->p_fd;
+#ifndef __rtems__
 	struct file *fp;
+#else /* __rtems__ */
+        rtems_libio_t *fp;
+#endif /* __rtems__ */
 	int i, n = 0;
 
 	FILEDESC_SLOCK(fdp);
@@ -1609,24 +1664,15 @@ pollscan(struct thread *td, struct pollfd *fds, u_int nfd)
 		} else {
 #ifndef __rtems__
 			fp = fdp->fd_ofiles[fds->fd].fde_file;
+#else /* __rtems__ */
+			fp = rtems_bsd_get_file_for_poll(fds->fd);
+#endif /* __rtems__ */
 #ifdef CAPABILITIES
 			if (fp == NULL ||
 			    cap_check(cap_rights(fdp, fds->fd), &cap_event_rights) != 0)
 #else
 			if (fp == NULL)
 #endif
-#else /* __rtems__ */
-			rtems_libio_t* iop;
-			int ffd = rtems_bsd_libio_iop_hold(fds->fd, &iop);
-			if (ffd >= 0) {
-				if (iop == NULL) {
-					fp = fdp->fd_ofiles[ffd].fde_file;
-				} else {
-					fp = NULL;
-				}
-			}
-			if (ffd < 0)
-#endif /* __rtems__ */
 			{
 				fds->revents = POLLNVAL;
 				n++;
@@ -1640,7 +1686,7 @@ pollscan(struct thread *td, struct pollfd *fds, u_int nfd)
 				fds->revents = fo_poll(fp, fds->events,
 				    td->td_ucred, td);
 #else /* __rtems__ */
-				fds->revents = rtems_bsd_libio_fo_poll(ffd, fp, fds->events,
+				fds->revents = rtems_bsd_fo_poll(fp, fds->events,
 				    td->td_ucred, td);
 #endif /* __rtems__ */
 				/*
diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c
index 60f9a69d..9c05a228 100644
--- a/freebsd/sys/kern/uipc_socket.c
+++ b/freebsd/sys/kern/uipc_socket.c
@@ -3384,7 +3384,11 @@ sopoll_generic(struct socket *so, int events, struct ucred *active_cred,
 int
 soo_kqfilter(struct file *fp, struct knote *kn)
 {
+#ifndef __rtems__
 	struct socket *so = kn->kn_fp->f_data;
+#else /* __rtems__ */
+	struct socket *so = rtems_bsd_knote_to_file(kn)->f_data;
+#endif /* __rtems__ */
 	struct sockbuf *sb;
 	struct knlist *knl;
 
@@ -3594,7 +3598,11 @@ pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred,
 static void
 filt_sordetach(struct knote *kn)
 {
+#ifndef __rtems__
 	struct socket *so = kn->kn_fp->f_data;
+#else /* __rtems__ */
+	struct socket *so = rtems_bsd_knote_to_file(kn)->f_data;
+#endif /* __rtems__ */
 
 	so_rdknl_lock(so);
 	knlist_remove(&so->so_rdsel.si_note, kn, 1);
@@ -3609,7 +3617,11 @@ filt_soread(struct knote *kn, long hint)
 {
 	struct socket *so;
 
+#ifndef __rtems__
 	so = kn->kn_fp->f_data;
+#else /* __rtems__ */
+	so = rtems_bsd_knote_to_file(kn)->f_data;
+#endif /* __rtems__ */
 
 	if (SOLISTENING(so)) {
 		SOCK_LOCK_ASSERT(so);
@@ -3645,7 +3657,11 @@ filt_soread(struct knote *kn, long hint)
 static void
 filt_sowdetach(struct knote *kn)
 {
+#ifndef __rtems__
 	struct socket *so = kn->kn_fp->f_data;
+#else /* __rtems__ */
+	struct socket *so = rtems_bsd_knote_to_file(kn)->f_data;
+#endif /* __rtems__ */
 
 	so_wrknl_lock(so);
 	knlist_remove(&so->so_wrsel.si_note, kn, 1);
@@ -3660,7 +3676,11 @@ filt_sowrite(struct knote *kn, long hint)
 {
 	struct socket *so;
 
+#ifndef __rtems__
 	so = kn->kn_fp->f_data;
+#else /* __rtems__ */
+	so = rtems_bsd_knote_to_file(kn)->f_data;
+#endif /* __rtems__ */
 
 	if (SOLISTENING(so))
 		return (0);
@@ -3690,7 +3710,11 @@ filt_soempty(struct knote *kn, long hint)
 {
 	struct socket *so;
 
+#ifndef __rtems__
 	so = kn->kn_fp->f_data;
+#else /* __rtems__ */
+	so = rtems_bsd_knote_to_file(kn)->f_data;
+#endif /* __rtems__ */
 
 	if (SOLISTENING(so))
 		return (1);
diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c
index a2f7d6f8..50413091 100644
--- a/freebsd/sys/kern/uipc_syscalls.c
+++ b/freebsd/sys/kern/uipc_syscalls.c
@@ -113,6 +113,7 @@ getsockaddr_noalloc(struct sockaddr **namp, const struct sockaddr *uaddr, size_t
 #endif /* __rtems__ */
 static int sockargs(struct mbuf **, char *, socklen_t, int);
 
+#ifndef __rtems__
 /*
  * Convert a user file descriptor to a kernel file entry and check if required
  * capability rights are present.
@@ -140,6 +141,7 @@ getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
 	*fpp = fp;
 	return (0);
 }
+#endif /* __rtems__ */
 
 /*
  * System call interface to the socket abstraction.
@@ -193,7 +195,9 @@ kern_socket(struct thread *td, int domain, int type, int protocol)
 			(void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td);
 		td->td_retval[0] = fd;
 	}
+#ifndef __rtems__
 	fdrop(fp, td);
+#endif /* __rtems__ */
 	return (error);
 }
 
@@ -349,7 +353,9 @@ accept1(td, s, uname, anamelen, flags)
 		    sizeof(namelen));
 	if (error != 0)
 		fdclose(td, fp, td->td_retval[0]);
+#ifndef __rtems__
 	fdrop(fp, td);
+#endif /* __rtems__ */
 	free(name, M_SONAME);
 	return (error);
 }
@@ -472,8 +478,10 @@ done:
 		} else
 			*fp = NULL;
 	}
+#ifndef __rtems__
 	if (nfp != NULL)
 		fdrop(nfp, td);
+#endif /* __rtems__ */
 	fdrop(headfp, td);
 	return (error);
 }
@@ -692,15 +700,21 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol,
 		(void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
 		(void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
 	}
+#ifndef __rtems__
 	fdrop(fp1, td);
 	fdrop(fp2, td);
+#endif /* __rtems__ */
 	return (0);
 free4:
 	fdclose(td, fp2, rsv[1]);
+#ifndef __rtems__
 	fdrop(fp2, td);
+#endif /* __rtems__ */
 free3:
 	fdclose(td, fp1, rsv[0]);
+#ifndef __rtems__
 	fdrop(fp1, td);
+#endif /* __rtems__ */
 free2:
 	if (so2 != NULL)
 		(void)soclose(so2);
@@ -1712,6 +1726,7 @@ getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len)
 void
 m_dispose_extcontrolm(struct mbuf *m)
 {
+#ifndef __rtems__
 	struct cmsghdr *cm;
 	struct file *fp;
 	struct thread *td;
@@ -1752,4 +1767,5 @@ m_dispose_extcontrolm(struct mbuf *m)
 		}
 		m_chtype(m, MT_CONTROL);
 	}
+#endif /* __rtems__ */
 }
diff --git a/freebsd/sys/kern/vfs_cache.c b/freebsd/sys/kern/vfs_cache.c
index 7ae1de1d..3faf6188 100644
--- a/freebsd/sys/kern/vfs_cache.c
+++ b/freebsd/sys/kern/vfs_cache.c
@@ -2146,6 +2146,7 @@ static int __read_mostly disablecwd;
 SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0,
    "Disable the getcwd syscall");
 
+#ifndef __rtems__
 /* Implementation of the getcwd syscall. */
 int
 sys___getcwd(struct thread *td, struct __getcwd_args *uap)
@@ -2196,6 +2197,7 @@ kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen,
 	free(tmpbuf, M_TEMP);
 	return (error);
 }
+#endif /* __rtems__ */
 
 /*
  * Thus begins the fullpath magic.
diff --git a/freebsd/sys/kern/vfs_lookup.c b/freebsd/sys/kern/vfs_lookup.c
index 656ec51d..83b9f713 100644
--- a/freebsd/sys/kern/vfs_lookup.c
+++ b/freebsd/sys/kern/vfs_lookup.c
@@ -381,7 +381,9 @@ namei(struct nameidata *ndp)
 	FILEDESC_SLOCK(fdp);
 	ndp->ni_rootdir = fdp->fd_rdir;
 	vrefact(ndp->ni_rootdir);
+#ifndef __rtems__
 	ndp->ni_topdir = fdp->fd_jdir;
+#endif /* __rtems__ */
 
 	/*
 	 * If we are auditing the kernel pathname, save the user pathname.
@@ -837,7 +839,9 @@ dirloop:
 			pr = NULL;
 #endif /* __rtems__ */
 			if (dp == ndp->ni_rootdir || 
+#ifndef __rtems__
 			    dp == ndp->ni_topdir || 
+#endif /* __rtems__ */
 			    dp == rootvnode ||
 			    pr != NULL ||
 			    ((dp->v_vflag & VV_ROOT) != 0 &&
diff --git a/freebsd/sys/kern/vfs_mount.c b/freebsd/sys/kern/vfs_mount.c
index 4635857e..2e122a98 100644
--- a/freebsd/sys/kern/vfs_mount.c
+++ b/freebsd/sys/kern/vfs_mount.c
@@ -950,7 +950,9 @@ vfs_domount_first(
 	VOP_UNLOCK(vp, 0);
 	EVENTHANDLER_DIRECT_INVOKE(vfs_mounted, mp, newdp, td);
 	VOP_UNLOCK(newdp, 0);
+#ifndef __rtems__
 	mountcheckdirs(vp, newdp);
+#endif /* __rtems__ */
 	vrele(newdp);
 	if ((mp->mnt_flag & MNT_RDONLY) == 0)
 		vfs_allocate_syncvnode(mp);
diff --git a/freebsd/sys/kern/vfs_subr.c b/freebsd/sys/kern/vfs_subr.c
index bc38e770..5f4d09da 100644
--- a/freebsd/sys/kern/vfs_subr.c
+++ b/freebsd/sys/kern/vfs_subr.c
@@ -5365,7 +5365,11 @@ filt_vfsread(struct knote *kn, long hint)
 		return (0);
 
 	VI_LOCK(vp);
+#ifndef __rtems__
 	kn->kn_data = va.va_size - kn->kn_fp->f_offset;
+#else /* __rtems__ */
+	kn->kn_data = va.va_size - rtems_bsd_knote_to_file(kn)->f_offset;
+#endif /* __rtems__ */
 	res = (kn->kn_sfflags & NOTE_FILE_POLL) != 0 || kn->kn_data != 0;
 	VI_UNLOCK(vp);
 	return (res);
diff --git a/freebsd/sys/kern/vfs_syscalls.c b/freebsd/sys/kern/vfs_syscalls.c
index 0b7e054a..7e8e29e4 100644
--- a/freebsd/sys/kern/vfs_syscalls.c
+++ b/freebsd/sys/kern/vfs_syscalls.c
@@ -1050,12 +1050,19 @@ sys_openat(struct thread *td, struct openat_args *uap)
 }
 
 int
+#ifndef __rtems__
 kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
     int flags, int mode)
+#else /* __rtems__ */
+kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
+    int flags, int mode, struct file *fp)
+#endif /* __rtems__ */
 {
 	struct proc *p = td->td_proc;
 	struct filedesc *fdp = p->p_fd;
+#ifndef __rtems__
 	struct file *fp;
+#endif /* __rtems__ */
 	struct vnode *vp;
 	struct nameidata nd;
 	cap_rights_t rights;
@@ -1088,9 +1095,14 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
 	 * Allocate a file structure. The descriptor to reference it
 	 * is allocated and set by finstall() below.
 	 */
+#ifndef __rtems__
 	error = falloc_noinstall(td, &fp);
 	if (error != 0)
 		return (error);
+#else /* __rtems__ */
+	rtems_libio_iop_hold(fp->f_io);
+	error = 0;
+#endif /* __rtems__ */
 	/*
 	 * An extra reference on `fp' has been held for us by
 	 * falloc_noinstall().
@@ -1164,12 +1176,15 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
 	}
 
 	VOP_UNLOCK(vp, 0);
+#ifndef __rtems__
 	if (flags & O_TRUNC) {
 		error = fo_truncate(fp, 0, td->td_ucred, td);
 		if (error != 0)
 			goto bad;
 	}
+#endif /* __rtems__ */
 success:
+#ifndef __rtems__
 	/*
 	 * If we haven't already installed the FD (for dupfdopen), do so now.
 	 */
@@ -1191,6 +1206,7 @@ success:
 	} else {
 		filecaps_free(&nd.ni_filecaps);
 	}
+#endif /* __rtems__ */
 
 	/*
 	 * Release our private reference, leaving the one associated with
@@ -4372,6 +4388,7 @@ sys_fhreadlink(struct thread *td, struct fhreadlink_args *uap)
 	return (error);
 }
 
+#ifndef __rtems__
 /*
  * syscall for the rpc.lockd to use to translate a NFS file handle into an
  * open descriptor.
@@ -4459,6 +4476,7 @@ bad:
 	td->td_retval[0] = indx;
 	return (error);
 }
+#endif /* __rtems__ */
 
 /*
  * Stat an (NFS) file handle.
diff --git a/freebsd/sys/opencrypto/cryptodev.c b/freebsd/sys/opencrypto/cryptodev.c
index 71872532..97459559 100644
--- a/freebsd/sys/opencrypto/cryptodev.c
+++ b/freebsd/sys/opencrypto/cryptodev.c
@@ -1513,17 +1513,10 @@ cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread
 		}
 		/* falloc automatically provides an extra reference to 'f'. */
 		finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops);
-#ifdef __rtems__
-		fd = rtems_bsd_libio_iop_allocate_with_file(td, fd, &rtems_bsd_sysgen_nodeops);
-		if (fd < 0) {
-			fdclose(td, f, fd);
-			mtx_destroy(&fcr->lock);
-			free(fcr, M_XDATA);
-			return (error);
-		}
-#endif /* __rtems__ */
 		*(u_int32_t *)data = fd;
+#ifndef __rtems__
 		fdrop(f, td);
+#endif /* __rtems__ */
 		break;
 	case CRIOFINDDEV:
 		error = cryptodev_find((struct crypt_find_op *)data);
diff --git a/freebsd/sys/sys/file.h b/freebsd/sys/sys/file.h
index d48ca0e9..68c33299 100644
--- a/freebsd/sys/sys/file.h
+++ b/freebsd/sys/sys/file.h
@@ -247,6 +247,7 @@ extern int maxfiles;		/* kernel limit on number of open files */
 extern int maxfilesperproc;	/* per process limit on number of open files */
 extern volatile int openfiles;	/* actual number of open files */
 
+#ifndef __rtems__
 int fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp);
 int fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp,
     u_char *maxprotp, struct file **fpp);
@@ -257,6 +258,51 @@ int fget_write(struct thread *td, int fd, cap_rights_t *rightsp,
 int fget_fcntl(struct thread *td, int fd, cap_rights_t *rightsp,
     int needfcntl, struct file **fpp);
 int _fdrop(struct file *fp, struct thread *td);
+#else /* __rtems__ */
+int rtems_bsd_fget(int fd, struct file **fpp, int flags);
+
+static inline int
+fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
+{
+	struct file *fp;
+
+	(void)td;
+	(void)rightsp;
+	return (rtems_bsd_fget(fd, fpp, LIBIO_FLAGS_OPEN));
+}
+
+static inline int
+fget_read(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
+{
+	struct file *fp;
+
+	(void)td;
+	(void)rightsp;
+	return (rtems_bsd_fget(fd, fpp, LIBIO_FLAGS_OPEN | LIBIO_FLAGS_READ));
+}
+
+static inline int
+fget_write(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
+{
+	struct file *fp;
+
+	(void)td;
+	(void)rightsp;
+	return (rtems_bsd_fget(fd, fpp, LIBIO_FLAGS_OPEN | LIBIO_FLAGS_WRITE));
+}
+
+static inline int
+fget_fcntl(struct thread *td, int fd, cap_rights_t *rightsp, int needfcntl,
+    struct file **fpp)
+{
+	struct file *fp;
+
+	(void)td;
+	(void)needfcntl;
+	(void)rightsp;
+	return (rtems_bsd_fget(fd, fpp, LIBIO_FLAGS_OPEN));
+}
+#endif /* __rtems__ */
 
 fo_rdwr_t	invfo_rdwr;
 fo_truncate_t	invfo_truncate;
@@ -274,7 +320,36 @@ fo_fill_kinfo_t	vn_fill_kinfo;
 int vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif);
 #endif /* __rtems__ */
 
+#ifndef __rtems__
 void finit(struct file *, u_int, short, void *, struct fileops *);
+#else /* __rtems__ */
+static inline void
+finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops)
+{
+	uint32_t libio_flags;
+
+	fp->f_data = data;
+	fp->f_flag = flag;
+	fp->f_type = type;
+	fp->f_ops = ops;
+
+	libio_flags = LIBIO_FLAGS_OPEN;
+
+	if ((flag & FREAD) == FREAD) {
+		libio_flags |= LIBIO_FLAGS_READ;
+	}
+
+	if ((flag & FWRITE) == FWRITE) {
+		libio_flags |= LIBIO_FLAGS_WRITE;
+	}
+
+	if ((flag & FNONBLOCK) == FNONBLOCK) {
+		libio_flags |= LIBIO_FLAGS_NO_DELAY;
+	}
+
+        rtems_libio_iop_flags_set(fp->f_io, libio_flags);
+}
+#endif /* __rtems__ */
 int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp,
     struct vnode **vpp);
 int fgetvp_exec(struct thread *td, int fd, cap_rights_t *rightsp,
@@ -286,6 +361,7 @@ int fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp,
 int fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp,
     struct vnode **vpp);
 
+#ifndef __rtems__
 static __inline int
 _fnoop(void)
 {
@@ -299,23 +375,19 @@ fhold(struct file *fp)
 	return (refcount_acquire_checked(&fp->f_count));
 }
 
-#ifndef __rtems__
 #define	fdrop(fp, td)							\
 	(refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop())
 #else /* __rtems__ */
-static inline int fdrop(struct file *fp, struct thread *td)
+/*
+ * Must not be called after falloc_caps().  The file reference counting in
+ * RTEMS and FreeBSD work slightly different.
+ */
+static inline void
+fdrop(struct file *fp, struct thread *td)
 {
-	if (fp->f_io != NULL) {
-		if (RTEMS_BSD_DESCRIP_TRACE)
-		  printf("bsd:  fb: fdrop: iop=%p %d (%d) fp=%p (%d) by %p\n",
-			 fp->f_io, fp->f_io->data0, fp->f_io->flags >> 12,
-			 fp, fp->f_count, __builtin_return_address(0));
-		rtems_libio_iop_drop(fp->f_io);
-	} else if (RTEMS_BSD_DESCRIP_TRACE) {
-		printf("bsd:  fb: fdrop: %d %p %d by %p\n",
-		       -1, fp, fp->f_count, __builtin_return_address(0));
-	}
-	return (refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop());
+
+	(void)td;
+	rtems_libio_iop_drop(fp->f_io);
 }
 #endif /* __rtems__ */
 
diff --git a/freebsd/sys/sys/filedesc.h b/freebsd/sys/sys/filedesc.h
index dc132677..634470fb 100644
--- a/freebsd/sys/sys/filedesc.h
+++ b/freebsd/sys/sys/filedesc.h
@@ -77,20 +77,26 @@ struct fdescenttbl {
 #define NDSLOTTYPE	u_long
 
 struct filedesc {
+#ifndef __rtems__
 	struct	fdescenttbl *fd_files;	/* open files table */
+#endif /* __rtems__ */
 	struct	vnode *fd_cdir;		/* current directory */
 	struct	vnode *fd_rdir;		/* root directory */
+#ifndef __rtems__
 	struct	vnode *fd_jdir;		/* jail root directory */
 	NDSLOTTYPE *fd_map;		/* bitmap of free fds */
 	int	fd_lastfile;		/* high-water mark of fd_ofiles */
 	int	fd_freefile;		/* approx. next free file */
+#endif /* __rtems__ */
 	u_short	fd_cmask;		/* mask for file creation */
+#ifndef __rtems__
 	int	fd_refcnt;		/* thread reference count */
 	int	fd_holdcnt;		/* hold count on structure + mutex */
 	struct	sx fd_sx;		/* protects members of this struct */
 	struct	kqlist fd_kqlist;	/* list of kqueues on this filedesc */
 	int	fd_holdleaderscount;	/* block fdfree() for shared close() */
 	int	fd_holdleaderswakeup;	/* fdfree() needs wakeup */
+#endif /* __rtems__ */
 };
 
 /*
@@ -102,6 +108,7 @@ struct filedesc {
  *
  * fdl_refcount and fdl_holdcount are protected by struct filedesc mtx.
  */
+#ifndef __rtems__
 struct filedesc_to_leader {
 	int		fdl_refcount;	/* references from struct proc */
 	int		fdl_holdcount;	/* temporary hold during closef */
@@ -113,6 +120,9 @@ struct filedesc_to_leader {
 };
 #define	fd_nfiles	fd_files->fdt_nfiles
 #define	fd_ofiles	fd_files->fdt_ofiles
+#else /* __rtems__ */
+struct filedesc_to_leader;
+#endif /* __rtems__ */
 
 /*
  * Per-process open flags.
@@ -120,15 +130,26 @@ struct filedesc_to_leader {
 #define	UF_EXCLOSE	0x01		/* auto-close on exec */
 
 #ifdef _KERNEL
+#ifdef __rtems__
+#include <sys/file.h>
+#include <rtems/libio_.h>
+#endif /* __rtems__ */
 
 /* Lock a file descriptor table. */
 #define	FILEDESC_LOCK_INIT(fdp)	sx_init(&(fdp)->fd_sx, "filedesc structure")
 #define	FILEDESC_LOCK_DESTROY(fdp)	sx_destroy(&(fdp)->fd_sx)
 #define	FILEDESC_LOCK(fdp)	(&(fdp)->fd_sx)
+#ifndef __rtems__
 #define	FILEDESC_XLOCK(fdp)	sx_xlock(&(fdp)->fd_sx)
 #define	FILEDESC_XUNLOCK(fdp)	sx_xunlock(&(fdp)->fd_sx)
 #define	FILEDESC_SLOCK(fdp)	sx_slock(&(fdp)->fd_sx)
 #define	FILEDESC_SUNLOCK(fdp)	sx_sunlock(&(fdp)->fd_sx)
+#else /* __rtems__ */
+#define	FILEDESC_XLOCK(fdp)	rtems_libio_lock()
+#define	FILEDESC_XUNLOCK(fdp)	rtems_libio_unlock()
+#define	FILEDESC_SLOCK(fdp)	rtems_libio_lock()
+#define	FILEDESC_SUNLOCK(fdp)	rtems_libio_unlock()
+#endif /* __rtems__ */
 
 #define	FILEDESC_LOCK_ASSERT(fdp)	sx_assert(&(fdp)->fd_sx, SX_LOCKED | \
 					    SX_NOTRECURSED)
@@ -154,17 +175,42 @@ enum {
 
 struct thread;
 
-void	filecaps_init(struct filecaps *fcaps);
+static __inline void
+filecaps_init(struct filecaps *fcaps)
+{
+
+        bzero(fcaps, sizeof(*fcaps));
+        fcaps->fc_nioctls = -1;
+}
 bool	filecaps_copy(const struct filecaps *src, struct filecaps *dst,
 	    bool locked);
 void	filecaps_move(struct filecaps *src, struct filecaps *dst);
+#ifndef __rtems__
 void	filecaps_free(struct filecaps *fcaps);
+#else /* __rtems__ */
+#define	filecaps_free(fcaps) do { } while (0)
+#endif /* __rtems__ */
 
 int	closef(struct file *fp, struct thread *td);
 int	dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
 	    int openerror, int *indxp);
+#ifndef __rtems__
 int	falloc_caps(struct thread *td, struct file **resultfp, int *resultfd,
 	    int flags, struct filecaps *fcaps);
+#else /* __rtems__ */
+int rtems_bsd_falloc(struct file **resultfp, int *resultfd);
+
+static inline int
+falloc_caps(struct thread *td, struct file **resultfp, int *resultfd,
+    int flags, struct filecaps *fcaps)
+{
+
+	(void)td;
+	(void)flags;
+	(void)fcaps;
+	return (rtems_bsd_falloc(resultfp, resultfd));
+}
+#endif /* __rtems__ */
 int	falloc_noinstall(struct thread *td, struct file **resultfp);
 void	_finstall(struct filedesc *fdp, struct file *fp, int fd, int flags,
 	    struct filecaps *fcaps);
@@ -173,7 +219,20 @@ int	finstall(struct thread *td, struct file *fp, int *resultfd, int flags,
 int	fdalloc(struct thread *td, int minfd, int *result);
 int	fdallocn(struct thread *td, int minfd, int *fds, int n);
 int	fdcheckstd(struct thread *td);
+#ifndef __rtems__
 void	fdclose(struct thread *td, struct file *fp, int idx);
+#else /* __rtems__ */
+void rtems_bsd_fdclose(struct file *fp);
+
+static inline void
+fdclose(struct thread *td, struct file *fp, int idx)
+{
+
+	(void)td;
+	(void)idx;
+	rtems_bsd_fdclose(fp);
+}
+#endif /* __rtems__ */
 void	fdcloseexec(struct thread *td);
 void	fdsetugidsafety(struct thread *td);
 struct	filedesc *fdcopy(struct filedesc *fdp);
@@ -192,6 +251,7 @@ int	getvnode(struct thread *td, int fd, cap_rights_t *rightsp,
 	    struct file **fpp);
 void	mountcheckdirs(struct vnode *olddp, struct vnode *newdp);
 
+#ifndef __rtems__
 int	fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 	    struct file **fpp, struct filecaps *havecapsp);
 int	fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
@@ -245,7 +305,32 @@ void	pwd_chdir(struct thread *td, struct vnode *vp);
 int	pwd_chroot(struct thread *td, struct vnode *vp);
 void	pwd_ensure_dirs(void);
 
-#ifdef __rtems__
+#else /* __rtems__ */
+static inline int
+fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
+    struct file **fpp, struct filecaps *havecapsp)
+{
+
+	(void)td;
+	(void)needrightsp;
+	(void)havecapsp;
+	return (rtems_bsd_fget(fd, fpp, LIBIO_FLAGS_OPEN));
+}
+
+#define	fget_cap_locked(fdp, fd, needrightsp, fpp, havecapsp) \
+    fget_cap(NULL, fd, needrightsp, fpp, havecapsp)
+
+static inline int
+rtems_bsd_fget_unlocked(int fd, struct file **fpp, seq_t *seqp)
+{
+
+	(void)seqp;
+	return (rtems_bsd_fget(fd, fpp, LIBIO_FLAGS_OPEN));
+}
+
+#define	fget_unlocked(fdp, fd, needrightsp, fpp, seqp) \
+    rtems_bsd_fget_unlocked(fd, fpp, seqp)
+
 #include <machine/rtems-bsd-libio.h>
 #endif /* __rtems__ */
 #endif /* _KERNEL */
diff --git a/freebsd/sys/sys/namei.h b/freebsd/sys/sys/namei.h
index 53814117..500024de 100644
--- a/freebsd/sys/sys/namei.h
+++ b/freebsd/sys/sys/namei.h
@@ -75,7 +75,9 @@ struct nameidata {
 	 */
 	struct  vnode *ni_startdir;	/* starting directory */
 	struct	vnode *ni_rootdir;	/* logical root directory */
+#ifndef __rtems__
 	struct	vnode *ni_topdir;	/* logical top directory */
+#endif /* __rtems__ */
 	int	ni_dirfd;		/* starting directory for *at functions */
 	int	ni_lcf;			/* local call flags */
 	/*
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index 6ac1025d..4e061de8 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -633,8 +633,8 @@ struct proc {
 #endif /* __rtems__ */
 	struct ucred	*p_ucred;	/* (c) Process owner's identity. */
 	struct filedesc	*p_fd;		/* (b) Open files. */
-	struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
 #ifndef __rtems__
+	struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
 	struct pstats	*p_stats;	/* (b) Accounting/statistics (CPU). */
 	struct plimit	*p_limit;	/* (c) Resource limits. */
 	struct callout	p_limco;	/* (c) Limit callout handle */
diff --git a/freebsd/sys/sys/socketvar.h b/freebsd/sys/sys/socketvar.h
index 96ba4a01..ad57730a 100644
--- a/freebsd/sys/sys/socketvar.h
+++ b/freebsd/sys/sys/socketvar.h
@@ -381,9 +381,22 @@ struct uio;
  */
 #ifndef __rtems__
 int	getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
-#endif /* __rtems__ */
 int	getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
 	    struct file **fpp, u_int *fflagp, struct filecaps *havecaps);
+#else /* __rtems__ */
+int rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp);
+
+static inline int
+getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
+    struct file **fpp, u_int *fflagp, struct filecaps *havecaps)
+{
+
+	(void)td;
+	(void)rightsp;
+	(void)havecaps;
+	return (rtems_bsd_getsock(fd, fpp, fflagp));
+}
+#endif /* __rtems__ */
 void	soabort(struct socket *so);
 int	soaccept(struct socket *so, struct sockaddr **nam);
 void	soaio_enqueue(struct task *task);
diff --git a/freebsd/sys/sys/syscallsubr.h b/freebsd/sys/sys/syscallsubr.h
index 677afdd6..f150d7f9 100644
--- a/freebsd/sys/sys/syscallsubr.h
+++ b/freebsd/sys/sys/syscallsubr.h
@@ -191,8 +191,13 @@ int     kern_nanosleep(struct thread *td, struct timespec *rqt,
 	    struct timespec *rmt);
 int	kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap,
 	    long *ploff);
+#ifndef __rtems__
 int	kern_openat(struct thread *td, int fd, char *path,
 	    enum uio_seg pathseg, int flags, int mode);
+#else /* __rtems__ */
+int	kern_openat(struct thread *td, int fd, char *path,
+	    enum uio_seg pathseg, int flags, int mode, struct file *fp);
+#endif /* __rtems__ */
 int	kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg,
 	    int name, u_long flags, long *valuep);
 int	kern_pipe(struct thread *td, int fildes[2], int flags,
diff --git a/libbsd.py b/libbsd.py
index 983f41a1..ec72b3e2 100644
--- a/libbsd.py
+++ b/libbsd.py
@@ -203,6 +203,7 @@ class rtems(builder.Module):
                 'rtems/rtems-kernel-dev.c',
                 'rtems/rtems-kernel-dirent.c',
                 'rtems/rtems-kernel-epoch.c',
+                'rtems/rtems-kernel-fget.c',
                 'rtems/rtems-kernel-get-file.c',
                 'rtems/rtems-kernel-init.c',
                 'rtems/rtems-kernel-irqs.c',
diff --git a/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h b/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
index a83334b5..dc19c7c2 100644
--- a/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
+++ b/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
@@ -1765,8 +1765,6 @@
 #define	eventhandler_prune_list _bsd_eventhandler_prune_list
 #define	eventhandler_register _bsd_eventhandler_register
 #define	extattr_check_cred _bsd_extattr_check_cred
-#define	falloc_caps _bsd_falloc_caps
-#define	falloc_noinstall _bsd_falloc_noinstall
 #define	fb_commonioctl _bsd_fb_commonioctl
 #define	fb_dump_adp_info _bsd_fb_dump_adp_info
 #define	fb_dump_mode_info _bsd_fb_dump_mode_info
@@ -1806,16 +1804,6 @@
 #define	fdt_pinctrl_configure_tree _bsd_fdt_pinctrl_configure_tree
 #define	fdt_pinctrl_register _bsd_fdt_pinctrl_register
 #define	fdt_regsize _bsd_fdt_regsize
-#define	fget _bsd_fget
-#define	fget_cap _bsd_fget_cap
-#define	fget_cap_locked _bsd_fget_cap_locked
-#define	fget_fcntl _bsd_fget_fcntl
-#define	fget_read _bsd_fget_read
-#define	fget_unlocked _bsd_fget_unlocked
-#define	fget_write _bsd_fget_write
-#define	fgetvp _bsd_fgetvp
-#define	fgetvp_read _bsd_fgetvp_read
-#define	fgetvp_rights _bsd_fgetvp_rights
 #define	fha_assign _bsd_fha_assign
 #define	fha_init _bsd_fha_init
 #define	fha_nd_complete _bsd_fha_nd_complete
@@ -1827,15 +1815,9 @@
 #define	fib6_free_nh_ext _bsd_fib6_free_nh_ext
 #define	fib6_lookup_nh_basic _bsd_fib6_lookup_nh_basic
 #define	fib6_lookup_nh_ext _bsd_fib6_lookup_nh_ext
-#define	filecaps_copy _bsd_filecaps_copy
-#define	filecaps_free _bsd_filecaps_free
-#define	filecaps_init _bsd_filecaps_init
-#define	filecaps_move _bsd_filecaps_move
-#define	filedesc_to_leader_alloc _bsd_filedesc_to_leader_alloc
 #define	find_and_ref_tcp_fb _bsd_find_and_ref_tcp_fb
 #define	find_and_ref_tcp_functions _bsd_find_and_ref_tcp_functions
 #define	find_handler _bsd_find_handler
-#define	finit _bsd_finit
 #define	finstall _bsd_finstall
 #define	firewire_broadcastaddr _bsd_firewire_broadcastaddr
 #define	firewire_busreset _bsd_firewire_busreset
diff --git a/rtemsbsd/include/machine/rtems-bsd-kernel-space.h b/rtemsbsd/include/machine/rtems-bsd-kernel-space.h
index 37bd701d..7b766538 100644
--- a/rtemsbsd/include/machine/rtems-bsd-kernel-space.h
+++ b/rtemsbsd/include/machine/rtems-bsd-kernel-space.h
@@ -233,11 +233,6 @@ dev_t rtems_bsd__makedev(int _M, int _m);
  */
 #define SIGISMEMBER(set, signo) (0)
 
-/*
- * Special knote status bit to indicate the kn_fp is an iop.
- */
-#define KN_FP_IS_IOP       0x10000000
-
 /*
  * Ensure that padding bytes are zeroed and that the name is NUL-terminated.
  */
diff --git a/rtemsbsd/include/machine/rtems-bsd-libio.h b/rtemsbsd/include/machine/rtems-bsd-libio.h
index e662a9ec..3c3a8bbb 100644
--- a/rtemsbsd/include/machine/rtems-bsd-libio.h
+++ b/rtemsbsd/include/machine/rtems-bsd-libio.h
@@ -54,6 +54,8 @@ extern const rtems_filesystem_file_handlers_r rtems_bsd_sysgen_imfsnodeops;
 extern const rtems_filesystem_file_handlers_r rtems_bsd_sysgen_dirops;
 extern const rtems_filesystem_file_handlers_r rtems_bsd_sysgen_fileops;
 
+int rtems_bsd_sysgen_close(rtems_libio_t *iop);
+
 static int inline rtems_bsd_error_to_status_and_errno(int error)
 {
 	if (error == 0) {
@@ -63,26 +65,6 @@ static int inline rtems_bsd_error_to_status_and_errno(int error)
 	}
 }
 
-static inline uint32_t
-rtems_bsd_libio_fflag_to_flags(u_int fflag)
-{
-	uint32_t libio_flags = 0;
-
-	if ((fflag & FREAD) == FREAD) {
-		libio_flags |= LIBIO_FLAGS_READ;
-	}
-
-	if ((fflag & FWRITE) == FWRITE) {
-		libio_flags |= LIBIO_FLAGS_WRITE;
-	}
-
-	if ((fflag & FNONBLOCK) == FNONBLOCK) {
-		libio_flags |= LIBIO_FLAGS_NO_DELAY;
-	}
-
-	return (libio_flags);
-}
-
 static inline u_int
 rtems_bsd_libio_flags_to_fflag(uint32_t libio_flags)
 {
@@ -103,20 +85,6 @@ rtems_bsd_libio_flags_to_fflag(uint32_t libio_flags)
 	return (fflag);
 }
 
-static inline bool
-rtems_bsd_is_libbsd_nvops(rtems_libio_t *iop)
-{
-	return (iop->pathinfo.handlers == &rtems_bsd_sysgen_dirops ||
-	    iop->pathinfo.handlers == &rtems_bsd_sysgen_fileops);
-}
-
-static inline bool
-rtems_bsd_is_libbsd_descriptor(rtems_libio_t *iop)
-{
-	return (iop->pathinfo.handlers == &rtems_bsd_sysgen_nodeops ||
-	    rtems_bsd_is_libbsd_nvops(iop));
-}
-
 static inline rtems_libio_t *
 rtems_bsd_libio_loc_to_iop(const rtems_filesystem_location_info_t *loc)
 {
@@ -151,173 +119,19 @@ rtems_bsd_libio_loc_to_vnode_dir(const rtems_filesystem_location_info_t *loc)
 	    ->node_access_2;
 }
 
-static inline void
-rtems_bsd_libio_iop_free(rtems_libio_t *iop)
-{
-	rtems_libio_free(iop);
-}
-
-static int
-rtems_bsd_libio_iop_to_descriptor(rtems_libio_t *iop)
-{
-	return (int)iop->data0;
-}
-
 static struct vnode *
 rtems_bsd_libio_iop_to_vnode(rtems_libio_t *iop)
 {
 	return rtems_bsd_libio_loc_to_vnode(&iop->pathinfo);
 }
 
-static int
-rtems_bsd_libio_fd_to_descriptor(int fd)
-{
-	return rtems_bsd_libio_iop_to_descriptor(rtems_libio_iop(fd));
-}
-
 static inline struct file *
-rtems_bsd_libio_iop_to_file_hold(rtems_libio_t *iop, struct thread *td)
-{
-	struct file *fp;
-	int error = fget_unlocked(td->td_proc->p_fd,
-	    rtems_bsd_libio_iop_to_descriptor(iop), NULL, &fp, NULL);
-	if (error != 0) {
-		fp = NULL;
-	}
-	return fp;
-}
-
-static inline int
-rtems_bsd_file_to_libio_fd(struct file *fp)
-{
-	return fp->f_io - rtems_libio_iops;
-}
-
-static inline void
-rtems_bsd_libio_iop_set_bsd_descriptor(rtems_libio_t *iop, int fd)
-{
-	iop->data0 = fd;
-	/* if not vnops the fstat passes a loc, need to get the iop to get the
-	 * fp */
-	if (!rtems_bsd_is_libbsd_nvops(iop)) {
-		iop->pathinfo.node_access = iop;
-	}
-}
-
-static inline void
-rtems_bsd_libio_iop_set_bsd_file(rtems_libio_t *iop, struct file *fp)
-{
-	fp->f_io = iop;
-}
-
-/*
- * The fd is a libio file descriptor.
- *
- * Return -1 if the descriptor is closed or not valid. The descriptor is not
- * held.
- *
- * If open hold the descriptor. If the descriptor referneces a BSD
- * descriptor return the BSD descriptor else return the libio descriptor.
- *
- * Optionally return the iop in *iopp if the descriptor if a libio descriptor
- * else return NULL.
- */
-static inline int
-rtems_bsd_libio_iop_hold(int fd, rtems_libio_t **iopp)
+rtems_bsd_knote_to_file(const struct knote *kn)
 {
-	rtems_libio_t *iop = NULL;
-	unsigned int flags = 0;
-	int ffd = -1;
-	if (fd < rtems_libio_number_iops) {
-		iop = rtems_libio_iop(fd);
-		flags = rtems_libio_iop_hold(iop);
-		if ((flags & LIBIO_FLAGS_OPEN) != 0) {
-			if (rtems_bsd_is_libbsd_descriptor(iop)) {
-				ffd = rtems_bsd_libio_iop_to_descriptor(iop);
-				if (iopp != NULL) {
-					*iopp = NULL;
-				}
-			} else {
-				ffd = fd;
-				if (iopp != NULL) {
-					*iopp = iop;
-				}
-			}
-		} else {
-			rtems_libio_iop_drop(iop);
-		}
-		if (RTEMS_BSD_DESCRIP_TRACE)
-			flags = iop->flags;
-	} else {
-		*iopp = NULL;
-	}
-	if (RTEMS_BSD_DESCRIP_TRACE)
-		printf("bsd: iop: hold: fd=%d ffd=%d refs=%d iop=%p by %p\n",
-		    fd, ffd, flags >> 12, iop, __builtin_return_address(0));
-	return ffd;
+	return (kn->kn_fp->data1);
 }
 
-static inline int
-rtems_bsd_libio_iop_drop(int fd)
-{
-	if (RTEMS_BSD_DESCRIP_TRACE)
-		printf("bsd: iop: drop: fd=%d refs=%d by %p\n", fd,
-		    rtems_libio_iop(fd)->flags >> 12,
-		    __builtin_return_address(0));
-	rtems_libio_iop_drop(rtems_libio_iop(fd));
-	return 0;
-}
-
-static inline int
-rtems_bsd_libio_fo_poll(int fd, struct file *fp, int events,
-    struct ucred *active_cred, struct thread *td)
-{
-	int error;
-	if (fp == NULL) {
-		rtems_libio_t *iop = rtems_libio_iop(fd);
-		error = (*iop->pathinfo.handlers->poll_h)(iop, events);
-	} else {
-		error = (*fp->f_ops->fo_poll)(fp, events, active_cred, td);
-		fd = rtems_bsd_file_to_libio_fd(fp);
-	}
-	rtems_bsd_libio_iop_drop(fd);
-	return error;
-}
-
-static inline void
-rtems_bsd_libio_iop_to_knote(struct knote *kn, rtems_libio_t *iop)
-{
-	kn->kn_fp = (struct file *)iop;
-}
-
-static inline struct kqueue *
-rtems_bsd_libio_knote_to_kq(struct knote *kn)
-{
-	struct kqueue *kq = kn->kn_kq;
-	if ((kn->kn_status & KN_FP_IS_IOP) == 0) {
-		if (kq != kn->kn_fp->f_data)
-			panic("libio kq wrong\n");
-	}
-	return kq;
-}
-
-/*
- * Returns an iop with null file system mount or NULL is ENFILE.
- */
-rtems_libio_t *rtems_bsd_libio_iop_allocate(void);
-
-/*
- * Returns the libio descriptor or -1 if ENFILE.
- */
-int rtems_bsd_libio_iop_allocate_with_file(
-    struct thread *td, int fd, const rtems_filesystem_file_handlers_r *ops);
-
-/*
- * Set the BSD file descriptor in the iop. Returns 0 if successful or an error
- * number,
- */
-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 file *rtems_bsd_iop_to_file(const rtems_libio_t *iop);
 
 /*
  * Set the vnode in the libio location.
diff --git a/rtemsbsd/rtems/rtems-bsd-libio.c b/rtemsbsd/rtems/rtems-bsd-libio.c
index fba82831..59f22feb 100644
--- a/rtemsbsd/rtems/rtems-bsd-libio.c
+++ b/rtemsbsd/rtems/rtems-bsd-libio.c
@@ -45,67 +45,6 @@
 
 #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)
diff --git a/rtemsbsd/rtems/rtems-bsd-syscall-api.c b/rtemsbsd/rtems/rtems-bsd-syscall-api.c
index 5c45d88a..ba8a6b60 100644
--- a/rtemsbsd/rtems/rtems-bsd-syscall-api.c
+++ b/rtemsbsd/rtems/rtems-bsd-syscall-api.c
@@ -43,6 +43,7 @@
 #include <sys/file.h>
 #include <sys/filedesc.h>
 #include <sys/proc.h>
+#include <sys/socketvar.h>
 #include <sys/syscallsubr.h>
 #include <sys/sysproto.h>
 #include <sys/vnode.h>
@@ -63,7 +64,6 @@ static int rtems_bsd_sysgen_opendir(
     rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
 static int rtems_bsd_sysgen_open(
     rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
-static int rtems_bsd_sysgen_close(rtems_libio_t *iop);
 static ssize_t rtems_bsd_sysgen_read(
     rtems_libio_t *iop, void *buffer, size_t count);
 static ssize_t rtems_bsd_sysgen_readv(
@@ -165,6 +165,98 @@ const rtems_filesystem_file_handlers_r rtems_bsd_sysgen_imfsnodeops = {
 	.mmap_h = rtems_filesystem_default_mmap
 };
 
+int
+rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
+{
+	int error;
+	rtems_libio_t *iop;
+	unsigned int actual_flags;
+	struct file *fp;
+
+	if ((uint32_t)fd >= rtems_libio_number_iops) {
+		error = EBADF;
+		goto bad;
+	}
+
+	iop = rtems_libio_iop(fd);
+	actual_flags = rtems_libio_iop_hold(iop);
+
+	if ((actual_flags & LIBIO_FLAGS_OPEN) != LIBIO_FLAGS_OPEN) {
+		error = EBADF;
+		goto drop;
+	}
+
+	if (iop->pathinfo.handlers->close_h != rtems_bsd_sysgen_close) {
+		error = ENOTSOCK;
+		goto drop;
+	}
+
+	fp = iop->data1;
+
+	if (fp->f_type != DTYPE_SOCKET) {
+		error = ENOTSOCK;
+		goto drop;
+	}
+
+	if (fflagp != NULL)
+		*fflagp = fp->f_flag;
+	*fpp = fp;
+	return (0);
+
+drop:
+	rtems_libio_iop_drop(iop);
+
+bad:
+	*fpp = NULL;
+	return (error);
+}
+
+struct file *
+rtems_bsd_iop_to_file(const rtems_libio_t *iop)
+{
+
+	if (iop->pathinfo.handlers->close_h != rtems_bsd_sysgen_close) {
+		return (NULL);
+	}
+
+	return (iop->data1);
+}
+
+int
+rtems_bsd_falloc(struct file **resultfp, int *resultfd)
+{
+	struct file *fp;
+	rtems_libio_t *iop;
+
+	fp = malloc(sizeof(*fp), M_TEMP, M_ZERO | M_NOWAIT);
+	*resultfp = fp;
+	if (fp == NULL) {
+		return (ENOMEM);
+	}
+
+	iop = rtems_libio_allocate();
+	if (iop == NULL) {
+		return (ENFILE);
+	}
+
+        fp->f_io = iop;
+        iop->data1 = fp;
+	iop->pathinfo.node_access = iop;
+	iop->pathinfo.handlers = &rtems_bsd_sysgen_nodeops;
+	iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry;
+	rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo);
+	*resultfd = rtems_libio_iop_to_descriptor(iop);
+	return (0);
+}
+
+void
+rtems_bsd_fdclose(struct file *fp)
+{
+
+	rtems_libio_free(fp->f_io);
+	free(fp, M_TEMP);
+}
+
 int
 accept(int socket, struct sockaddr *__restrict address,
     socklen_t *__restrict address_len)
@@ -181,37 +273,14 @@ accept(int socket, struct sockaddr *__restrict address,
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	int ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.name = address;
 	ua.anamelen = address_len;
 	error = sys_accept(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
-	if (error != 0) {
-		return rtems_bsd_error_to_status_and_errno(error);
-	}
-	iop = rtems_bsd_libio_iop_allocate();
-	afd = td->td_retval[0];
-	if (iop == NULL) {
-		kern_close(td, afd);
-		return rtems_bsd_error_to_status_and_errno(ENFILE);
-	}
-	error = rtems_bsd_libio_iop_set_bsd_fd(
-	    td, afd, iop, &rtems_bsd_sysgen_nodeops);
 	if (error != 0) {
-		rtems_bsd_libio_iop_free(iop);
-		kern_close(td, afd);
 		return rtems_bsd_error_to_status_and_errno(error);
 	}
-	if (RTEMS_BSD_SYSCALL_TRACE) {
-		printf("bsd: sys: accept: %d (%d) => %d -> %d\n", socket, ffd,
-		    rtems_libio_iop_to_descriptor(iop),
-		    rtems_bsd_libio_iop_to_descriptor(iop));
-	}
-	return rtems_libio_iop_to_descriptor(iop);
+	return (td->td_retval[0]);
 }
 
 int
@@ -219,7 +288,6 @@ bind(int socket, const struct sockaddr *address, socklen_t address_len)
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct bind_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: bind: %d\n", socket);
@@ -227,15 +295,10 @@ bind(int socket, const struct sockaddr *address, socklen_t address_len)
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd == -1) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.name = address;
 	ua.namelen = address_len;
 	error = sys_bind(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -244,7 +307,6 @@ connect(int socket, const struct sockaddr *address, socklen_t address_len)
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct connect_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: connect: %d\n", socket);
@@ -252,15 +314,10 @@ connect(int socket, const struct sockaddr *address, socklen_t address_len)
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.name = address;
 	ua.namelen = address_len;
 	error = sys_connect(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -270,7 +327,6 @@ getpeername(int socket, struct sockaddr *__restrict address,
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct getpeername_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: getpeername: %d\n", socket);
@@ -278,15 +334,10 @@ getpeername(int socket, struct sockaddr *__restrict address,
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.fdes = ffd;
+	ua.fdes = socket;
 	ua.asa = address;
 	ua.alen = address_len;
 	error = sys_getpeername(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -296,7 +347,6 @@ getsockname(int socket, struct sockaddr *__restrict address,
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct getsockname_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: getsockname: %d\n", socket);
@@ -304,15 +354,10 @@ getsockname(int socket, struct sockaddr *__restrict address,
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.fdes = ffd;
+	ua.fdes = socket;
 	ua.asa = address;
 	ua.alen = address_len;
 	error = sys_getsockname(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -322,7 +367,6 @@ getsockopt(int socket, int level, int option_name,
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct getsockopt_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: getsockopt: %d\n", socket);
@@ -330,17 +374,12 @@ getsockopt(int socket, int level, int option_name,
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.level = level;
 	ua.name = option_name;
 	ua.val = (caddr_t)option_value;
 	ua.avalsize = option_len;
 	error = sys_getsockopt(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -349,7 +388,6 @@ kqueue(void)
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct kqueue_args ua = {};
-	rtems_libio_t *iop;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: kqueue:\n");
@@ -357,28 +395,11 @@ kqueue(void)
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	iop = rtems_bsd_libio_iop_allocate();
-	if (iop == NULL) {
-		return rtems_bsd_error_to_status_and_errno(ENFILE);
-	}
 	error = sys_kqueue(td, &ua);
 	if (error != 0) {
-		goto out;
-	}
-	error = rtems_bsd_libio_iop_set_bsd_fd(
-	    td, td->td_retval[0], iop, &rtems_bsd_sysgen_nodeops);
-	if (error == 0) {
-		if (RTEMS_BSD_SYSCALL_TRACE) {
-			printf("bsd: sys: kqueue: %d -> %d\n",
-			    rtems_libio_iop_to_descriptor(iop),
-			    rtems_bsd_libio_iop_to_descriptor(iop));
-		}
-		return rtems_libio_iop_to_descriptor(iop);
+		return rtems_bsd_error_to_status_and_errno(error);
 	}
-	kern_close(td, rtems_libio_iop_to_descriptor(iop));
-out:
-	rtems_bsd_libio_iop_free(iop);
-	return rtems_bsd_error_to_status_and_errno(error);
+	return (td->td_retval[0]);
 }
 
 __weak_reference(kevent, _kevent);
@@ -397,18 +418,13 @@ kevent(int kq, const struct kevent *changelist, int nchanges,
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(kq, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.fd = ffd;
+	ua.fd = kq;
 	ua.changelist = changelist;
 	ua.nchanges = nchanges;
 	ua.eventlist = eventlist;
 	ua.nevents = nevents;
 	ua.timeout = timeout;
 	error = sys_kevent(td, &ua);
-	rtems_bsd_libio_iop_drop(kq);
 	if (error != 0) {
 		return rtems_bsd_error_to_status_and_errno(error);
 	}
@@ -420,7 +436,6 @@ listen(int socket, int backlog)
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct listen_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: listen: %d\n", socket);
@@ -428,14 +443,9 @@ listen(int socket, int backlog)
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.backlog = backlog;
 	error = sys_listen(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -507,7 +517,6 @@ recvfrom(int socket, void *__restrict buffer, size_t length, int flags,
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct recvfrom_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: recvfrom: %d\n", socket);
@@ -515,18 +524,13 @@ recvfrom(int socket, void *__restrict buffer, size_t length, int flags,
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.buf = buffer;
 	ua.len = length;
 	ua.flags = flags;
 	ua.from = address;
 	ua.fromlenaddr = address_len;
 	error = sys_recvfrom(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	if (error != 0) {
 		return rtems_bsd_error_to_status_and_errno(error);
 	}
@@ -538,7 +542,6 @@ recvmsg(int socket, struct msghdr *message, int flags)
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct recvmsg_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: recvmsg: %d\n", socket);
@@ -546,15 +549,10 @@ recvmsg(int socket, struct msghdr *message, int flags)
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.msg = message;
 	ua.flags = flags;
 	error = sys_recvmsg(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	if (error != 0) {
 		return rtems_bsd_error_to_status_and_errno(error);
 	}
@@ -591,7 +589,6 @@ sendto(int socket, const void *message, size_t length, int flags,
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct sendto_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: sendto: %d\n", socket);
@@ -599,18 +596,13 @@ sendto(int socket, const void *message, size_t length, int flags,
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.buf = (caddr_t)message;
 	ua.len = length;
 	ua.flags = flags;
 	ua.to = dest_addr;
 	ua.tolen = dest_len;
 	error = sys_sendto(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	if (error != 0) {
 		return rtems_bsd_error_to_status_and_errno(error);
 	}
@@ -622,7 +614,6 @@ sendmsg(int socket, const struct msghdr *message, int flags)
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct sendmsg_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: sendmsg: %d\n", socket);
@@ -630,15 +621,10 @@ sendmsg(int socket, const struct msghdr *message, int flags)
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.msg = message;
 	ua.flags = flags;
 	error = sys_sendmsg(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -648,7 +634,6 @@ setsockopt(int socket, int level, int option_name, const void *option_value,
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
 	struct setsockopt_args ua;
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: setsockopt: %d\n", socket);
@@ -656,17 +641,12 @@ setsockopt(int socket, int level, int option_name, const void *option_value,
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	ua.s = ffd;
+	ua.s = socket;
 	ua.level = level;
 	ua.name = option_name;
 	ua.val = __DECONST(void *, option_value);
 	ua.valsize = option_len;
 	error = sys_setsockopt(td, &ua);
-	rtems_bsd_libio_iop_drop(socket);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -674,7 +654,6 @@ int
 shutdown(int socket, int how)
 {
 	struct thread *td = rtems_bsd_get_curthread_or_null();
-	int ffd;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: shutdown: %d\n", socket);
@@ -682,17 +661,8 @@ shutdown(int socket, int how)
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	ffd = rtems_bsd_libio_iop_hold(socket, NULL);
-	if (ffd < 0) {
-		return rtems_bsd_error_to_status_and_errno(EBADF);
-	}
-	if (rtems_bsd_is_libbsd_descriptor(rtems_libio_iop(socket))) {
-		struct shutdown_args ua = { .s = ffd, .how = how };
-		error = sys_shutdown(td, &ua);
-	} else {
-		error = ENOTSOCK;
-	}
-	rtems_bsd_libio_iop_drop(socket);
+	struct shutdown_args ua = { .s = socket, .how = how };
+	error = sys_shutdown(td, &ua);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -700,45 +670,26 @@ int
 socket(int domain, int type, int protocol)
 {
 	struct thread *td;
-	rtems_libio_t *iop;
 	struct socket_args ua;
 	int error;
 	td = rtems_bsd_get_curthread_or_null();
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	iop = rtems_bsd_libio_iop_allocate();
-	if (iop == NULL) {
-		return rtems_bsd_error_to_status_and_errno(ENFILE);
-	}
 	ua.domain = domain;
 	ua.type = type;
 	ua.protocol = protocol;
 	error = sys_socket(td, &ua);
 	if (error != 0) {
-		rtems_bsd_libio_iop_free(iop);
-		return rtems_bsd_error_to_status_and_errno(error);
-	}
-	error = rtems_bsd_libio_iop_set_bsd_fd(
-	    td, td->td_retval[0], iop, &rtems_bsd_sysgen_nodeops);
-	if (error != 0) {
-		kern_close(td, td->td_retval[0]);
-		rtems_bsd_libio_iop_free(iop);
 		return rtems_bsd_error_to_status_and_errno(error);
 	}
-	if (RTEMS_BSD_SYSCALL_TRACE) {
-		printf("bsd: sys: socket: %d -> %d\n",
-		    rtems_libio_iop_to_descriptor(iop),
-		    rtems_bsd_libio_iop_to_descriptor(iop));
-	}
-	return rtems_libio_iop_to_descriptor(iop);
+	return (td->td_retval[0]);
 }
 
 int
 socketpair(int domain, int type, int protocol, int *socket_vector)
 {
 	struct thread *td;
-	rtems_libio_t *iop[2];
 	struct socketpair_args ua;
 	int error;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
@@ -748,48 +699,15 @@ socketpair(int domain, int type, int protocol, int *socket_vector)
 	if (td == NULL) {
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	iop[0] = rtems_bsd_libio_iop_allocate();
-	if (iop[0] == NULL) {
-		return rtems_bsd_error_to_status_and_errno(ENFILE);
-	}
-	iop[1] = rtems_bsd_libio_iop_allocate();
-	if (iop[1] == NULL) {
-		rtems_bsd_libio_iop_free(iop[0]);
-		return rtems_bsd_error_to_status_and_errno(ENFILE);
-	}
 	ua.domain = domain;
 	ua.type = type;
 	ua.protocol = protocol;
 	ua.rsv = socket_vector;
 	error = sys_socketpair(td, &ua);
 	if (error != 0) {
-		goto out;
-	}
-	error = rtems_bsd_libio_iop_set_bsd_fd(
-	    td, socket_vector[0], iop[0], &rtems_bsd_sysgen_nodeops);
-	if (error != 0) {
-		goto out;
-	}
-	error = rtems_bsd_libio_iop_set_bsd_fd(
-	    td, socket_vector[1], iop[1], &rtems_bsd_sysgen_nodeops);
-	if (error == 0) {
-		socket_vector[0] = rtems_libio_iop_to_descriptor(iop[0]);
-		socket_vector[1] = rtems_libio_iop_to_descriptor(iop[1]);
-		if (RTEMS_BSD_SYSCALL_TRACE) {
-			printf("bsd: sys: socketpair: %d -> %d, %d -> %d\n",
-			    socket_vector[0],
-			    rtems_bsd_libio_iop_to_descriptor(iop[0]),
-			    socket_vector[1],
-			    rtems_bsd_libio_iop_to_descriptor(iop[1]));
-		}
-		return 0;
+		return rtems_bsd_error_to_status_and_errno(error);
 	}
-out:
-	kern_close(td, rtems_bsd_libio_iop_to_descriptor(iop[0]));
-	kern_close(td, rtems_bsd_libio_iop_to_descriptor(iop[1]));
-	rtems_bsd_libio_iop_free(iop[0]);
-	rtems_bsd_libio_iop_free(iop[1]);
-	return rtems_bsd_error_to_status_and_errno(error);
+	return (0);
 }
 
 
@@ -814,6 +732,7 @@ rtems_bsd_sysgen_open_node(
 	int opathlen;
 	int fd;
 	int error;
+	struct vnode *vn;
 
 	if (td == NULL) {
 		if (RTEMS_BSD_SYSCALL_TRACE) {
@@ -822,6 +741,18 @@ rtems_bsd_sysgen_open_node(
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
 
+
+	fp = malloc(sizeof(*fp), M_TEMP, M_ZERO | M_NOWAIT);
+	if (fp == NULL) {
+		return rtems_bsd_error_to_status_and_errno(ENOMEM);
+	}
+
+	refcount_init(&fp->f_count, 1);
+	fp->f_cred = crhold(td->td_ucred);
+	fp->f_ops = &badfileops;
+	fp->f_io = iop;
+	iop->data1 = fp;
+
 	fdp = td->td_proc->p_fd;
 
 	/*
@@ -890,7 +821,7 @@ rtems_bsd_sysgen_open_node(
 	VREF(fdp->fd_cdir);
 
 	error = kern_openat(td, AT_FDCWD, RTEMS_DECONST(char *, opath),
-	    UIO_USERSPACE, oflag, mode);
+	    UIO_USERSPACE, oflag, mode, fp);
 
 	vrele(fdp->fd_cdir);
 
@@ -907,19 +838,10 @@ rtems_bsd_sysgen_open_node(
 	FILEDESC_XLOCK(fdp);
 	fdp->fd_cdir = cdir;
 	fdp->fd_rdir = rdir;
-	if (fd < fdp->fd_nfiles) {
-		struct vnode *vn;
-		fp = fget_locked(fdp, fd);
-		if (fp != NULL) {
-			vn = fp->f_vnode;
-		} else {
-			vn = NULL;
-		}
-		rtems_bsd_libio_loc_set_vnode(&iop->pathinfo, vn);
-	}
+	rtems_bsd_libio_loc_set_vnode(&iop->pathinfo, fp->f_vnode);
 	FILEDESC_XUNLOCK(fdp);
 
-	rtems_bsd_libio_iop_set_bsd_fd(td, fd, iop, &rtems_bsd_sysgen_fileops);
+        iop->pathinfo.handlers = &rtems_bsd_sysgen_fileops;
 
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: open: fd = %d vn=%p\n", fd,
@@ -946,28 +868,42 @@ rtems_bsd_sysgen_open(
 int
 rtems_bsd_sysgen_close(rtems_libio_t *iop)
 {
-	struct thread *td = curthread;
+	struct thread *td;
+	struct file *fp;
 	int error;
-	int ffd = rtems_bsd_libio_iop_to_descriptor(iop);
+
 	if (RTEMS_BSD_SYSCALL_TRACE) {
-		printf("bsd: sys: close: %d -> %d\n",
-		    rtems_libio_iop_to_descriptor(iop), ffd);
-	}
-	if (td != NULL) {
-		if (ffd >= 0) {
-			rtems_libio_iop_hold(iop);
-			error = kern_close(td, ffd);
-		} else {
-			error = EBADF;
+		printf("bsd: sys: close: %d\n",
+		    rtems_libio_iop_to_descriptor(iop));
+	}
+
+	td = rtems_bsd_get_curthread_or_null();
+	if (td == NULL) {
+		if (RTEMS_BSD_SYSCALL_TRACE) {
+			printf("bsd: sys: close: no curthread\n");
 		}
-	} else {
-		error = ENOMEM;
+		return (rtems_bsd_error_to_status_and_errno(ENOMEM));
 	}
-	if (RTEMS_BSD_SYSCALL_TRACE) {
-		printf("bsd: sys: close: %d: %d: %s\n",
-		    rtems_libio_iop_to_descriptor(iop), error, strerror(error));
+
+	fp = iop->data1;
+	BSD_ASSERT(fp->f_count == 1);
+	error = (fo_close(fp, td));
+	if (error != 0) {
+		if (RTEMS_BSD_SYSCALL_TRACE) {
+			printf("bsd: sys: close: error = %d\n", error);
+		}
+		return (rtems_bsd_error_to_status_and_errno(error));
 	}
-	return rtems_bsd_error_to_status_and_errno(error);
+
+	if (RTEMS_BSD_SYSCALL_TRACE) {
+		printf("bsd: sys: close: success\n");
+	}
+	FILEDESC_XLOCK(NULL);
+	knote_fdclose(td, rtems_libio_iop_to_descriptor(iop));
+	FILEDESC_XUNLOCK(NULL);
+	crfree(fp->f_cred);
+	free(fp, M_TEMP);
+	return (0);
 }
 
 ssize_t
@@ -975,7 +911,7 @@ rtems_bsd_sysgen_read(rtems_libio_t *iop, void *buffer, size_t count)
 {
 	struct thread *td = curthread;
 	struct vnode *vp = rtems_bsd_libio_iop_to_vnode(iop);
-	int fd = rtems_bsd_libio_iop_to_descriptor(iop);
+	int fd = rtems_libio_iop_to_descriptor(iop);
 	int error;
 	ssize_t size = 0;
 
@@ -1046,7 +982,7 @@ rtems_bsd_sysgen_read(rtems_libio_t *iop, void *buffer, size_t count)
 			.uio_rw = UIO_READ,
 			.uio_td = td };
 		error = kern_readv(
-		    td, rtems_bsd_libio_iop_to_descriptor(iop), &auio);
+		    td, rtems_libio_iop_to_descriptor(iop), &auio);
 		if (error == 0)
 			size = td->td_retval[0];
 	}
@@ -1091,7 +1027,7 @@ rtems_bsd_sysgen_readv(
 	auio.uio_resid = total;
 	auio.uio_segflg = UIO_USERSPACE;
 
-	error = kern_readv(td, rtems_bsd_libio_iop_to_descriptor(iop), &auio);
+	error = kern_readv(td, rtems_libio_iop_to_descriptor(iop), &auio);
 
 	if (error != 0)
 		return rtems_bsd_error_to_status_and_errno(error);
@@ -1129,7 +1065,7 @@ rtems_bsd_sysgen_write(rtems_libio_t *iop, const void *buffer, size_t count)
 	auio.uio_resid = count;
 	auio.uio_segflg = UIO_USERSPACE;
 
-	error = kern_writev(td, rtems_bsd_libio_iop_to_descriptor(iop), &auio);
+	error = kern_writev(td, rtems_libio_iop_to_descriptor(iop), &auio);
 
 	if (error != 0)
 		return rtems_bsd_error_to_status_and_errno(error);
@@ -1165,7 +1101,7 @@ rtems_bsd_sysgen_writev(
 	auio.uio_resid = total;
 	auio.uio_segflg = UIO_USERSPACE;
 
-	error = kern_writev(td, rtems_bsd_libio_iop_to_descriptor(iop), &auio);
+	error = kern_writev(td, rtems_libio_iop_to_descriptor(iop), &auio);
 
 	if (error != 0)
 		return rtems_bsd_error_to_status_and_errno(error);
@@ -1191,7 +1127,7 @@ rtems_bsd_sysgen_ioctl(
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
 	error = kern_ioctl(
-	    td, rtems_bsd_libio_iop_to_descriptor(iop), com, buffer);
+	    td, rtems_libio_iop_to_descriptor(iop), com, buffer);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -1211,7 +1147,7 @@ rtems_bsd_sysgen_lseek(rtems_libio_t *iop, off_t offset, int whence)
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
 	error = kern_lseek(
-	    td, rtems_bsd_libio_iop_to_descriptor(iop), offset, whence);
+	    td, rtems_libio_iop_to_descriptor(iop), offset, whence);
 	if (error != 0) {
 		return rtems_bsd_error_to_status_and_errno(error);
 	}
@@ -1253,9 +1189,7 @@ rtems_bsd_sysgen_fstat(
 {
 	struct thread *td = curthread;
 	rtems_libio_t *iop = rtems_bsd_libio_loc_to_iop(loc);
-	struct filedesc *fdp;
 	struct file *fp = NULL;
-	int fd;
 	int error;
 	if (iop == NULL) {
 		if (RTEMS_BSD_SYSCALL_TRACE) {
@@ -1263,22 +1197,13 @@ rtems_bsd_sysgen_fstat(
 		}
 		return rtems_bsd_error_to_status_and_errno(ENXIO);
 	}
-	fd = rtems_bsd_libio_iop_to_descriptor(iop);
-	if (RTEMS_BSD_SYSCALL_TRACE) {
-		printf("bsd: sys: fstat: %d\n", fd);
-	}
 	if (td == NULL) {
 		if (RTEMS_BSD_SYSCALL_TRACE) {
 			printf("bsd: sys: fstat: no curthread\n");
 		}
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	fdp = td->td_proc->p_fd;
-	FILEDESC_XLOCK(fdp);
-	if (fd < fdp->fd_nfiles) {
-		fp = fget_locked(fdp, fd);
-	}
-	FILEDESC_XUNLOCK(fdp);
+	fp = rtems_bsd_iop_to_file(iop);
 	if (fp != NULL) {
 		error = fo_stat(fp, buf, NULL, td);
 	} else {
@@ -1293,11 +1218,9 @@ rtems_bsd_sysgen_imfsfstat(
 {
 	struct thread *td = curthread;
 	struct socket *so = rtems_bsd_libio_imfs_loc_to_so(loc);
-	struct filedesc *fdp;
 	struct file *fp = NULL;
-	struct socket *fd_so = NULL;
-	int fd;
 	int error;
+	int fd;
 	if (RTEMS_BSD_SYSCALL_TRACE) {
 		printf("bsd: sys: imfsfstat: socket=%p\n", so);
 	}
@@ -1307,17 +1230,22 @@ rtems_bsd_sysgen_imfsfstat(
 		}
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	fdp = td->td_proc->p_fd;
-	FILEDESC_XLOCK(fdp);
-	for (fd = 0; fd < fdp->fd_nfiles; fd++) {
-		fp = fget_locked(fdp, fd);
-		fd_so = fp->f_data;
-		if (so == fd_so) {
+	rtems_libio_lock();
+	for (fd = 0; fd < (int)rtems_libio_number_iops; ++fd) {
+		rtems_libio_t *iop;
+
+		iop = rtems_libio_iop(fd);
+		if (iop->pathinfo.handlers == NULL) {
+			continue;
+		}
+		fp = rtems_bsd_iop_to_file(iop);
+		if (fp != NULL && fp->f_data == so) {
 			break;
 		}
+
 		fp = NULL;
 	}
-	FILEDESC_XUNLOCK(fdp);
+	rtems_libio_unlock();
 	if (fp != NULL) {
 		if (RTEMS_BSD_SYSCALL_TRACE) {
 			printf("bsd: sys: imfsfstat: %d\n", fd);
@@ -1344,7 +1272,7 @@ rtems_bsd_sysgen_ftruncate(rtems_libio_t *iop, off_t length)
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
 	error = kern_ftruncate(
-	    td, rtems_bsd_libio_iop_to_descriptor(iop), length);
+	    td, rtems_libio_iop_to_descriptor(iop), length);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -1362,7 +1290,7 @@ rtems_bsd_sysgen_fsync(rtems_libio_t *iop)
 		}
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	error = kern_fsync(td, rtems_bsd_libio_iop_to_descriptor(iop), true);
+	error = kern_fsync(td, rtems_libio_iop_to_descriptor(iop), true);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -1380,7 +1308,7 @@ rtems_bsd_sysgen_fdatasync(rtems_libio_t *iop)
 		}
 		return rtems_bsd_error_to_status_and_errno(ENOMEM);
 	}
-	error = kern_fsync(td, rtems_bsd_libio_iop_to_descriptor(iop), false);
+	error = kern_fsync(td, rtems_libio_iop_to_descriptor(iop), false);
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
@@ -1416,7 +1344,7 @@ rtems_bsd_sysgen_fcntl(rtems_libio_t *iop, int cmd)
 	}
 	if (arg >= 0) {
 		error = kern_fcntl(
-		    td, rtems_bsd_libio_iop_to_descriptor(iop), cmd, arg);
+		    td, rtems_libio_iop_to_descriptor(iop), cmd, arg);
 		/* no return path with the RTEMS API for get calls */
 	}
 	return rtems_bsd_error_to_status_and_errno(error);
@@ -1425,13 +1353,23 @@ rtems_bsd_sysgen_fcntl(rtems_libio_t *iop, int cmd)
 int
 rtems_bsd_sysgen_poll(rtems_libio_t *iop, int events)
 {
-	printf("rtems_bsd_sysgen_poll called!\n");
-	return rtems_bsd_error_to_status_and_errno(EOPNOTSUPP);
+	struct thread *td;
+	struct file *fp;
+
+	td = rtems_bsd_get_curthread_or_null();
+	if (td == NULL) {
+		return (ENOMEM);
+	}
+
+	fp = iop->data1;
+	return (fo_poll(fp, events, td->td_ucred, td));
 }
 
 int
 rtems_bsd_sysgen_kqfilter(rtems_libio_t *iop, struct knote *kn)
 {
-	printf("rtems_bsd_sysgen_kqfilter called!\n");
-	return rtems_bsd_error_to_status_and_errno(EOPNOTSUPP);
+	struct file *fp;
+
+	fp = iop->data1;
+	return (fo_kqfilter(fp, kn));
 }
diff --git a/rtemsbsd/rtems/rtems-kernel-fget.c b/rtemsbsd/rtems/rtems-kernel-fget.c
new file mode 100644
index 00000000..e51ddb57
--- /dev/null
+++ b/rtemsbsd/rtems/rtems-kernel-fget.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH
+ *
+ * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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/file.h>
+
+/* Avoid referencing the VFS only through rtems_bsd_fget() */
+__weak_symbol int
+rtems_bsd_sysgen_close(rtems_libio_t *iop)
+{
+
+	(void)iop;
+	return (-1);
+}
+
+int
+rtems_bsd_fget(int fd, struct file **fpp, int flags)
+{
+	rtems_libio_t *iop;
+	unsigned int actual_flags;
+
+	if ((uint32_t)fd >= rtems_libio_number_iops) {
+		goto bad;
+	}
+
+	iop = rtems_libio_iop(fd);
+	actual_flags = rtems_libio_iop_hold(iop);
+
+	if ((actual_flags & flags) != flags) {
+		goto drop;
+	}
+
+	if (iop->pathinfo.handlers->close_h != rtems_bsd_sysgen_close) {
+		goto drop;
+	}
+
+	*fpp = iop->data1;
+	return (0);
+
+drop:
+	rtems_libio_iop_drop(iop);
+
+bad:
+	*fpp = NULL;
+	return (EBADF);
+}
diff --git a/rtemsbsd/rtems/rtems-kernel-init.c b/rtemsbsd/rtems/rtems-kernel-init.c
index 90a9c809..454943b3 100644
--- a/rtemsbsd/rtems/rtems-kernel-init.c
+++ b/rtemsbsd/rtems/rtems-kernel-init.c
@@ -141,6 +141,10 @@ cpu_startup(void *dummy)
 }
 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
 
+static struct filedesc p_fd = {
+    .fd_cmask = CMASK
+};
+
 /*
  * Create a single process. RTEMS is a single address, single process OS.
  */
@@ -166,8 +170,7 @@ proc0_init(void *dummy)
 	newcred->cr_ruidinfo = uifind(0);
 	p->p_ucred = newcred;
 	p->p_pid = getpid();
-	p->p_fd = fdinit(NULL, false);
-	p->p_fdtol = NULL;
+	p->p_fd = &p_fd;
 	rtems_sysvec.sv_flags = SV_ABI_FREEBSD;
 #ifdef __LP64__
 	rtems_sysvec.sv_flags |= SV_LP64;
-- 
2.35.3





More information about the devel mailing list