Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup LibIO
0007  *
0008  * @brief Basic IO API
0009  *
0010  * This file contains the support infrastructure used to manage the
0011  * table of integer style file descriptors used by the low level
0012  * POSIX system calls like open(), read, fstat(), etc.
0013  */
0014 
0015 /*
0016  * COPYRIGHT (C) 1989, 2021 On-Line Applications Research Corporation (OAR).
0017  *
0018  * Modifications to support reference counting in the file system are
0019  * Copyright (C) 2012 embedded brains GmbH & Co. KG
0020  *
0021  * Redistribution and use in source and binary forms, with or without
0022  * modification, are permitted provided that the following conditions
0023  * are met:
0024  * 1. Redistributions of source code must retain the above copyright
0025  *    notice, this list of conditions and the following disclaimer.
0026  * 2. Redistributions in binary form must reproduce the above copyright
0027  *    notice, this list of conditions and the following disclaimer in the
0028  *    documentation and/or other materials provided with the distribution.
0029  *
0030  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0031  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0032  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0033  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0034  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0035  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0036  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0037  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0038  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0039  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0040  * POSSIBILITY OF SUCH DAMAGE.
0041  */
0042 
0043 #ifndef _RTEMS_RTEMS_LIBIO_H
0044 #define _RTEMS_RTEMS_LIBIO_H
0045 
0046 #include <sys/types.h>
0047 #include <sys/stat.h>
0048 #include <sys/ioccom.h>
0049 #include <sys/statvfs.h>
0050 #include <sys/uio.h>
0051 
0052 #include <unistd.h>
0053 #include <termios.h>
0054 
0055 #include <rtems.h>
0056 #include <rtems/fs.h>
0057 #include <rtems/chain.h>
0058 #include <rtems/score/atomic.h>
0059 #include <rtems/termiosdevice.h>
0060 
0061 #ifdef __cplusplus
0062 extern "C" {
0063 #endif
0064 
0065 struct knote;
0066 
0067 /**
0068  * @defgroup LibIOFSOps File System Operations
0069  *
0070  * @ingroup LibIO
0071  *
0072  * @brief File system operations.
0073  */
0074 /**@{**/
0075 
0076 /**
0077  * @brief Locks a file system instance.
0078  *
0079  * This lock must allow nesting.
0080  *
0081  * @param[in, out] mt_entry The mount table entry of the file system instance.
0082  *
0083  * @see rtems_filesystem_default_lock().
0084  */
0085 typedef void (*rtems_filesystem_mt_entry_lock_t)(
0086   const rtems_filesystem_mount_table_entry_t *mt_entry
0087 );
0088 
0089 /**
0090  * @brief Unlocks a file system instance.
0091  *
0092  * @param[in, out] mt_entry The mount table entry of the file system instance.
0093  *
0094  * @see rtems_filesystem_default_unlock().
0095  */
0096 typedef void (*rtems_filesystem_mt_entry_unlock_t)(
0097   const rtems_filesystem_mount_table_entry_t *mt_entry
0098 );
0099 
0100 /**
0101  * @brief Path evaluation context.
0102  */
0103 typedef struct {
0104   /**
0105    * The contents of the remaining path to be evaluated.
0106    */
0107   const char *path;
0108 
0109   /**
0110    * The length of the remaining path to be evaluated.
0111    */
0112   size_t pathlen;
0113 
0114   /**
0115    * The contents of the token to be evaluated with respect to the current
0116    * location.
0117    */
0118   const char *token;
0119 
0120   /**
0121    * The length of the token to be evaluated with respect to the current
0122    * location.
0123    */
0124   size_t tokenlen;
0125 
0126   /**
0127    * The path evaluation is controlled by the following flags
0128    *  - RTEMS_FS_PERMS_READ,
0129    *  - RTEMS_FS_PERMS_WRITE,
0130    *  - RTEMS_FS_PERMS_EXEC,
0131    *  - RTEMS_FS_FOLLOW_HARD_LINK,
0132    *  - RTEMS_FS_FOLLOW_SYM_LINK,
0133    *  - RTEMS_FS_MAKE,
0134    *  - RTEMS_FS_EXCLUSIVE,
0135    *  - RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS, and
0136    *  - RTEMS_FS_REJECT_TERMINAL_DOT.
0137    */
0138   int flags;
0139 
0140   /**
0141    * Symbolic link evaluation is a recursive operation.  This field helps to
0142    * limit the recursion level and thus prevents a stack overflow.  The
0143    * recursion level is limited by RTEMS_FILESYSTEM_SYMLOOP_MAX.
0144    */
0145   int recursionlevel;
0146 
0147   /**
0148    * This is the current file system location of the evaluation process.
0149    * Tokens are evaluated with respect to the current location.  The token
0150    * interpretation may change the current location.  The purpose of the path
0151    * evaluation is to change the start location into a final current location
0152    * according to the path.
0153    */
0154   rtems_filesystem_location_info_t currentloc;
0155 
0156   /**
0157    * The location of the root directory of the user environment during the
0158    * evaluation start.
0159    */
0160   rtems_filesystem_global_location_t *rootloc;
0161 
0162   /**
0163    * The start location of the evaluation process.  The start location my
0164    * change during symbolic link evaluation.
0165    */
0166   rtems_filesystem_global_location_t *startloc;
0167 } rtems_filesystem_eval_path_context_t;
0168 
0169 /**
0170  * @brief Path evaluation.
0171  *
0172  * @param[in, out] ctx The path evaluation context.
0173  *
0174  * @see rtems_filesystem_default_eval_path().
0175  */
0176 typedef void (*rtems_filesystem_eval_path_t)(
0177   rtems_filesystem_eval_path_context_t *ctx
0178 );
0179 
0180 /**
0181  * @brief Creates a new link for the existing file.
0182  *
0183  * @param[in] parentloc The location of the parent of the new link.
0184  * @param[in] targetloc The location of the target file.
0185  * @param[in] name Name for the new link.
0186  * @param[in] namelen Length of the name for the new link in characters.
0187  *
0188  * @retval 0 Successful operation.
0189  * @retval -1 An error occurred.  The errno is set to indicate the error.
0190  *
0191  * @see rtems_filesystem_default_link().
0192  */
0193 typedef int (*rtems_filesystem_link_t)(
0194   const rtems_filesystem_location_info_t *parentloc,
0195   const rtems_filesystem_location_info_t *targetloc,
0196   const char *name,
0197   size_t namelen
0198 );
0199 
0200 /**
0201  * @brief Changes the mode of a node.
0202  *
0203  * @param[in] loc The location of the node.
0204  * @param[in] mode The new mode of the node
0205  *
0206  * @retval 0 Successful operation.
0207  * @retval -1 An error occurred.  The errno is set to indicate the error.
0208  *
0209  * @see rtems_filesystem_default_fchmod().
0210  */
0211 typedef int (*rtems_filesystem_fchmod_t)(
0212   const rtems_filesystem_location_info_t *loc,
0213   mode_t mode
0214 );
0215 
0216 /**
0217  * @brief Changes owner and group of a node.
0218  *
0219  * @param[in] loc The location of the node.
0220  * @param[in] owner User ID for the node.
0221  * @param[in] group Group ID for the node.
0222  *
0223  * @retval 0 Successful operation.
0224  * @retval -1 An error occurred.  The errno is set to indicate the error.
0225  *
0226  * @see rtems_filesystem_default_chown().
0227  */
0228 typedef int (*rtems_filesystem_chown_t)(
0229   const rtems_filesystem_location_info_t *loc,
0230   uid_t owner,
0231   gid_t group
0232 );
0233 
0234 /**
0235  * @brief Clones a location.
0236  *
0237  * The location is initialized with a bitwise copy of an existing location.
0238  * The caller must ensure that this location is protected from a release during
0239  * the clone operation.  After a successful clone operation the clone will be
0240  * added to the location chain of the corresponding mount table entry.
0241  *
0242  * @param[in, out] loc Location to clone.
0243  *
0244  * @retval 0 Successful operation.
0245  * @retval -1 An error occurred.  The errno is set to indicate the error.
0246  *
0247  * @see rtems_filesystem_default_clonenode().
0248  */
0249 typedef int (*rtems_filesystem_clonenode_t)(
0250   rtems_filesystem_location_info_t *loc
0251 );
0252 
0253 /**
0254  * @brief Frees the location of a node.
0255  *
0256  * @param[in] loc The location of the node.
0257  *
0258  * @see rtems_filesystem_default_freenode().
0259  */
0260 typedef void (*rtems_filesystem_freenode_t)(
0261   const rtems_filesystem_location_info_t *loc
0262 );
0263 
0264 /**
0265  * @brief Mounts a file system instance in a mount point (directory).
0266  *
0267  * The mount point belongs to the file system instance of the handler and is
0268  * specified by a field of the mount table entry.  The handler must check that
0269  * the mount point is capable of mounting a file system instance.  This is the
0270  * last step during the mount process.  The file system instance is fully
0271  * initialized at this point.
0272  *
0273  * @param[in] mt_entry The mount table entry.
0274  *
0275  * @retval 0 Successful operation.
0276  * @retval -1 An error occurred.  The errno is set to indicate the error.
0277  *
0278  * @see rtems_filesystem_default_mount().
0279  */
0280 typedef int (*rtems_filesystem_mount_t) (
0281   rtems_filesystem_mount_table_entry_t *mt_entry
0282 );
0283 
0284 /**
0285  * @brief Initializes a file system instance.
0286  *
0287  * This function must initialize the file system root node in the mount table
0288  * entry.
0289  *
0290  * @param[in] mt_entry The mount table entry.
0291  * @param[in] data The data provided by the user.
0292  *
0293  * @retval 0 Successful operation.
0294  * @retval -1 An error occurred.  The errno is set to indicate the error.
0295  */
0296 typedef int (*rtems_filesystem_fsmount_me_t)(
0297   rtems_filesystem_mount_table_entry_t *mt_entry,
0298   const void *data
0299 );
0300 
0301 /**
0302  * @brief Unmounts a file system instance in a mount point (directory).
0303  *
0304  * In case this function is successful the file system instance will be marked
0305  * as unmounted.  The file system instance will be destroyed when the last
0306  * reference to it vanishes.
0307  *
0308  * @param[in] mt_entry The mount table entry.
0309  *
0310  * @retval 0 Successful operation.
0311  * @retval -1 An error occurred.  The errno is set to indicate the error.
0312  *
0313  * @see rtems_filesystem_default_unmount().
0314  */
0315 typedef int (*rtems_filesystem_unmount_t) (
0316   rtems_filesystem_mount_table_entry_t *mt_entry
0317 );
0318 
0319 /**
0320  * @brief Destroys a file system instance.
0321  *
0322  * The mount point node location of the mount table entry is invalid.  This
0323  * handler must free the file system root location and all remaining resources
0324  * of the file system instance.
0325  *
0326  * @param[in] mt_entry The mount table entry.
0327  *
0328  * @see rtems_filesystem_default_fsunmount().
0329  */
0330 typedef void (*rtems_filesystem_fsunmount_me_t)(
0331   rtems_filesystem_mount_table_entry_t *mt_entry
0332 );
0333 
0334 /**
0335  * @brief Tests if the node of one location is equal to the node of the other
0336  * location.
0337  *
0338  * The caller ensures that both nodes are within the same file system instance.
0339  *
0340  * @param[in] a The one location.
0341  * @param[in] b The other location.
0342  *
0343  * @retval true The nodes of the locations are equal.
0344  * @retval false Otherwise.
0345  *
0346  * @see rtems_filesystem_default_are_nodes_equal().
0347  */
0348 typedef bool (*rtems_filesystem_are_nodes_equal_t)(
0349   const rtems_filesystem_location_info_t *a,
0350   const rtems_filesystem_location_info_t *b
0351 );
0352 
0353 /**
0354  * @brief Creates a new node.
0355  *
0356  * This handler should create a new node according to the parameters.
0357  *
0358  * @param[in] parentloc The location of the parent of the new node.
0359  * @param[in] name Name for the new node.
0360  * @param[in] namelen Length of the name for the new node in characters.
0361  * @param[in] mode Mode for the new node.
0362  * @param[in] dev Optional device identifier for the new node.
0363  *
0364  * @retval 0 Successful operation.
0365  * @retval -1 An error occurred.  The errno is set to indicate the error.
0366  *
0367  * @see rtems_filesystem_default_mknod().
0368  */
0369 typedef int (*rtems_filesystem_mknod_t)(
0370   const rtems_filesystem_location_info_t *parentloc,
0371   const char *name,
0372   size_t namelen,
0373   mode_t mode,
0374   dev_t dev
0375 );
0376 
0377 /**
0378  * @brief Removes a node.
0379  *
0380  * @param[in] parentloc The location of the parent of the node.
0381  * @param[in] loc The location of the node.
0382  *
0383  * @retval 0 Successful operation.
0384  * @retval -1 An error occurred.  The errno is set to indicate the error.
0385  *
0386  * @see rtems_filesystem_default_rmnod().
0387  */
0388 typedef int (*rtems_filesystem_rmnod_t)(
0389   const rtems_filesystem_location_info_t *parentloc,
0390   const rtems_filesystem_location_info_t *loc
0391 );
0392 
0393 /**
0394  * @brief Set node access and modification times.
0395  *
0396  * @param[in] loc The location of the node.
0397  * @param[in] times Access and modification times for the node
0398  *
0399  * @retval 0 Successful operation.
0400  * @retval -1 An error occurred.  The errno is set to indicate the error.
0401  *
0402  * @see rtems_filesystem_default_utimens().
0403  */
0404 typedef int (*rtems_filesystem_utimens_t)(
0405   const rtems_filesystem_location_info_t *loc,
0406   struct timespec times[2]
0407 );
0408 
0409 /**
0410  * @brief Makes a symbolic link to a node.
0411  *
0412  * @param[in] parentloc The location of the parent of the new symbolic link.
0413  * @param[in] name Name for the new symbolic link.
0414  * @param[in] namelen Length of the name for the new symbolic link in
0415  * characters.
0416  * @param[in] target Contents for the symbolic link.
0417  *
0418  * @retval 0 Successful operation.
0419  * @retval -1 An error occurred.  The errno is set to indicate the error.
0420  *
0421  * @see rtems_filesystem_default_symlink().
0422  */
0423 typedef int (*rtems_filesystem_symlink_t)(
0424   const rtems_filesystem_location_info_t *parentloc,
0425   const char *name,
0426   size_t namelen,
0427   const char *target
0428 );
0429 
0430 /**
0431  * @brief Reads the contents of a symbolic link.
0432  *
0433  * @param[in] loc The location of the symbolic link.
0434  * @param[out] buf The buffer for the contents.
0435  * @param[in] bufsize The size of the buffer in characters.
0436  *
0437  * @retval non-negative Size of the actual contents in characters.
0438  * @retval -1 An error occurred.  The errno is set to indicate the error.
0439  *
0440  * @see rtems_filesystem_default_readlink().
0441  */
0442 typedef ssize_t (*rtems_filesystem_readlink_t)(
0443   const rtems_filesystem_location_info_t *loc,
0444   char *buf,
0445   size_t bufsize
0446 );
0447 
0448 /**
0449  * @brief Renames a node.
0450  *
0451  * @param[in] oldparentloc The location of the parent of the old node.
0452  * @param[in] oldloc The location of the old node.
0453  * @param[in] newparentloc The location of the parent of the new node.
0454  * @param[in] name Name for the new node.
0455  * @param[in] namelen Length of the name for the new node in characters.
0456  *
0457  * @retval 0 Successful operation.
0458  * @retval -1 An error occurred.  The errno is set to indicate the error.
0459  *
0460  * @see rtems_filesystem_default_rename().
0461  */
0462 typedef int (*rtems_filesystem_rename_t)(
0463   const rtems_filesystem_location_info_t *oldparentloc,
0464   const rtems_filesystem_location_info_t *oldloc,
0465   const rtems_filesystem_location_info_t *newparentloc,
0466   const char *name,
0467   size_t namelen
0468 );
0469 
0470 /**
0471  * @brief Gets file system information.
0472  *
0473  * @param[in] loc The location of a node.
0474  * @param[out] buf Buffer for file system information.
0475  *
0476  * @retval 0 Successful operation.
0477  * @retval -1 An error occurred.  The errno is set to indicate the error.
0478  *
0479  * @see rtems_filesystem_default_statvfs().
0480  */
0481 typedef int (*rtems_filesystem_statvfs_t)(
0482   const rtems_filesystem_location_info_t *loc,
0483   struct statvfs *buf
0484 );
0485 
0486 /**
0487  * @brief File system operations table.
0488  */
0489 struct _rtems_filesystem_operations_table {
0490   rtems_filesystem_mt_entry_lock_t lock_h;
0491   rtems_filesystem_mt_entry_unlock_t unlock_h;
0492   rtems_filesystem_eval_path_t eval_path_h;
0493   rtems_filesystem_link_t link_h;
0494   rtems_filesystem_are_nodes_equal_t are_nodes_equal_h;
0495   rtems_filesystem_mknod_t mknod_h;
0496   rtems_filesystem_rmnod_t rmnod_h;
0497   rtems_filesystem_fchmod_t fchmod_h;
0498   rtems_filesystem_chown_t chown_h;
0499   rtems_filesystem_clonenode_t clonenod_h;
0500   rtems_filesystem_freenode_t freenod_h;
0501   rtems_filesystem_mount_t mount_h;
0502   rtems_filesystem_unmount_t unmount_h;
0503   rtems_filesystem_fsunmount_me_t fsunmount_me_h;
0504   rtems_filesystem_utimens_t utimens_h;
0505   rtems_filesystem_symlink_t symlink_h;
0506   rtems_filesystem_readlink_t readlink_h;
0507   rtems_filesystem_rename_t rename_h;
0508   rtems_filesystem_statvfs_t statvfs_h;
0509 };
0510 
0511 /**
0512  * @brief File system operations table with default operations.
0513  */
0514 extern const rtems_filesystem_operations_table
0515   rtems_filesystem_operations_default;
0516 
0517 /**
0518  * @brief Obtains the IO library mutex.
0519  *
0520  * @see rtems_filesystem_mt_entry_lock_t.
0521  */
0522 void rtems_filesystem_default_lock(
0523   const rtems_filesystem_mount_table_entry_t *mt_entry
0524 );
0525 
0526 /**
0527  * @brief Releases the IO library mutex.
0528  *
0529  * @see rtems_filesystem_mt_entry_unlock_t.
0530  */
0531 void rtems_filesystem_default_unlock(
0532   const rtems_filesystem_mount_table_entry_t *mt_entry
0533 );
0534 
0535 /**
0536  * @brief Terminates the path evaluation and replaces the current location with
0537  * the null location.
0538  *
0539  * @see rtems_filesystem_eval_path_t.
0540  */
0541 void rtems_filesystem_default_eval_path(
0542   rtems_filesystem_eval_path_context_t *ctx
0543 );
0544 
0545 /**
0546  * @retval -1 Always.  The errno is set to ENOTSUP.
0547  *
0548  * @see rtems_filesystem_link_t.
0549  */
0550 int rtems_filesystem_default_link(
0551   const rtems_filesystem_location_info_t *parentloc,
0552   const rtems_filesystem_location_info_t *targetloc,
0553   const char *name,
0554   size_t namelen
0555 );
0556 
0557 /**
0558  * @brief Tests if the node access pointer of one location is equal to
0559  * the node access pointer of the other location.
0560  *
0561  * @param[in] a The one location.
0562  * @param[in] b The other location.
0563  *
0564  * @retval true The node access pointers of the locations are equal.
0565  * @retval false Otherwise.
0566  *
0567  * @see rtems_filesystem_are_nodes_equal_t.
0568  */
0569 bool rtems_filesystem_default_are_nodes_equal(
0570   const rtems_filesystem_location_info_t *a,
0571   const rtems_filesystem_location_info_t *b
0572 );
0573 
0574 /**
0575  * @retval -1 Always.  The errno is set to ENOTSUP.
0576  *
0577  * @see rtems_filesystem_mknod_t.
0578  */
0579 int rtems_filesystem_default_mknod(
0580   const rtems_filesystem_location_info_t *parentloc,
0581   const char *name,
0582   size_t namelen,
0583   mode_t mode,
0584   dev_t dev
0585 );
0586 
0587 /**
0588  * @retval -1 Always.  The errno is set to ENOTSUP.
0589  *
0590  * @see rtems_filesystem_rmnod_t.
0591  */
0592 int rtems_filesystem_default_rmnod(
0593   const rtems_filesystem_location_info_t *parentloc,
0594   const rtems_filesystem_location_info_t *loc
0595 );
0596 
0597 /**
0598  * @retval -1 Always.  The errno is set to ENOTSUP.
0599  *
0600  * @see rtems_filesystem_fchmod_t.
0601  */
0602 int rtems_filesystem_default_fchmod(
0603   const rtems_filesystem_location_info_t *loc,
0604   mode_t mode
0605 );
0606 
0607 /**
0608  * @retval -1 Always.  The errno is set to ENOTSUP.
0609  *
0610  * @see rtems_filesystem_chown_t.
0611  */
0612 int rtems_filesystem_default_chown(
0613   const rtems_filesystem_location_info_t *loc,
0614   uid_t owner,
0615   gid_t group
0616 );
0617 
0618 /**
0619  * @retval 0 Always.
0620  *
0621  * @see rtems_filesystem_clonenode_t.
0622  */
0623 int rtems_filesystem_default_clonenode(
0624   rtems_filesystem_location_info_t *loc
0625 );
0626 
0627 /**
0628  * @see rtems_filesystem_freenode_t.
0629  */
0630 void rtems_filesystem_default_freenode(
0631   const rtems_filesystem_location_info_t *loc
0632 );
0633 
0634 /**
0635  * @retval -1 Always.  The errno is set to ENOTSUP.
0636  *
0637  * @see rtems_filesystem_mount_t.
0638  */
0639 int rtems_filesystem_default_mount (
0640    rtems_filesystem_mount_table_entry_t *mt_entry     /* IN */
0641 );
0642 
0643 /**
0644  * @retval -1 Always.  The errno is set to ENOTSUP.
0645  *
0646  * @see rtems_filesystem_unmount_t.
0647  */
0648 int rtems_filesystem_default_unmount(
0649   rtems_filesystem_mount_table_entry_t *mt_entry     /* IN */
0650 );
0651 
0652 /**
0653  * @retval -1 Always.  The errno is set to ENOTSUP.
0654  *
0655  * @see rtems_filesystem_fsunmount_me_t.
0656  */
0657 void rtems_filesystem_default_fsunmount(
0658    rtems_filesystem_mount_table_entry_t *mt_entry    /* IN */
0659 );
0660 
0661 /**
0662  * @retval -1 Always.  The errno is set to ENOTSUP.
0663  *
0664  * @see rtems_filesystem_utimens_t.
0665  */
0666 int rtems_filesystem_default_utimens(
0667   const rtems_filesystem_location_info_t *loc,
0668   struct timespec times[2]
0669 );
0670 
0671 /**
0672  * @retval -1 Always.  The errno is set to ENOTSUP.
0673  *
0674  * @see rtems_filesystem_symlink_t.
0675  */
0676 int rtems_filesystem_default_symlink(
0677   const rtems_filesystem_location_info_t *parentloc,
0678   const char *name,
0679   size_t namelen,
0680   const char *target
0681 );
0682 
0683 /**
0684  * @retval -1 Always.  The errno is set to ENOTSUP.
0685  *
0686  * @see rtems_filesystem_readlink_t.
0687  */
0688 ssize_t rtems_filesystem_default_readlink(
0689   const rtems_filesystem_location_info_t *loc,
0690   char *buf,
0691   size_t bufsize
0692 );
0693 
0694 /**
0695  * @retval -1 Always.  The errno is set to ENOTSUP.
0696  *
0697  * @see rtems_filesystem_rename_t.
0698  */
0699 int rtems_filesystem_default_rename(
0700   const rtems_filesystem_location_info_t *oldparentloc,
0701   const rtems_filesystem_location_info_t *oldloc,
0702   const rtems_filesystem_location_info_t *newparentloc,
0703   const char *name,
0704   size_t namelen
0705 );
0706 
0707 /**
0708  * @retval -1 Always.  The errno is set to ENOTSUP.
0709  *
0710  * @see rtems_filesystem_statvfs_t.
0711  */
0712 int rtems_filesystem_default_statvfs(
0713   const rtems_filesystem_location_info_t *loc,
0714   struct statvfs *buf
0715 );
0716 
0717 /** @} */
0718 
0719 /**
0720  * @defgroup LibIOFSHandler File System Node Handler
0721  *
0722  * @ingroup LibIO
0723  *
0724  * @brief File system node handler.
0725  */
0726 /**@{**/
0727 
0728 /**
0729  * @brief Opens a node.
0730  *
0731  * @param[in, out] iop The IO pointer.
0732  * @param[in] path The path.
0733  * @param[in] oflag The open flags.
0734  * @param[in] mode Optional mode for node creation.
0735  *
0736  * @retval 0 Successful operation.
0737  * @retval -1 An error occurred.  The errno is set to indicate the error.
0738  *
0739  * @see rtems_filesystem_default_open().
0740  */
0741 typedef int (*rtems_filesystem_open_t)(
0742   rtems_libio_t *iop,
0743   const char    *path,
0744   int            oflag,
0745   mode_t         mode
0746 );
0747 
0748 /**
0749  * @brief Closes a node.
0750  *
0751  * @param[in, out] iop The IO pointer.
0752  *
0753  * @retval 0 Successful operation.
0754  * @retval -1 An error occurred.  The errno is set to indicate the error.
0755  *
0756  * @see rtems_filesystem_default_close().
0757  */
0758 typedef int (*rtems_filesystem_close_t)(
0759   rtems_libio_t *iop
0760 );
0761 
0762 /**
0763  * @brief Reads from a node.
0764  *
0765  * This handler is responsible to update the offset field of the IO descriptor.
0766  *
0767  * @param[in, out] iop The IO pointer.
0768  * @param[out] buffer The buffer for read data.
0769  * @param[in] count The size of the buffer in characters.
0770  *
0771  * @retval non-negative Count of read characters.
0772  * @retval -1 An error occurred.  The errno is set to indicate the error.
0773  *
0774  * @see rtems_filesystem_default_read().
0775  */
0776 typedef ssize_t (*rtems_filesystem_read_t)(
0777   rtems_libio_t *iop,
0778   void          *buffer,
0779   size_t         count
0780 );
0781 
0782 /**
0783  * @brief Reads an IO vector from a node.
0784  *
0785  * This handler is responsible to update the offset field of the IO descriptor.
0786  *
0787  * @param[in, out] iop The IO pointer.
0788  * @param[in] iov The IO vector with buffer for read data.  The caller must
0789  * ensure that the IO vector values are valid.
0790  * @param[in] iovcnt The count of buffers in the IO vector.
0791  * @param[in] total The total count of bytes in the buffers in the IO vector.
0792  *
0793  * @retval non-negative Count of read characters.
0794  * @retval -1 An error occurred.  The errno is set to indicate the error.
0795  *
0796  * @see rtems_filesystem_default_readv().
0797  */
0798 typedef ssize_t (*rtems_filesystem_readv_t)(
0799   rtems_libio_t      *iop,
0800   const struct iovec *iov,
0801   int                 iovcnt,
0802   ssize_t             total
0803 );
0804 
0805 /**
0806  * @brief Writes to a node.
0807  *
0808  * This handler is responsible to update the offset field of the IO descriptor.
0809  *
0810  * @param[in, out] iop The IO pointer.
0811  * @param[out] buffer The buffer for write data.
0812  * @param[in] count The size of the buffer in characters.
0813  *
0814  * @retval non-negative Count of written characters.
0815  * @retval -1 An error occurred.  The errno is set to indicate the error.
0816  *
0817  * @see rtems_filesystem_default_write().
0818  */
0819 typedef ssize_t (*rtems_filesystem_write_t)(
0820   rtems_libio_t *iop,
0821   const void    *buffer,
0822   size_t         count
0823 );
0824 
0825 /**
0826  * @brief Writes an IO vector to a node.
0827  *
0828  * This handler is responsible to update the offset field of the IO descriptor.
0829  *
0830  * @param[in, out] iop The IO pointer.
0831  * @param[in] iov The IO vector with buffer for write data.  The caller must
0832  * ensure that the IO vector values are valid.
0833  * @param[in] iovcnt The count of buffers in the IO vector.
0834  * @param[in] total The total count of bytes in the buffers in the IO vector.
0835  *
0836  * @retval non-negative Count of written characters.
0837  * @retval -1 An error occurred.  The errno is set to indicate the error.
0838  *
0839  * @see rtems_filesystem_default_writev().
0840  */
0841 typedef ssize_t (*rtems_filesystem_writev_t)(
0842   rtems_libio_t      *iop,
0843   const struct iovec *iov,
0844   int                 iovcnt,
0845   ssize_t             total
0846 );
0847 
0848 /**
0849  * @brief IO control of a node.
0850  *
0851  * @param[in, out] iop The IO pointer.
0852  * @param[in] request The IO control request.
0853  * @param[in, out] buffer The buffer for IO control request data.
0854  *
0855  * @retval 0 Successful operation.
0856  * @retval -1 An error occurred.  The errno is set to indicate the error.
0857  *
0858  * @see rtems_filesystem_default_ioctl().
0859  */
0860 typedef int (*rtems_filesystem_ioctl_t)(
0861   rtems_libio_t   *iop,
0862   ioctl_command_t  request,
0863   void            *buffer
0864 );
0865 
0866 /**
0867  * @brief Moves the read/write file offset.
0868  *
0869  * @param[in, out] iop The IO pointer.
0870  * @param[in] offset The offset.
0871  * @param[in] whence The reference position for the offset.
0872  *
0873  * @retval non-negative The new offset from the beginning of the file.
0874  * @retval -1 An error occurred.  The errno is set to indicate the error.
0875  *
0876  * @see rtems_filesystem_default_lseek(),
0877  * rtems_filesystem_default_lseek_file(), and
0878  * rtems_filesystem_default_lseek_directory().
0879  */
0880 typedef off_t (*rtems_filesystem_lseek_t)(
0881   rtems_libio_t *iop,
0882   off_t          offset,
0883   int            whence
0884 );
0885 
0886 /**
0887  * @brief Gets a node status.
0888  *
0889  * @param[in, out] iop The IO pointer.
0890  * @param[out] stat The buffer to status information.
0891  *
0892  * @retval 0 Successful operation.
0893  * @retval -1 An error occurred.  The errno is set to indicate the error.
0894  *
0895  * @see rtems_filesystem_default_fstat().
0896  */
0897 typedef int (*rtems_filesystem_fstat_t)(
0898   const rtems_filesystem_location_info_t *loc,
0899   struct stat *buf
0900 );
0901 
0902 /**
0903  * @brief Truncates a file to a specified length.
0904  *
0905  * @param[in, out] iop The IO pointer.
0906  * @param[in] length The new length in characters.
0907  *
0908  * @retval 0 Successful operation.
0909  * @retval -1 An error occurred.  The errno is set to indicate the error.
0910  *
0911  * @see rtems_filesystem_default_ftruncate() and
0912  * rtems_filesystem_default_ftruncate_directory().
0913  */
0914 typedef int (*rtems_filesystem_ftruncate_t)(
0915   rtems_libio_t *iop,
0916   off_t length
0917 );
0918 
0919 /**
0920  * @brief Synchronizes changes to a file.
0921  *
0922  * @param[in, out] iop The IO pointer.
0923  *
0924  * @retval 0 Successful operation.
0925  * @retval -1 An error occurred.  The errno is set to indicate the error.
0926  *
0927  * @see rtems_filesystem_default_fsync_or_fdatasync() and
0928  * rtems_filesystem_default_fsync_or_fdatasync_success().
0929  */
0930 typedef int (*rtems_filesystem_fsync_t)(
0931   rtems_libio_t *iop
0932 );
0933 
0934 /**
0935  * @brief Synchronizes the data of a file.
0936  *
0937  * @param[in, out] iop The IO pointer.
0938  *
0939  * @retval 0 Successful operation.
0940  * @retval -1 An error occurred.  The errno is set to indicate the error.
0941  *
0942  * @see rtems_filesystem_default_fsync_or_fdatasync() and
0943  * rtems_filesystem_default_fsync_or_fdatasync_success().
0944  */
0945 typedef int (*rtems_filesystem_fdatasync_t)(
0946   rtems_libio_t *iop
0947 );
0948 
0949 /**
0950  * @brief File control.
0951  *
0952  * @param[in, out] iop The IO pointer.
0953  * @param[in] cmd Control command.
0954  *
0955  * @retval 0 Successful operation.
0956  * @retval errno An error occurred.  This value is assigned to errno.
0957  *
0958  * @see rtems_filesystem_default_fcntl().
0959  */
0960 typedef int (*rtems_filesystem_fcntl_t)(
0961   rtems_libio_t *iop,
0962   int cmd
0963 );
0964 
0965 /**
0966  * @brief Poll and select support.
0967  *
0968  * @param[in, out] iop The IO pointer.
0969  * @param[in] events The poll events.
0970  *
0971  * @return The poll return events.
0972  *
0973  * @see rtems_filesystem_default_poll().
0974  */
0975 typedef int (*rtems_filesystem_poll_t)(
0976   rtems_libio_t *iop,
0977   int events
0978 );
0979 
0980 /**
0981  * @brief Kernel event filter support.
0982  *
0983  * @param[in, out] iop The IO pointer.
0984  * @param[in] kn The kernel event note.
0985  *
0986  * @retval 0 Successful operation.
0987  * @retval error An error occurred.  This is usually EINVAL.
0988  *
0989  * @see rtems_filesystem_default_kqfilter().
0990  */
0991 typedef int (*rtems_filesystem_kqfilter_t)(
0992   rtems_libio_t *iop,
0993   struct knote *kn
0994 );
0995 
0996 /**
0997  * @brief MMAP support.
0998  *
0999  * @param[in, out] iop The IO pointer.
1000  * @param[in, out] addr The starting address of the mapped memory.
1001  * @param[in] len The maximum number of bytes to map.
1002  * @param[in] prot The desired memory protection.
1003  * @param[in] off The offset within the file descriptor to map.
1004  *
1005  * @retval 0 Successful operation.
1006  * @retval error An error occurred.  This is usually EINVAL.
1007  *
1008  * @see rtems_filesystem_default_mmap().
1009  */
1010 typedef int (*rtems_filesystem_mmap_t)(
1011   rtems_libio_t *iop,
1012   void **addr,
1013   size_t len,
1014   int prot,
1015   off_t off
1016 );
1017 
1018 /**
1019  * @brief File system node operations table.
1020  */
1021 struct _rtems_filesystem_file_handlers_r {
1022   rtems_filesystem_open_t open_h;
1023   rtems_filesystem_close_t close_h;
1024   rtems_filesystem_read_t read_h;
1025   rtems_filesystem_write_t write_h;
1026   rtems_filesystem_ioctl_t ioctl_h;
1027   rtems_filesystem_lseek_t lseek_h;
1028   rtems_filesystem_fstat_t fstat_h;
1029   rtems_filesystem_ftruncate_t ftruncate_h;
1030   rtems_filesystem_fsync_t fsync_h;
1031   rtems_filesystem_fdatasync_t fdatasync_h;
1032   rtems_filesystem_fcntl_t fcntl_h;
1033   rtems_filesystem_poll_t poll_h;
1034   rtems_filesystem_kqfilter_t kqfilter_h;
1035   rtems_filesystem_readv_t readv_h;
1036   rtems_filesystem_writev_t writev_h;
1037   rtems_filesystem_mmap_t mmap_h;
1038 };
1039 
1040 /**
1041  * @brief File system node handler table with default node handlers.
1042  */
1043 extern const rtems_filesystem_file_handlers_r
1044   rtems_filesystem_handlers_default;
1045 
1046 /**
1047  * @retval 0 Always.
1048  *
1049  * @see rtems_filesystem_open_t.
1050  */
1051 int rtems_filesystem_default_open(
1052   rtems_libio_t *iop,
1053   const char    *path,
1054   int            oflag,
1055   mode_t         mode
1056 );
1057 
1058 /**
1059  * @retval 0 Always.
1060  *
1061  * @see rtems_filesystem_close_t.
1062  */
1063 int rtems_filesystem_default_close(
1064   rtems_libio_t *iop
1065 );
1066 
1067 /**
1068  * @retval -1 Always.  The errno is set to ENOTSUP.
1069  *
1070  * @see rtems_filesystem_read_t.
1071  */
1072 ssize_t rtems_filesystem_default_read(
1073   rtems_libio_t *iop,
1074   void          *buffer,
1075   size_t         count
1076 );
1077 
1078 /**
1079  * @brief Calls the read handler for each IO vector entry.
1080  *
1081  * @see rtems_filesystem_readv_t.
1082  */
1083 ssize_t rtems_filesystem_default_readv(
1084   rtems_libio_t      *iop,
1085   const struct iovec *iov,
1086   int                 iovcnt,
1087   ssize_t             total
1088 );
1089 
1090 /**
1091  * @retval -1 Always.  The errno is set to ENOTSUP.
1092  *
1093  * @see rtems_filesystem_write_t.
1094  */
1095 ssize_t rtems_filesystem_default_write(
1096   rtems_libio_t *iop,
1097   const void    *buffer,
1098   size_t         count
1099 );
1100 
1101 /**
1102  * @brief Calls the write handler for each IO vector entry.
1103  *
1104  * @see rtems_filesystem_write_t.
1105  */
1106 ssize_t rtems_filesystem_default_writev(
1107   rtems_libio_t      *iop,
1108   const struct iovec *iov,
1109   int                 iovcnt,
1110   ssize_t             total
1111 );
1112 
1113 /**
1114  * @retval -1 Always.  The errno is set to ENOTTY.
1115  *
1116  * @see rtems_filesystem_ioctl_t.
1117  */
1118 int rtems_filesystem_default_ioctl(
1119   rtems_libio_t   *iop,
1120   ioctl_command_t  request,
1121   void            *buffer
1122 );
1123 
1124 /**
1125  * @retval -1 Always.  The errno is set to ESPIPE.
1126  *
1127  * @see rtems_filesystem_lseek_t.
1128  */
1129 off_t rtems_filesystem_default_lseek(
1130   rtems_libio_t *iop,
1131   off_t          offset,
1132   int            whence
1133 );
1134 
1135 /**
1136  * @brief An offset 0 with a whence of SEEK_SET will perform a directory rewind
1137  * operation.
1138  *
1139  * This function has no protection against concurrent access.
1140  *
1141  * @retval -1 The offset is not zero or the whence is not SEEK_SET.
1142  * @retval 0 Successful rewind operation.
1143  *
1144  * @see rtems_filesystem_lseek_t.
1145  */
1146 off_t rtems_filesystem_default_lseek_directory(
1147   rtems_libio_t *iop,
1148   off_t offset,
1149   int whence
1150 );
1151 
1152 /**
1153  * @brief Default lseek() handler for files.
1154  *
1155  * The fstat() handler will be used to obtain the file size in case whence is
1156  * SEEK_END.
1157  *
1158  * This function has no protection against concurrent access.
1159  *
1160  * @retval -1 An error occurred.  In case an integer overflow occurred, then the
1161  * errno will be set to EOVERFLOW.  In case the new offset is negative, then
1162  * the errno will be set to EINVAL.  In case the whence is SEEK_END and the
1163  * fstat() handler to obtain the current file size returned an error status,
1164  * then the errno will be set by the fstat() handler.
1165  * @retval offset The new offset.
1166  *
1167  * @see rtems_filesystem_lseek_t.
1168  */
1169 off_t rtems_filesystem_default_lseek_file(
1170   rtems_libio_t *iop,
1171   off_t offset,
1172   int whence
1173 );
1174 
1175 /**
1176  * @brief Sets the mode to S_IRWXU | S_IRWXG | S_IRWXO.
1177  *
1178  * @retval 0 Always.
1179  *
1180  * @see rtems_filesystem_fstat_t.
1181  */
1182 int rtems_filesystem_default_fstat(
1183   const rtems_filesystem_location_info_t *loc,
1184   struct stat *buf
1185 );
1186 
1187 /**
1188  * @retval -1 Always.  The errno is set to EINVAL.
1189  *
1190  * @see rtems_filesystem_ftruncate_t.
1191  */
1192 int rtems_filesystem_default_ftruncate(
1193   rtems_libio_t *iop,
1194   off_t length
1195 );
1196 
1197 /**
1198  * @retval -1 Always.  The errno is set to EISDIR.
1199  *
1200  * @see rtems_filesystem_ftruncate_t.
1201  */
1202 int rtems_filesystem_default_ftruncate_directory(
1203   rtems_libio_t *iop,
1204   off_t length
1205 );
1206 
1207 /**
1208  * @retval -1 Always.  The errno is set to EINVAL.
1209  *
1210  * @see rtems_filesystem_fsync_t and rtems_filesystem_fdatasync_t.
1211  */
1212 int rtems_filesystem_default_fsync_or_fdatasync(
1213   rtems_libio_t *iop
1214 );
1215 
1216 /**
1217  * @retval 0 Always.
1218  *
1219  * @see rtems_filesystem_fsync_t and rtems_filesystem_fdatasync_t.
1220  */
1221 int rtems_filesystem_default_fsync_or_fdatasync_success(
1222   rtems_libio_t *iop
1223 );
1224 
1225 /**
1226  * @retval 0 Always.
1227  *
1228  * @see rtems_filesystem_fcntl_t.
1229  */
1230 int rtems_filesystem_default_fcntl(
1231   rtems_libio_t *iop,
1232   int cmd
1233 );
1234 
1235 /**
1236  * @brief Default poll handler.
1237  *
1238  * @retval POLLERR Always.
1239  *
1240  * @see rtems_filesystem_poll_t.
1241  */
1242 int rtems_filesystem_default_poll(
1243   rtems_libio_t *iop,
1244   int events
1245 );
1246 
1247 /**
1248  * @brief Default kernel event filter handler.
1249  *
1250  * @retval EINVAL Always.
1251  *
1252  * @see rtems_filesystem_kqfilter_t.
1253  */
1254 int rtems_filesystem_default_kqfilter(
1255   rtems_libio_t *iop,
1256   struct knote *kn
1257 );
1258 
1259 /**
1260  * @brief Default MMAP handler.
1261  *
1262  * @retval ENOTSUP Always.
1263  *
1264  * @see rtems_filesystem_mmap_t.
1265  */
1266 int rtems_filesystem_default_mmap(
1267   rtems_libio_t *iop,
1268   void **addr,
1269   size_t len,
1270   int prot,
1271   off_t off
1272 );
1273 
1274 /** @} */
1275 
1276 /**
1277  * @defgroup LibIO IO Library
1278  *
1279  * @ingroup RTEMSImpl
1280  *
1281  * @brief Provides system call and file system interface definitions.
1282  *
1283  * General purpose communication channel for RTEMS to allow UNIX/POSIX
1284  * system call behavior under RTEMS.  Initially this supported only
1285  * IO to devices but has since been enhanced to support networking
1286  * and support for mounted file systems.
1287  */
1288 /**@{**/
1289 
1290 typedef off_t rtems_off64_t __attribute__((deprecated));
1291 
1292 /**
1293  * @brief Gets the mount handler for the file system @a type.
1294  *
1295  * @return The file system mount handler associated with the @a type, or
1296  * @c NULL if no such association exists.
1297  */
1298 rtems_filesystem_fsmount_me_t
1299 rtems_filesystem_get_mount_handler(
1300   const char *type
1301 );
1302 
1303 /**
1304  * @brief Contain file system specific information which is required to support
1305  * fpathconf().
1306  */
1307 typedef struct {
1308   int    link_max;                 /* count */
1309   int    max_canon;                /* max formatted input line size */
1310   int    max_input;                /* max input line size */
1311   int    name_max;                 /* max name length */
1312   int    path_max;                 /* max path */
1313   int    pipe_buf;                 /* pipe buffer size */
1314   int    posix_async_io;           /* async IO supported on fs, 0=no, 1=yes */
1315   int    posix_chown_restrictions; /* can chown: 0=no, 1=yes */
1316   int    posix_no_trunc;           /* error on names > max name, 0=no, 1=yes */
1317   int    posix_prio_io;            /* priority IO, 0=no, 1=yes */
1318   int    posix_sync_io;            /* file can be sync'ed, 0=no, 1=yes */
1319   int    posix_vdisable;           /* special char processing, 0=no, 1=yes */
1320 } rtems_filesystem_limits_and_options_t;
1321 
1322 /**
1323  * @brief Default pathconf settings.
1324  *
1325  * Override in a filesystem.
1326  */
1327 extern const rtems_filesystem_limits_and_options_t
1328   rtems_filesystem_default_pathconf;
1329 
1330 /**
1331  * @brief An open file data structure.
1332  *
1333  * It will be indexed by 'fd'.
1334  *
1335  * @todo Should really have a separate per/file data structure that this points
1336  * to (eg: offset, driver, pathname should be in that)
1337  */
1338 struct rtems_libio_tt {
1339   Atomic_Uint                             flags;
1340   off_t                                   offset;    /* current offset into file */
1341   rtems_filesystem_location_info_t        pathinfo;
1342   uint32_t                                data0;     /* private to "driver" */
1343   void                                   *data1;     /* ... */
1344 };
1345 
1346 /**
1347  * @brief Paramameter block for read/write.
1348  *
1349  * It must include 'offset' instead of using iop's offset since we can have
1350  * multiple outstanding i/o's on a device.
1351  */
1352 typedef struct {
1353   rtems_libio_t          *iop;
1354   off_t                   offset;
1355   char                   *buffer;
1356   uint32_t                count;
1357   uint32_t                flags;
1358   uint32_t                bytes_moved;
1359 } rtems_libio_rw_args_t;
1360 
1361 /**
1362  * @brief Parameter block for open/close.
1363  */
1364 typedef struct rtems_libio_open_close_args {
1365   rtems_libio_t          *iop;
1366   uint32_t                flags;
1367   uint32_t                mode;
1368 } rtems_libio_open_close_args_t;
1369 
1370 /**
1371  * @brief Parameter block for ioctl.
1372  */
1373 typedef struct {
1374   rtems_libio_t          *iop;
1375   ioctl_command_t         command;
1376   void                   *buffer;
1377   int                     ioctl_return;
1378 } rtems_libio_ioctl_args_t;
1379 
1380 /**
1381  * @name Flag Values
1382  */
1383 /**@{**/
1384 
1385 #define LIBIO_FLAGS_NO_DELAY      0x0001U  /* return immediately if no data */
1386 #define LIBIO_FLAGS_READ          0x0002U  /* reading */
1387 #define LIBIO_FLAGS_WRITE         0x0004U  /* writing */
1388 #define LIBIO_FLAGS_OPEN          0x0100U  /* device is open */
1389 #define LIBIO_FLAGS_APPEND        0x0200U  /* all writes append */
1390 #define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800U  /* close on process exec() */
1391 #define LIBIO_FLAGS_READ_WRITE    (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
1392 #define LIBIO_FLAGS_REFERENCE_INC 0x1000U
1393 
1394 /** @} */
1395 
1396 static inline unsigned int rtems_libio_iop_flags( const rtems_libio_t *iop )
1397 {
1398   return _Atomic_Load_uint( &iop->flags, ATOMIC_ORDER_RELAXED );
1399 }
1400 
1401 /**
1402  * @brief Returns true if this is a no delay iop, otherwise returns false.
1403  *
1404  * @param[in] iop The iop.
1405  */
1406 static inline bool rtems_libio_iop_is_no_delay( const rtems_libio_t *iop )
1407 {
1408   return ( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_NO_DELAY ) != 0;
1409 }
1410 
1411 /**
1412  * @brief Returns true if this is a readable iop, otherwise returns false.
1413  *
1414  * @param[in] iop The iop.
1415  */
1416 static inline bool rtems_libio_iop_is_readable( const rtems_libio_t *iop )
1417 {
1418   return ( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_READ ) != 0;
1419 }
1420 
1421 /**
1422  * @brief Returns true if this is a writeable iop, otherwise returns false.
1423  *
1424  * @param[in] iop The iop.
1425  */
1426 static inline bool rtems_libio_iop_is_writeable( const rtems_libio_t *iop )
1427 {
1428   return ( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_WRITE ) != 0;
1429 }
1430 
1431 /**
1432  * @brief Returns true if this is an append iop, otherwise returns false.
1433  *
1434  * @param[in] iop The iop.
1435  */
1436 static inline bool rtems_libio_iop_is_append( const rtems_libio_t *iop )
1437 {
1438   return ( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_APPEND ) != 0;
1439 }
1440 
1441 /**
1442  * @name External I/O Handlers
1443  */
1444 /**@{**/
1445 
1446 typedef int (*rtems_libio_open_t)(
1447   const char  *pathname,
1448   uint32_t    flag,
1449   uint32_t    mode
1450 );
1451 
1452 typedef int (*rtems_libio_close_t)(
1453   int  fd
1454 );
1455 
1456 typedef ssize_t (*rtems_libio_read_t)(
1457   int         fd,
1458   void       *buffer,
1459   size_t    count
1460 );
1461 
1462 typedef ssize_t (*rtems_libio_write_t)(
1463   int         fd,
1464   const void *buffer,
1465   size_t      count
1466 );
1467 
1468 typedef int (*rtems_libio_ioctl_t)(
1469   int         fd,
1470   uint32_t    command,
1471   void       *buffer
1472 );
1473 
1474 typedef off_t (*rtems_libio_lseek_t)(
1475   int           fd,
1476   off_t         offset,
1477   int           whence
1478 );
1479 
1480 /** @} */
1481 
1482 /**
1483  * @name Permission Macros
1484  */
1485 /**@{**/
1486 
1487 /*
1488  *  The following macros are used to build up the permissions sets
1489  *  used to check permissions.  These are similar in style to the
1490  *  mode_t bits and should stay compatible with them.
1491  */
1492 #define RTEMS_FS_PERMS_READ 0x4
1493 #define RTEMS_FS_PERMS_WRITE 0x2
1494 #define RTEMS_FS_PERMS_EXEC 0x1
1495 #define RTEMS_FS_PERMS_RWX \
1496   (RTEMS_FS_PERMS_READ | RTEMS_FS_PERMS_WRITE | RTEMS_FS_PERMS_EXEC)
1497 #define RTEMS_FS_FOLLOW_HARD_LINK 0x8
1498 #define RTEMS_FS_FOLLOW_SYM_LINK 0x10
1499 #define RTEMS_FS_FOLLOW_LINK \
1500   (RTEMS_FS_FOLLOW_HARD_LINK | RTEMS_FS_FOLLOW_SYM_LINK)
1501 #define RTEMS_FS_MAKE 0x20
1502 #define RTEMS_FS_EXCLUSIVE 0x40
1503 #define RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS 0x80
1504 #define RTEMS_FS_REJECT_TERMINAL_DOT 0x100
1505 
1506 /** @} */
1507 
1508 union __rtems_dev_t {
1509   dev_t device;
1510   struct {
1511      rtems_device_major_number major;
1512      rtems_device_minor_number minor;
1513   } __overlay;
1514 };
1515 
1516 static inline dev_t rtems_filesystem_make_dev_t(
1517   rtems_device_major_number _major,
1518   rtems_device_minor_number _minor
1519 )
1520 {
1521   union __rtems_dev_t temp;
1522 
1523   temp.__overlay.major = _major;
1524   temp.__overlay.minor = _minor;
1525   return temp.device;
1526 }
1527 
1528 static inline dev_t rtems_filesystem_make_dev_t_from_pointer(
1529   const void *pointer
1530 )
1531 {
1532   uint64_t temp = (((uint64_t) 1) << 63) | (((uintptr_t) pointer) >> 1);
1533 
1534   return rtems_filesystem_make_dev_t((uint32_t) (temp >> 32), (uint32_t) temp);
1535 }
1536 
1537 static inline rtems_device_major_number rtems_filesystem_dev_major_t(
1538   dev_t device
1539 )
1540 {
1541   union __rtems_dev_t temp;
1542 
1543   temp.device = device;
1544   return temp.__overlay.major;
1545 }
1546 
1547 
1548 static inline rtems_device_minor_number rtems_filesystem_dev_minor_t(
1549   dev_t device
1550 )
1551 {
1552   union __rtems_dev_t temp;
1553 
1554   temp.device = device;
1555   return temp.__overlay.minor;
1556 }
1557 
1558 #define rtems_filesystem_split_dev_t( _dev, _major, _minor ) \
1559   do { \
1560     (_major) = rtems_filesystem_dev_major_t ( _dev ); \
1561     (_minor) = rtems_filesystem_dev_minor_t( _dev ); \
1562   } while(0)
1563 
1564 /*
1565  *  Prototypes for filesystem
1566  */
1567 
1568 /**
1569  *  @brief Base File System Initialization
1570  *
1571  *  Initialize the foundation of the file system.  This is specified
1572  *  by the structure rtems_filesystem_mount_table.  The usual
1573  *  configuration is a single instantiation of the IMFS or miniIMFS with
1574  *  a single "/dev" directory in it.
1575  */
1576 void rtems_filesystem_initialize( void );
1577 
1578 void rtems_libio_post_driver(void);
1579 
1580 void rtems_libio_exit(void);
1581 
1582 /**
1583  * @brief Creates a directory and all its parent directories according to
1584  * @a path.
1585  *
1586  * The @a mode value selects the access permissions of the directory.
1587  *
1588  * @retval 0 Successful operation.
1589  * @retval -1 An error occurred.  The @c errno indicates the error.
1590  */
1591 extern int rtems_mkdir(const char *path, mode_t mode);
1592 
1593 /** @} */
1594 
1595 /**
1596  * @defgroup FileSystemTypesAndMount File System Types and Mount
1597  *
1598  * @ingroup LibIO
1599  *
1600  * @brief File system types and mount.
1601  */
1602 /**@{**/
1603 
1604 /**
1605  * @name File System Types
1606  */
1607 /**@{**/
1608 
1609 #define RTEMS_FILESYSTEM_TYPE_IMFS "imfs"
1610 #define RTEMS_FILESYSTEM_TYPE_FTPFS "ftpfs"
1611 #define RTEMS_FILESYSTEM_TYPE_TFTPFS "tftpfs"
1612 #define RTEMS_FILESYSTEM_TYPE_NFS "nfs"
1613 #define RTEMS_FILESYSTEM_TYPE_DOSFS "dosfs"
1614 #define RTEMS_FILESYSTEM_TYPE_RFS "rfs"
1615 #define RTEMS_FILESYSTEM_TYPE_JFFS2 "jffs2"
1616 
1617 /** @} */
1618 
1619 /**
1620  * @brief Mount table entry.
1621  */
1622 struct rtems_filesystem_mount_table_entry_tt {
1623   rtems_chain_node                       mt_node;
1624   void                                  *fs_info;
1625   const rtems_filesystem_operations_table *ops;
1626   const void                            *immutable_fs_info;
1627   rtems_chain_control                    location_chain;
1628   rtems_filesystem_global_location_t    *mt_point_node;
1629   rtems_filesystem_global_location_t    *mt_fs_root;
1630   bool                                   mounted;
1631   bool                                   writeable;
1632   bool                                   no_regular_file_mknod;
1633   const rtems_filesystem_limits_and_options_t *pathconf_limits_and_options;
1634 
1635   /*
1636    * The target or mount point of the file system.
1637    */
1638   const char                            *target;
1639 
1640   /*
1641    * The type of filesystem or the name of the filesystem.
1642    */
1643   const char                            *type;
1644 
1645   /*
1646    *  When someone adds a mounted filesystem on a real device,
1647    *  this will need to be used.
1648    *
1649    *  The lower layers can manage how this is managed. Leave as a
1650    *  string.
1651    */
1652   char                                  *dev;
1653 
1654   /**
1655    * The task that initiated the unmount process.  After unmount process
1656    * completion this task will be notified via the transient event.
1657    *
1658    * @see ClassicEventTransient.
1659    */
1660   rtems_id                               unmount_task;
1661 };
1662 
1663 /**
1664  * @brief File system options.
1665  */
1666 typedef enum {
1667   RTEMS_FILESYSTEM_READ_ONLY,
1668   RTEMS_FILESYSTEM_READ_WRITE,
1669   RTEMS_FILESYSTEM_BAD_OPTIONS
1670 } rtems_filesystem_options_t;
1671 
1672 /**
1673  * @brief File system table entry.
1674  */
1675 typedef struct rtems_filesystem_table_t {
1676   const char                    *type;
1677   rtems_filesystem_fsmount_me_t  mount_h;
1678 } rtems_filesystem_table_t;
1679 
1680 /**
1681  * @brief Static table of file systems.
1682  *
1683  * Externally defined by confdefs.h or the user.
1684  */
1685 extern const rtems_filesystem_table_t rtems_filesystem_table [];
1686 
1687 extern rtems_chain_control rtems_filesystem_mount_table;
1688 
1689 /**
1690  * @brief Registers a file system @a type.
1691  *
1692  * The @a mount_h handler will be used to mount a file system of this @a type.
1693  *
1694  * @retval 0 Successful operation.
1695  * @retval -1 An error occurred.  The @c errno indicates the error.
1696  */
1697 int rtems_filesystem_register(
1698   const char                    *type,
1699   rtems_filesystem_fsmount_me_t  mount_h
1700 );
1701 
1702 /**
1703  * @brief Unregisters a file system @a type.
1704  *
1705  * @retval 0 Successful operation.
1706  * @retval -1 An error occurred.  The @c errno indicates the error.
1707  */
1708 int rtems_filesystem_unregister(
1709   const char *type
1710 );
1711 
1712 /**
1713  * @brief Unmounts the file system instance at the specified mount path.
1714  *
1715  * The function waits for the unmount process completion.  In case the calling
1716  * thread uses resources of the unmounted file system the function may never
1717  * return.  In case the calling thread has its root or current directory in the
1718  * unmounted file system the function returns with an error status and errno is
1719  * set to EBUSY.
1720  *
1721  * The unmount process completion notification uses the transient event.  It is
1722  * a fatal error to terminate the calling thread while waiting for this event.
1723  *
1724  * A concurrent unmount request for the same file system instance has
1725  * unpredictable effects.
1726  *
1727  * @param[in] mount_path The path to the file system instance mount point.
1728  *
1729  * @retval 0 Successful operation.
1730  * @retval -1 An error occurred.  The @c errno indicates the error.
1731  *
1732  * @see ClassicEventTransient.
1733  */
1734 int unmount(
1735   const char *mount_path
1736 );
1737 
1738 /**
1739  * @brief Mounts a file system instance at the specified target path.
1740  *
1741  * To mount a standard file system instance one of the following defines should
1742  * be used to select the file system type
1743  * - RTEMS_FILESYSTEM_TYPE_DOSFS,
1744  * - RTEMS_FILESYSTEM_TYPE_FTPFS,
1745  * - RTEMS_FILESYSTEM_TYPE_IMFS,
1746  * - RTEMS_FILESYSTEM_TYPE_JFFS2,
1747  * - RTEMS_FILESYSTEM_TYPE_NFS,
1748  * - RTEMS_FILESYSTEM_TYPE_RFS, or
1749  * - RTEMS_FILESYSTEM_TYPE_TFTPFS.
1750  *
1751  * Only configured or registered file system types are available.  You can add
1752  * file system types to your application configuration with the following
1753  * configuration options
1754  * - CONFIGURE_FILESYSTEM_DOSFS,
1755  * - CONFIGURE_FILESYSTEM_FTPFS,
1756  * - CONFIGURE_FILESYSTEM_IMFS,
1757  * - CONFIGURE_FILESYSTEM_JFFS2,
1758  * - CONFIGURE_FILESYSTEM_NFS,
1759  * - CONFIGURE_FILESYSTEM_RFS, and
1760  * - CONFIGURE_FILESYSTEM_TFTPFS.
1761  *
1762  * In addition to these configuration options file system types can be
1763  * registered with rtems_filesystem_register().
1764  *
1765  * @param[in] source The source parameter will be forwarded to the file system
1766  * initialization handler.  Usually the source is a path to the corresponding
1767  * device file, or @c NULL in case the file system does not use a device file.
1768  * @param[in] target The target path must lead to an existing directory, or
1769  * must be @c NULL.  In case the target is @c NULL, the root file system will
1770  * be mounted.
1771  * @param[in] filesystemtype This string selects the file system type.
1772  * @param[in] options The options specify if the file system instance allows
1773  * read-write or read-only access.
1774  * @param[in] data The data parameter will be forwarded to the file system
1775  * initialization handler.  It can be used to pass file system specific mount
1776  * options.  The data structure for mount options is file system specific.  See
1777  * also in the corresponding file system documentation.
1778  *
1779  * @retval 0 Successful operation.
1780  * @retval -1 An error occurred.  The @c errno indicates the error.
1781  *
1782  * @see rtems_filesystem_register(), mount_and_make_target_path(), @ref DOSFS
1783  * and @ref JFFS2.
1784  */
1785 int mount(
1786   const char                 *source,
1787   const char                 *target,
1788   const char                 *filesystemtype,
1789   rtems_filesystem_options_t options,
1790   const void                 *data
1791 );
1792 
1793 /**
1794  * @brief Mounts a file system and makes the @a target path.
1795  *
1796  * The @a target path will be created with rtems_mkdir() and must not be
1797  * @c NULL.
1798  *
1799  * @see mount().
1800  *
1801  * @retval 0 Successful operation.
1802  * @retval -1 An error occurred.  The @c errno indicates the error.
1803  */
1804 int mount_and_make_target_path(
1805   const char                 *source,
1806   const char                 *target,
1807   const char                 *filesystemtype,
1808   rtems_filesystem_options_t options,
1809   const void                 *data
1810 );
1811 
1812 /**
1813  * @brief Per file system type routine.
1814  *
1815  * @see rtems_filesystem_iterate().
1816  *
1817  * @retval true Stop the iteration.
1818  * @retval false Continue the iteration.
1819  */
1820 typedef bool (*rtems_per_filesystem_routine)(
1821   const rtems_filesystem_table_t *fs_entry,
1822   void *arg
1823 );
1824 
1825 /**
1826  * @brief Iterates over all file system types.
1827  *
1828  * For each file system type the @a routine will be called with the entry and
1829  * the @a routine_arg parameter.
1830  *
1831  * Do not register or unregister file system types in @a routine.
1832  *
1833  * The iteration is protected by the IO library mutex.
1834  *
1835  * @retval true Iteration stopped due to @a routine return status.
1836  * @retval false Iteration through all entries.
1837  */
1838 bool rtems_filesystem_iterate(
1839   rtems_per_filesystem_routine routine,
1840   void *routine_arg
1841 );
1842 
1843 /**
1844  * @brief Mount table entry visitor.
1845  *
1846  * @retval true Stop the iteration.
1847  * @retval false Continue the iteration.
1848  *
1849  * @see rtems_filesystem_mount_iterate().
1850  */
1851 typedef bool (*rtems_filesystem_mt_entry_visitor)(
1852   const rtems_filesystem_mount_table_entry_t *mt_entry,
1853   void *arg
1854 );
1855 
1856 /**
1857  * @brief Iterates over all file system mount entries.
1858  *
1859  * The iteration is protected by the IO library mutex.  Do not mount or unmount
1860  * file systems in the visitor function.
1861  *
1862  * @param[in] visitor For each file system mount entry the visitor function
1863  * will be called with the entry and the visitor argument as parameters.
1864  * @param[in] visitor_arg The second parameter for the visitor function.
1865  *
1866  * @retval true Iteration stopped due to visitor function return status.
1867  * @retval false Iteration through all entries.
1868  */
1869 bool rtems_filesystem_mount_iterate(
1870   rtems_filesystem_mt_entry_visitor visitor,
1871   void *visitor_arg
1872 );
1873 
1874 typedef struct {
1875   const char *source;
1876   const char *target;
1877   const char *filesystemtype;
1878   rtems_filesystem_options_t options;
1879   const void *data;
1880 } rtems_filesystem_mount_configuration;
1881 
1882 extern const rtems_filesystem_mount_configuration
1883   rtems_filesystem_root_configuration;
1884 
1885 /** @} */
1886 
1887 /**
1888  * @defgroup Termios Termios
1889  *
1890  * @ingroup LibIO
1891  *
1892  * @brief Termios
1893  */
1894 /**@{**/
1895 
1896 struct rtems_termios_tty;
1897 
1898 typedef struct rtems_termios_callbacks {
1899   int    (*firstOpen)(int major, int minor, void *arg);
1900   int    (*lastClose)(int major, int minor, void *arg);
1901   int    (*pollRead)(int minor);
1902   ssize_t (*write)(int minor, const char *buf, size_t len);
1903   int    (*setAttributes)(int minor, const struct termios *t);
1904   int    (*stopRemoteTx)(int minor);
1905   int    (*startRemoteTx)(int minor);
1906   rtems_termios_device_mode outputUsesInterrupts;
1907 } rtems_termios_callbacks;
1908 
1909 static inline void rtems_termios_initialize( void )
1910 {
1911   /* Nothing to do, provided for backward compatibility */
1912 }
1913 
1914 /*
1915  * CCJ: Change before opening a tty. Newer code from Eric is coming
1916  * so extra work to handle an open tty is not worth it. If the tty
1917  * is open, close then open it again.
1918  */
1919 rtems_status_code rtems_termios_bufsize (
1920   size_t cbufsize,     /* cooked buffer size */
1921   size_t raw_input,    /* raw input buffer size */
1922   size_t raw_output    /* raw output buffer size */
1923 );
1924 
1925 /**
1926  * @brief The status code returned by all Termios input processing (iproc)
1927  * functions and input signal (isig) handlers.
1928  */
1929 typedef enum {
1930   /**
1931    * @brief This status indicates that the input processing can continue.
1932    *
1933    * Input signal handlers shall return this status if no signal was raised and
1934    * the input processing can continue.
1935    */
1936   RTEMS_TERMIOS_IPROC_CONTINUE,
1937 
1938   /**
1939    * @brief This status indicates that the input processing should stop due to
1940    * a signal.
1941    *
1942    * This indicates that the character was processed and determined to be one
1943    * that requires a signal to be raised (e.g. VINTR or VKILL).  The tty must
1944    * be in the right Termios mode for this to occur.  There is no further
1945    * processing of this character required and the pending read() operation
1946    * should be interrupted.
1947    */
1948   RTEMS_TERMIOS_IPROC_INTERRUPT,
1949 
1950   /**
1951    * @brief This status indicates that the input processing is done.
1952    *
1953    * This status shall not be returned by input processing signal handlers.
1954    */
1955   RTEMS_TERMIOS_IPROC_DONE
1956 } rtems_termios_iproc_status_code;
1957 
1958 /**
1959  * @brief Type for ISIG (VINTR/VKILL) handler
1960  *
1961  * This type defines the interface to a method which will process
1962  * VKILL and VINTR characters. The user can register a handler to
1963  * override the default behavior which is to take no special action
1964  * on these characters. The POSIX required behavior is to
1965  * generate a SIGINTR or SIGQUIT signal. This behavior is implemented if
1966  * the user registers the @ref rtems_termios_posix_isig_handler().
1967  *
1968  * @param c     character that was input
1969  * @param tty   termios structure pointer for this input tty
1970  *
1971  * @return The value returned is according to that documented
1972  *         for @ref rtems_termios_iproc_status_code.
1973  */
1974 typedef rtems_termios_iproc_status_code (*rtems_termios_isig_handler)(
1975   unsigned char             c,
1976   struct rtems_termios_tty *tty
1977 );
1978 
1979 /**
1980  * @brief Default handler for ISIG (VINTR/VKILL)
1981  *
1982  * This handler is installed by default by termios. It performs
1983  * no actions on receiving the VINTR and VKILL characters. This is
1984  * not POSIX conformant behavior but is the historical RTEMS behavior
1985  * and avoid any default dependency on signal processing code.
1986  *
1987  * @param c     character that was input
1988  * @param tty   termios structure pointer for this input tty
1989  *
1990  * The installed ISIG handler is only invoked if the character is
1991  * (VKILL or VINTR) and ISIG is enabled. Thus the handler need only
1992  * check the character and perform the appropriate action.
1993  *
1994  * @return The value returned is according to that documented
1995  *         for all methods adhering to @ref rtems_termios_isig_handler.
1996  */
1997 rtems_termios_iproc_status_code rtems_termios_default_isig_handler(
1998   unsigned char             c,
1999   struct rtems_termios_tty *tty
2000 );
2001 
2002 /**
2003  * @brief POSIX handler for ISIG (VINTR/VKILL)
2004  *
2005  * This handler is installed by the used to obtain POSIX behavior
2006  * upon receiving the VINTR and VKILL characters.  The POSIX required
2007  * behavior is to generate a SIGINTR or SIGQUIT signal if ISIG is enabled.
2008  *
2009  * @param c     character that was input
2010  * @param tty   termios structure pointer for this input tty
2011  *
2012  * @return The value returned is according to that documented
2013  *         for all methods adhering to @ref rtems_termios_isig_handler.
2014  */
2015 rtems_termios_iproc_status_code rtems_termios_posix_isig_handler(
2016   unsigned char             c,
2017   struct rtems_termios_tty *tty
2018 );
2019 
2020 /**
2021  * @brief Register handler for ISIG (VINTR/VKILL)
2022  *
2023  * This method is invoked to install an ISIG handler. This may be used
2024  * to install @ref rtems_termios_posix_isig_handler() to obtain POSIX
2025  * behavior or a custom handler. The handler
2026  * @ref rtems_termios_default_isig_handler() is installed by default.
2027  *
2028  * @param handler entry point of the new ISIG handler
2029  *
2030  * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful.
2031  */
2032 rtems_status_code rtems_termios_register_isig_handler(
2033   rtems_termios_isig_handler handler
2034 );
2035 
2036 int rtems_termios_enqueue_raw_characters(
2037   void *ttyp,
2038   const char *buf,
2039   int   len
2040 );
2041 
2042 rtems_status_code rtems_termios_open (
2043   rtems_device_major_number      major,
2044   rtems_device_minor_number      minor,
2045   void                          *arg,
2046   const rtems_termios_callbacks *callbacks
2047 );
2048 
2049 rtems_status_code rtems_termios_close(
2050   void *arg
2051 );
2052 
2053 rtems_status_code rtems_termios_read(
2054   void *arg
2055 );
2056 
2057 rtems_status_code rtems_termios_write(
2058   void *arg
2059 );
2060 
2061 rtems_status_code rtems_termios_ioctl(
2062   void *arg
2063 );
2064 
2065 int rtems_termios_dequeue_characters(
2066   void *ttyp,
2067   int   len
2068 );
2069 
2070 /** @} */
2071 
2072 /**
2073  * @brief The pathconf setting for a file system.
2074  */
2075 #define rtems_filesystem_pathconf(_mte) ((_mte)->pathconf_limits_and_options)
2076 
2077 /**
2078  * @brief The type of file system. Its name.
2079  */
2080 #define rtems_filesystem_type(_mte) ((_mte)->type)
2081 
2082 /**
2083  * @brief The mount point of a file system.
2084  */
2085 #define rtems_filesystem_mount_point(_mte) ((_mte)->target)
2086 
2087 /**
2088  * @brief The device entry of a file system.
2089  */
2090 #define rtems_filesystem_mount_device(_mte) ((_mte)->dev)
2091 
2092 #ifdef __cplusplus
2093 }
2094 #endif
2095 
2096 #endif /* _RTEMS_LIBIO_H */