RTEMS CPU Kit with SuperCore  4.10.99.0
rtems/libio_.h
Go to the documentation of this file.
00001 
00009 /*
00010  *  COPYRIGHT (c) 1989-2011.
00011  *  On-Line Applications Research Corporation (OAR).
00012  *
00013  *  Modifications to support reference counting in the file system are
00014  *  Copyright (c) 2012 embedded brains GmbH.
00015  *
00016  *  The license and distribution terms for this file may be
00017  *  found in the file LICENSE in this distribution or at
00018  *  http://www.rtems.com/license/LICENSE.
00019  */
00020 
00021 #ifndef _RTEMS_RTEMS_LIBIO__H
00022 #define _RTEMS_RTEMS_LIBIO__H
00023 
00024 #include <errno.h>
00025 
00026 #include <rtems.h>
00027 #include <rtems/libio.h>
00028 #include <rtems/seterr.h>
00029 
00030 #ifdef __cplusplus
00031 extern "C" {
00032 #endif
00033 
00042 #define RTEMS_FILESYSTEM_SYMLOOP_MAX 32
00043 
00044 /*
00045  *  Semaphore to protect the io table
00046  */
00047 
00048 #define RTEMS_LIBIO_SEM         rtems_build_name('L', 'B', 'I', 'O')
00049 #define RTEMS_LIBIO_IOP_SEM(n)  rtems_build_name('L', 'B', 'I', n)
00050 
00051 extern rtems_id                          rtems_libio_semaphore;
00052 
00053 /*
00054  *  File descriptor Table Information
00055  */
00056 
00057 extern uint32_t        rtems_libio_number_iops;
00058 extern rtems_libio_t  *rtems_libio_iops;
00059 extern rtems_libio_t  *rtems_libio_last_iop;
00060 extern rtems_libio_t *rtems_libio_iop_freelist;
00061 
00062 extern const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers;
00063 
00064 extern rtems_filesystem_mount_table_entry_t rtems_filesystem_null_mt_entry;
00065 
00081 extern rtems_filesystem_global_location_t rtems_filesystem_global_location_null;
00082 
00083 /*
00084  *  rtems_libio_iop
00085  *
00086  *  Macro to return the file descriptor pointer.
00087  */
00088 
00089 #define rtems_libio_iop(_fd) \
00090   ((((uint32_t)(_fd)) < rtems_libio_number_iops) ? \
00091          &rtems_libio_iops[_fd] : 0)
00092 
00093 /*
00094  *  rtems_libio_iop_to_descriptor
00095  *
00096  *  Macro to convert an internal file descriptor pointer (iop) into
00097  *  the integer file descriptor used by the "section 2" system calls.
00098  */
00099 
00100 #define rtems_libio_iop_to_descriptor(_iop) \
00101    ((!(_iop)) ? -1 : (_iop - rtems_libio_iops))
00102 
00103 /*
00104  *  rtems_libio_check_is_open
00105  *
00106  *  Macro to check if a file descriptor is actually open.
00107  */
00108 
00109 #define rtems_libio_check_is_open(_iop) \
00110   do {                                               \
00111       if (((_iop)->flags & LIBIO_FLAGS_OPEN) == 0) { \
00112           errno = EBADF;                             \
00113           return -1;                                 \
00114       }                                              \
00115   } while (0)
00116 
00117 /*
00118  *  rtems_libio_check_fd
00119  *
00120  *  Macro to check if a file descriptor number is valid.
00121  */
00122 
00123 #define rtems_libio_check_fd(_fd) \
00124   do {                                                     \
00125       if ((uint32_t) (_fd) >= rtems_libio_number_iops) {   \
00126           errno = EBADF;                                   \
00127           return -1;                                       \
00128       }                                                    \
00129   } while (0)
00130 
00131 /*
00132  *  rtems_libio_check_buffer
00133  *
00134  *  Macro to check if a buffer pointer is valid.
00135  */
00136 
00137 #define rtems_libio_check_buffer(_buffer) \
00138   do {                                    \
00139       if ((_buffer) == 0) {               \
00140           errno = EINVAL;                 \
00141           return -1;                      \
00142       }                                   \
00143   } while (0)
00144 
00145 /*
00146  *  rtems_libio_check_count
00147  *
00148  *  Macro to check if a count or length is valid.
00149  */
00150 
00151 #define rtems_libio_check_count(_count) \
00152   do {                                  \
00153       if ((_count) == 0) {              \
00154           return 0;                     \
00155       }                                 \
00156   } while (0)
00157 
00158 /*
00159  *  rtems_libio_check_permissions_with_error
00160  *
00161  *  Macro to check if a file descriptor is open for this operation.
00162  *  On failure, return the user specified error.
00163  */
00164 
00165 #define rtems_libio_check_permissions_with_error(_iop, _flag, _errno) \
00166   do {                                                      \
00167       if (((_iop)->flags & (_flag)) == 0) {                 \
00168             rtems_set_errno_and_return_minus_one( _errno ); \
00169             return -1;                                      \
00170       }                                                     \
00171   } while (0)
00172 
00173 /*
00174  *  rtems_libio_check_permissions
00175  *
00176  *  Macro to check if a file descriptor is open for this operation.
00177  *  On failure, return EINVAL
00178  */
00179 
00180 #define rtems_libio_check_permissions(_iop, _flag) \
00181    rtems_libio_check_permissions_with_error(_iop, _flag, EINVAL )
00182 
00193 void rtems_filesystem_location_clone(
00194   rtems_filesystem_location_info_t *clone,
00195   const rtems_filesystem_location_info_t *master
00196 );
00197 
00209 rtems_filesystem_node_types_t rtems_filesystem_node_type(
00210   const rtems_filesystem_location_info_t *loc
00211 );
00212 
00225 void rtems_filesystem_location_free( rtems_filesystem_location_info_t *loc );
00226 
00227 /*
00228  *  External structures
00229  */
00230 #include <rtems/userenv.h>
00231 
00232 static inline void rtems_libio_lock( void )
00233 {
00234   rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
00235 }
00236 
00237 static inline void rtems_libio_unlock( void )
00238 {
00239   rtems_semaphore_release( rtems_libio_semaphore );
00240 }
00241 
00242 static inline void rtems_filesystem_mt_lock( void )
00243 {
00244   rtems_libio_lock();
00245 }
00246 
00247 static inline void rtems_filesystem_mt_unlock( void )
00248 {
00249   rtems_libio_unlock();
00250 }
00251 
00252 #define rtems_filesystem_mt_entry_declare_lock_context( ctx ) \
00253   rtems_interrupt_level ctx
00254 
00255 #define rtems_filesystem_mt_entry_lock( ctx ) rtems_interrupt_disable( ctx )
00256 
00257 #define rtems_filesystem_mt_entry_unlock( ctx ) rtems_interrupt_enable( ctx )
00258 
00259 static inline void rtems_filesystem_instance_lock(
00260   const rtems_filesystem_location_info_t *loc
00261 )
00262 {
00263   const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
00264 
00265   (*mt_entry->ops->lock_h)( mt_entry );
00266 }
00267 
00268 static inline void rtems_filesystem_instance_unlock(
00269   const rtems_filesystem_location_info_t *loc
00270 )
00271 {
00272   const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
00273 
00274   (*mt_entry->ops->unlock_h)( mt_entry );
00275 }
00276 
00277 /*
00278  *  File Descriptor Routine Prototypes
00279  */
00280 
00285 rtems_libio_t *rtems_libio_allocate(void);
00286 
00290 uint32_t rtems_libio_fcntl_flags( int fcntl_flags );
00291 
00295 int rtems_libio_to_fcntl_flags( uint32_t flags );
00296 
00301 void rtems_libio_free(
00302   rtems_libio_t *iop
00303 );
00304 
00305 /*
00306  *  File System Routine Prototypes
00307  */
00308 
00309 rtems_filesystem_location_info_t *
00310 rtems_filesystem_eval_path_start(
00311   rtems_filesystem_eval_path_context_t *ctx,
00312   const char *path,
00313   int eval_flags
00314 );
00315 
00316 rtems_filesystem_location_info_t *
00317 rtems_filesystem_eval_path_start_with_parent(
00318   rtems_filesystem_eval_path_context_t *ctx,
00319   const char *path,
00320   int eval_flags,
00321   rtems_filesystem_location_info_t *parentloc,
00322   int parent_eval_flags
00323 );
00324 
00325 rtems_filesystem_location_info_t *
00326 rtems_filesystem_eval_path_start_with_root_and_current(
00327   rtems_filesystem_eval_path_context_t *ctx,
00328   const char *path,
00329   int eval_flags,
00330   rtems_filesystem_global_location_t *const *global_root_ptr,
00331   rtems_filesystem_global_location_t *const *global_current_ptr
00332 );
00333 
00334 void rtems_filesystem_eval_path_continue(
00335   rtems_filesystem_eval_path_context_t *ctx
00336 );
00337 
00338 void rtems_filesystem_eval_path_cleanup(
00339   rtems_filesystem_eval_path_context_t *ctx
00340 );
00341 
00342 void rtems_filesystem_eval_path_recursive(
00343   rtems_filesystem_eval_path_context_t *ctx,
00344   const char *path,
00345   size_t pathlen
00346 );
00347 
00348 void rtems_filesystem_eval_path_cleanup_with_parent(
00349   rtems_filesystem_eval_path_context_t *ctx,
00350   rtems_filesystem_location_info_t *parentloc
00351 );
00352 
00366 void rtems_filesystem_eval_path_restart(
00367   rtems_filesystem_eval_path_context_t *ctx,
00368   rtems_filesystem_global_location_t **newstartloc_ptr
00369 );
00370 
00371 typedef enum {
00372   RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE,
00373   RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE,
00374   RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY
00375 } rtems_filesystem_eval_path_generic_status;
00376 
00388 typedef bool (*rtems_filesystem_eval_path_is_directory)(
00389   rtems_filesystem_eval_path_context_t *ctx,
00390   void *arg
00391 );
00392 
00405 typedef rtems_filesystem_eval_path_generic_status
00406 (*rtems_filesystem_eval_path_eval_token)(
00407   rtems_filesystem_eval_path_context_t *ctx,
00408   void *arg,
00409   const char *token,
00410   size_t tokenlen
00411 );
00412 
00413 typedef struct {
00414   rtems_filesystem_eval_path_is_directory is_directory;
00415   rtems_filesystem_eval_path_eval_token eval_token;
00416 } rtems_filesystem_eval_path_generic_config;
00417 
00418 void rtems_filesystem_eval_path_generic(
00419   rtems_filesystem_eval_path_context_t *ctx,
00420   void *arg,
00421   const rtems_filesystem_eval_path_generic_config *config
00422 );
00423 
00424 void rtems_filesystem_initialize(void);
00425 
00439 rtems_filesystem_location_info_t *rtems_filesystem_location_copy(
00440   rtems_filesystem_location_info_t *dst,
00441   const rtems_filesystem_location_info_t *src
00442 );
00443 
00444 static inline rtems_filesystem_location_info_t *
00445 rtems_filesystem_location_initialize_to_null(
00446   rtems_filesystem_location_info_t *loc
00447 )
00448 {
00449   return rtems_filesystem_location_copy(
00450     loc,
00451     &rtems_filesystem_global_location_null.location
00452   );
00453 }
00454 
00455 rtems_filesystem_global_location_t *
00456 rtems_filesystem_location_transform_to_global(
00457   rtems_filesystem_location_info_t *loc
00458 );
00459 
00467 void rtems_filesystem_global_location_assign(
00468   rtems_filesystem_global_location_t **lhs_global_loc_ptr,
00469   rtems_filesystem_global_location_t *rhs_global_loc
00470 );
00471 
00491 rtems_filesystem_global_location_t *rtems_filesystem_global_location_obtain(
00492   rtems_filesystem_global_location_t *const *global_loc_ptr
00493 );
00494 
00510 void rtems_filesystem_global_location_release(
00511   rtems_filesystem_global_location_t *global_loc
00512 );
00513 
00514 void rtems_filesystem_location_detach(
00515   rtems_filesystem_location_info_t *detach
00516 );
00517 
00518 void rtems_filesystem_location_copy_and_detach(
00519   rtems_filesystem_location_info_t *copy,
00520   rtems_filesystem_location_info_t *detach
00521 );
00522 
00523 static inline rtems_filesystem_global_location_t *
00524 rtems_filesystem_global_location_obtain_null(void)
00525 {
00526   rtems_filesystem_global_location_t *global_loc = NULL;
00527 
00528   return rtems_filesystem_global_location_obtain( &global_loc );
00529 }
00530 
00531 static inline bool rtems_filesystem_location_is_null(
00532   const rtems_filesystem_location_info_t *loc
00533 )
00534 {
00535   return loc->handlers == &rtems_filesystem_null_handlers;
00536 }
00537 
00538 static inline bool rtems_filesystem_global_location_is_null(
00539   const rtems_filesystem_global_location_t *global_loc
00540 )
00541 {
00542   return rtems_filesystem_location_is_null( &global_loc->location );
00543 }
00544 
00545 static inline void rtems_filesystem_location_error(
00546   const rtems_filesystem_location_info_t *loc,
00547   int eno
00548 )
00549 {
00550   if ( !rtems_filesystem_location_is_null( loc ) ) {
00551     errno = eno;
00552   }
00553 }
00554 
00555 int rtems_filesystem_mknod(
00556   const rtems_filesystem_location_info_t *parentloc,
00557   const char *name,
00558   size_t namelen,
00559   mode_t mode,
00560   dev_t dev
00561 );
00562 
00563 int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc );
00564 
00565 int rtems_filesystem_chown(
00566   const char *path,
00567   uid_t owner,
00568   gid_t group,
00569   int eval_follow_link
00570 );
00571 
00572 static inline bool rtems_filesystem_is_ready_for_unmount(
00573   rtems_filesystem_mount_table_entry_t *mt_entry
00574 )
00575 {
00576   bool ready = !mt_entry->mounted
00577     && rtems_chain_has_only_one_node( &mt_entry->location_chain )
00578     && mt_entry->mt_fs_root->reference_count == 1;
00579 
00580   if ( ready ) {
00581     rtems_chain_initialize_empty( &mt_entry->location_chain );
00582   }
00583 
00584   return ready;
00585 }
00586 
00587 static inline void rtems_filesystem_location_add_to_mt_entry(
00588   rtems_filesystem_location_info_t *loc
00589 )
00590 {
00591   rtems_filesystem_mt_entry_declare_lock_context( lock_context );
00592 
00593   rtems_filesystem_mt_entry_lock( lock_context );
00594   rtems_chain_append_unprotected(
00595     &loc->mt_entry->location_chain,
00596     &loc->mt_entry_node
00597   );
00598   rtems_filesystem_mt_entry_unlock( lock_context );
00599 }
00600 
00601 void rtems_filesystem_location_remove_from_mt_entry(
00602   rtems_filesystem_location_info_t *loc
00603 );
00604 
00605 void rtems_filesystem_do_unmount(
00606   rtems_filesystem_mount_table_entry_t *mt_entry
00607 );
00608 
00609 static inline bool rtems_filesystem_location_is_instance_root(
00610   const rtems_filesystem_location_info_t *loc
00611 )
00612 {
00613   const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
00614 
00615   return (*mt_entry->ops->are_nodes_equal_h)(
00616     loc,
00617     &mt_entry->mt_fs_root->location
00618   );
00619 }
00620 
00621 static inline const char *rtems_filesystem_eval_path_get_path(
00622   rtems_filesystem_eval_path_context_t *ctx
00623 )
00624 {
00625   return ctx->path;
00626 }
00627 
00628 static inline size_t rtems_filesystem_eval_path_get_pathlen(
00629   rtems_filesystem_eval_path_context_t *ctx
00630 )
00631 {
00632   return ctx->pathlen;
00633 }
00634 
00635 static inline void rtems_filesystem_eval_path_set_path(
00636   rtems_filesystem_eval_path_context_t *ctx,
00637   const char *path,
00638   size_t pathlen
00639 )
00640 {
00641   ctx->path = path;
00642   ctx->pathlen = pathlen;
00643 }
00644 
00645 static inline void rtems_filesystem_eval_path_clear_path(
00646   rtems_filesystem_eval_path_context_t *ctx
00647 )
00648 {
00649   ctx->pathlen = 0;
00650 }
00651 
00652 static inline const char *rtems_filesystem_eval_path_get_token(
00653   rtems_filesystem_eval_path_context_t *ctx
00654 )
00655 {
00656   return ctx->token;
00657 }
00658 
00659 static inline size_t rtems_filesystem_eval_path_get_tokenlen(
00660   rtems_filesystem_eval_path_context_t *ctx
00661 )
00662 {
00663   return ctx->tokenlen;
00664 }
00665 
00666 static inline void rtems_filesystem_eval_path_set_token(
00667   rtems_filesystem_eval_path_context_t *ctx,
00668   const char *token,
00669   size_t tokenlen
00670 )
00671 {
00672   ctx->token = token;
00673   ctx->tokenlen = tokenlen;
00674 }
00675 
00676 static inline void rtems_filesystem_eval_path_clear_token(
00677   rtems_filesystem_eval_path_context_t *ctx
00678 )
00679 {
00680   ctx->tokenlen = 0;
00681 }
00682 
00683 static inline void rtems_filesystem_eval_path_put_back_token(
00684   rtems_filesystem_eval_path_context_t *ctx
00685 )
00686 {
00687   size_t tokenlen = ctx->tokenlen;
00688 
00689   ctx->path -= tokenlen;
00690   ctx->pathlen += tokenlen;
00691   ctx->tokenlen = 0;
00692 }
00693 
00694 void rtems_filesystem_eval_path_eat_delimiter(
00695   rtems_filesystem_eval_path_context_t *ctx
00696 );
00697 
00698 void rtems_filesystem_eval_path_next_token(
00699   rtems_filesystem_eval_path_context_t *ctx
00700 );
00701 
00702 static inline void rtems_filesystem_eval_path_get_next_token(
00703   rtems_filesystem_eval_path_context_t *ctx,
00704   const char **token,
00705   size_t *tokenlen
00706 )
00707 {
00708   rtems_filesystem_eval_path_next_token(ctx);
00709   *token = ctx->token;
00710   *tokenlen = ctx->tokenlen;
00711 }
00712 
00713 static inline rtems_filesystem_location_info_t *
00714 rtems_filesystem_eval_path_get_currentloc(
00715   rtems_filesystem_eval_path_context_t *ctx
00716 )
00717 {
00718   return &ctx->currentloc;
00719 }
00720 
00721 static inline bool rtems_filesystem_eval_path_has_path(
00722   const rtems_filesystem_eval_path_context_t *ctx
00723 )
00724 {
00725   return ctx->pathlen > 0;
00726 }
00727 
00728 static inline bool rtems_filesystem_eval_path_has_token(
00729   const rtems_filesystem_eval_path_context_t *ctx
00730 )
00731 {
00732   return ctx->tokenlen > 0;
00733 }
00734 
00735 static inline int rtems_filesystem_eval_path_get_flags(
00736   const rtems_filesystem_eval_path_context_t *ctx
00737 )
00738 {
00739   return ctx->flags;
00740 }
00741 
00742 static inline void rtems_filesystem_eval_path_set_flags(
00743   rtems_filesystem_eval_path_context_t *ctx,
00744   int flags
00745 )
00746 {
00747   ctx->flags = flags;
00748 }
00749 
00750 static inline void rtems_filesystem_eval_path_clear_and_set_flags(
00751   rtems_filesystem_eval_path_context_t *ctx,
00752   int clear,
00753   int set
00754 )
00755 {
00756   int flags = ctx->flags;
00757 
00758   flags &= ~clear;
00759   flags |= set;
00760 
00761   ctx->flags = flags;
00762 }
00763 
00764 static inline void rtems_filesystem_eval_path_extract_currentloc(
00765   rtems_filesystem_eval_path_context_t *ctx,
00766   rtems_filesystem_location_info_t *get
00767 )
00768 {
00769   rtems_filesystem_location_copy_and_detach(
00770     get,
00771     &ctx->currentloc
00772   );
00773 }
00774 
00775 void rtems_filesystem_eval_path_error(
00776   rtems_filesystem_eval_path_context_t *ctx,
00777   int eno
00778 );
00779 
00786 int rtems_filesystem_location_exists_in_same_instance_as(
00787   const rtems_filesystem_location_info_t *a,
00788   const rtems_filesystem_location_info_t *b
00789 );
00790 
00791 bool rtems_filesystem_check_access(
00792   int eval_flags,
00793   mode_t node_mode,
00794   uid_t node_uid,
00795   gid_t node_gid
00796 );
00797 
00798 bool rtems_filesystem_eval_path_check_access(
00799   rtems_filesystem_eval_path_context_t *ctx,
00800   int eval_flags,
00801   mode_t node_mode,
00802   uid_t node_uid,
00803   gid_t node_gid
00804 );
00805 
00806 static inline bool rtems_filesystem_is_delimiter(char c)
00807 {
00808   return c == '/' || c == '\\';
00809 }
00810 
00811 static inline bool rtems_filesystem_is_current_directory(
00812   const char *token,
00813   size_t tokenlen
00814 )
00815 {
00816   return tokenlen == 1 && token [0] == '.';
00817 }
00818 
00819 static inline bool rtems_filesystem_is_parent_directory(
00820   const char *token,
00821   size_t tokenlen
00822 )
00823 {
00824   return tokenlen == 2 && token [0] == '.' && token [1] == '.';
00825 }
00826 
00829 #ifdef __cplusplus
00830 }
00831 #endif
00832 
00833 #endif
00834 /* end of include file */