[libbsd 11/22] Add struct file wrapper

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


Add a struct file wrapper in <rtems/bsd/sys/file.h> as an alternative to the
full FreeBSD struct file in <sys/file.h>.  This allows using <sys/file.h> for
FreeBSD file systems (VFS) and the wrapper for other areas such as devfs,
cryptodev, sockets, kqueue, poll, and select which do not need the VFS support.

Update #4475.
---
 rtemsbsd/include/rtems/bsd/sys/file.h  | 248 +++++++++++++++++++++++++
 rtemsbsd/rtems/rtems-kernel-get-file.c |   9 +-
 2 files changed, 252 insertions(+), 5 deletions(-)
 create mode 100644 rtemsbsd/include/rtems/bsd/sys/file.h

diff --git a/rtemsbsd/include/rtems/bsd/sys/file.h b/rtemsbsd/include/rtems/bsd/sys/file.h
new file mode 100644
index 00000000..04898677
--- /dev/null
+++ b/rtemsbsd/include/rtems/bsd/sys/file.h
@@ -0,0 +1,248 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief This header file provides a alternative implementation for interfaces
+ *   normally provided via <sys/file.h>.
+ */
+
+/*
+ * Copyright (C) 2013, 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.
+ */
+
+#ifndef _SYS_FILE_H_
+#define	_SYS_FILE_H_
+#define	_SYS_FILEDESC_H_
+
+#include <rtems/libio_.h>
+#include <sys/fcntl.h>
+#include <sys/refcount.h>
+#include <sys/seq.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct filecaps;
+struct filedesc;
+struct ucred;
+
+extern const rtems_filesystem_file_handlers_r socketops;
+
+#define	file rtems_libio_tt
+#define	f_data pathinfo.node_access_2
+
+#define	maxfiles rtems_libio_number_iops
+
+typedef int fo_kqfilter_t(struct file *, struct knote *);
+
+static inline void *
+rtems_bsd_loc_to_f_data(const rtems_filesystem_location_info_t *loc)
+{
+	return loc->node_access_2;
+}
+
+static inline uint32_t
+rtems_bsd_fflag_to_libio_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)
+{
+	u_int fflag = 0;
+
+	if ((libio_flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
+		fflag |= FREAD;
+	}
+
+	if ((libio_flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
+		fflag |= FWRITE;
+	}
+
+	if ((libio_flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY) {
+		fflag |= FNONBLOCK;
+	}
+
+	return (fflag);
+}
+
+static int inline
+rtems_bsd_error_to_status_and_errno(int error)
+{
+	if (error == 0) {
+		return 0;
+	} else {
+		rtems_set_errno_and_return_minus_one(error);
+	}
+}
+
+struct file *rtems_bsd_get_file(int fd);
+
+static inline int
+rtems_bsd_do_fget(int fd, struct file **fpp)
+{
+	struct file *fp;
+
+	fp = rtems_bsd_get_file(fd);
+	*fpp = fp;
+	return (fp != NULL ? 0 : EBADF);
+}
+
+#undef fget
+#define	fget(td, fd, rights, fpp) rtems_bsd_do_fget(fd, fpp)
+
+static inline void
+rtems_bsd_finit(struct file *fp, u_int fflag, void *data,
+    const rtems_filesystem_file_handlers_r *ops)
+{
+
+	fp->f_data = data;
+	fp->pathinfo.handlers = ops;
+	rtems_libio_iop_flags_set(fp, LIBIO_FLAGS_OPEN |
+	    rtems_bsd_fflag_to_libio_flags(fflag));
+}
+
+#undef finit
+#define	finit(fp, fflag, type, data, ops) rtems_bsd_finit(fp, fflag, data, ops)
+
+/*
+ * WARNING: fdalloc() and falloc_caps() do not increment the reference count of
+ * the file descriptor in contrast to FreeBSD.  We must not call the fdrop()
+ * corresponding to a fdalloc() or falloc_caps().  The reason for this is that
+ * FreeBSD performs a lazy cleanup once the reference count reaches zero.
+ * RTEMS uses the reference count to determine if a cleanup is allowed.
+ */
+#define	fdrop(fp, td) rtems_libio_iop_drop(fp)
+
+static inline int
+fo_ioctl(struct file *fp, u_long com, void *data, struct ucred *active_cred,
+    struct thread *td)
+{
+
+	int rv;
+
+	(void)active_cred;
+	(void)td;
+
+	errno = 0;
+	rv = ((*fp->pathinfo.handlers->ioctl_h)(fp, com, data));
+	if (rv == 0) {
+		return (0);
+	} else {
+		return (errno);
+	}
+}
+
+#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()
+
+#undef filecaps_free
+#define	filecaps_free(fcaps) do { } while (0)
+
+static inline int
+rtems_bsd_falloc(struct thread *td, struct file **resultfp, int *resultfd,
+    int flags)
+{
+	rtems_libio_t *iop;
+
+	(void)td;
+	(void)flags;
+
+	iop = rtems_libio_allocate();
+	*resultfp = iop;
+	*resultfd = rtems_libio_iop_to_descriptor(iop);
+
+	if (iop != NULL) {
+		iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry;
+		rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo);
+		return (0);
+	} else {
+		return (ENFILE);
+	}
+}
+
+#define	falloc_caps(td, resultfp, resultfd, flags, fcaps) \
+    rtems_bsd_falloc(td, resultfp, resultfd, flags)
+
+#define	falloc(td, resultfp, resultfd, flags) \
+    rtems_bsd_falloc(td, resultfp, resultfd, flags)
+
+static inline int
+rtems_bsd_fget_unlocked(struct filedesc *fdp, int fd, struct file **fpp,
+    seq_t *seqp)
+{
+	struct file *fp;
+
+	(void)fdp;
+	(void)seqp;
+	fp = rtems_bsd_get_file(fd);
+	*fpp = fp;
+	return (fp != NULL ? 0 : EBADF);
+}
+
+#undef fget_unlocked
+#define	fget_unlocked(fdp, fd, needrightsp, fpp, seqp) \
+    rtems_bsd_fget_unlocked(fdp, fd, fpp, seqp)
+
+/*
+ * WARNING: Use of fdrop() after fclose() corrupts the file descriptor.  See
+ * fdrop() comment.
+ */
+static inline void
+fdclose(struct thread *td, struct file *fp, int idx)
+{
+	(void)td;
+	(void)idx;
+
+	rtems_libio_free(fp);
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/** @} */
+
+#endif /* _SYS_FILE_H_ */
diff --git a/rtemsbsd/rtems/rtems-kernel-get-file.c b/rtemsbsd/rtems/rtems-kernel-get-file.c
index 143af6a2..2b4edef3 100644
--- a/rtemsbsd/rtems/rtems-kernel-get-file.c
+++ b/rtemsbsd/rtems/rtems-kernel-get-file.c
@@ -39,8 +39,7 @@
 
 #include <machine/rtems-bsd-kernel-space.h>
 
-#include <sys/types.h>
-#include <sys/file.h>
+#include <rtems/bsd/sys/file.h>
 
 struct file *
 rtems_bsd_get_file(int fd)
@@ -50,11 +49,11 @@ rtems_bsd_get_file(int fd)
 	if ((uint32_t) fd < rtems_libio_number_iops) {
 		unsigned int flags;
 
-		fp = rtems_bsd_fd_to_fp(fd);
-		flags = rtems_libio_iop_hold(&fp->f_io);
+		fp = &rtems_libio_iops[fd];
+		flags = rtems_libio_iop_hold(fp);
 
 		if ((flags & LIBIO_FLAGS_OPEN) == 0) {
-			rtems_libio_iop_drop(&fp->f_io);
+			rtems_libio_iop_drop(fp);
 			fp = NULL;
 		}
 	} else {
-- 
2.35.3



More information about the devel mailing list