File indexing completed on 2025-05-11 08:24:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #ifndef _RTEMS_RTEMS_LIBIO__H
0040 #define _RTEMS_RTEMS_LIBIO__H
0041
0042 #include <sys/uio.h>
0043 #include <errno.h>
0044 #include <limits.h>
0045 #include <pthread.h>
0046
0047 #include <rtems.h>
0048 #include <rtems/libio.h>
0049 #include <rtems/seterr.h>
0050 #include <rtems/score/assert.h>
0051 #include <rtems/score/timespec.h>
0052
0053 #ifdef __cplusplus
0054 extern "C" {
0055 #endif
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 #define RTEMS_FILESYSTEM_SYMLOOP_MAX 32
0068
0069
0070
0071
0072
0073
0074 #define F_DUP2FD 20
0075
0076
0077
0078
0079
0080 extern const uint32_t rtems_libio_number_iops;
0081 extern rtems_libio_t rtems_libio_iops[];
0082 extern void *rtems_libio_iop_free_head;
0083 extern void **rtems_libio_iop_free_tail;
0084
0085 extern const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers;
0086
0087 extern rtems_filesystem_mount_table_entry_t rtems_filesystem_null_mt_entry;
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 extern rtems_filesystem_global_location_t rtems_filesystem_global_location_null;
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 static inline unsigned int rtems_libio_iop_flags_set(
0115 rtems_libio_t *iop,
0116 unsigned int set
0117 )
0118 {
0119 return _Atomic_Fetch_or_uint( &iop->flags, set, ATOMIC_ORDER_RELAXED );
0120 }
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 static inline unsigned int rtems_libio_iop_flags_clear(
0131 rtems_libio_t *iop,
0132 unsigned int clear
0133 )
0134 {
0135 return _Atomic_Fetch_and_uint( &iop->flags, ~clear, ATOMIC_ORDER_RELAXED );
0136 }
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 static inline rtems_libio_t *rtems_libio_iop( int fd )
0148 {
0149 return &rtems_libio_iops[ fd ];
0150 }
0151
0152
0153
0154
0155
0156
0157
0158
0159 static inline unsigned int rtems_libio_iop_hold( rtems_libio_t *iop )
0160 {
0161 return _Atomic_Fetch_add_uint(
0162 &iop->flags,
0163 LIBIO_FLAGS_REFERENCE_INC,
0164 ATOMIC_ORDER_ACQUIRE
0165 );
0166 }
0167
0168
0169
0170
0171
0172
0173 static inline void rtems_libio_iop_drop( rtems_libio_t *iop )
0174 {
0175 #if defined(RTEMS_DEBUG)
0176 unsigned int flags;
0177 bool success;
0178
0179 flags = _Atomic_Load_uint( &iop->flags, ATOMIC_ORDER_RELAXED );
0180
0181 do {
0182 unsigned int desired;
0183
0184 _Assert( flags >= LIBIO_FLAGS_REFERENCE_INC );
0185
0186 desired = flags - LIBIO_FLAGS_REFERENCE_INC;
0187 success = _Atomic_Compare_exchange_uint(
0188 &iop->flags,
0189 &flags,
0190 desired,
0191 ATOMIC_ORDER_RELEASE,
0192 ATOMIC_ORDER_RELAXED
0193 );
0194 } while ( !success );
0195 #else
0196 _Atomic_Fetch_sub_uint(
0197 &iop->flags,
0198 LIBIO_FLAGS_REFERENCE_INC,
0199 ATOMIC_ORDER_RELEASE
0200 );
0201 #endif
0202 }
0203
0204
0205
0206
0207
0208
0209
0210
0211 #define rtems_libio_iop_to_descriptor(_iop) \
0212 ((_iop) - &rtems_libio_iops[0])
0213
0214
0215
0216
0217
0218
0219
0220 #define rtems_libio_check_is_open(_iop) \
0221 do { \
0222 if ((rtems_libio_iop_flags(_iop) & LIBIO_FLAGS_OPEN) == 0) { \
0223 errno = EBADF; \
0224 return -1; \
0225 } \
0226 } while (0)
0227
0228
0229
0230
0231
0232
0233 #define LIBIO_GET_IOP( _fd, _iop ) \
0234 do { \
0235 unsigned int _flags; \
0236 if ( (uint32_t) ( _fd ) >= rtems_libio_number_iops ) { \
0237 rtems_set_errno_and_return_minus_one( EBADF ); \
0238 } \
0239 _iop = rtems_libio_iop( _fd ); \
0240 _flags = rtems_libio_iop_hold( _iop ); \
0241 if ( ( _flags & LIBIO_FLAGS_OPEN ) == 0 ) { \
0242 rtems_libio_iop_drop( _iop ); \
0243 rtems_set_errno_and_return_minus_one( EBADF ); \
0244 } \
0245 } while ( 0 )
0246
0247
0248
0249
0250
0251
0252
0253 #define LIBIO_GET_IOP_WITH_ACCESS( _fd, _iop, _access_flags, _access_error ) \
0254 do { \
0255 unsigned int _flags; \
0256 unsigned int _mandatory; \
0257 if ( (uint32_t) ( _fd ) >= rtems_libio_number_iops ) { \
0258 rtems_set_errno_and_return_minus_one( EBADF ); \
0259 } \
0260 _iop = rtems_libio_iop( _fd ); \
0261 _flags = rtems_libio_iop_hold( _iop ); \
0262 _mandatory = LIBIO_FLAGS_OPEN | ( _access_flags ); \
0263 if ( ( _flags & _mandatory ) != _mandatory ) { \
0264 int _error; \
0265 rtems_libio_iop_drop( _iop ); \
0266 if ( ( _flags & LIBIO_FLAGS_OPEN ) == 0 ) { \
0267 _error = EBADF; \
0268 } else { \
0269 _error = _access_error; \
0270 } \
0271 rtems_set_errno_and_return_minus_one( _error ); \
0272 } \
0273 } while ( 0 )
0274
0275
0276
0277
0278
0279
0280
0281 #define rtems_libio_check_buffer(_buffer) \
0282 do { \
0283 if ((_buffer) == 0) { \
0284 errno = EINVAL; \
0285 return -1; \
0286 } \
0287 } while (0)
0288
0289
0290
0291
0292
0293
0294
0295 #define rtems_libio_check_count(_count) \
0296 do { \
0297 if ((_count) == 0) { \
0298 return 0; \
0299 } \
0300 } while (0)
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 void rtems_filesystem_location_clone(
0313 rtems_filesystem_location_info_t *clone,
0314 const rtems_filesystem_location_info_t *master
0315 );
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329 void rtems_filesystem_location_free( rtems_filesystem_location_info_t *loc );
0330
0331
0332
0333
0334 #include <rtems/userenv.h>
0335
0336 void rtems_libio_lock( void );
0337
0338 void rtems_libio_unlock( void );
0339
0340 static inline void rtems_filesystem_mt_lock( void )
0341 {
0342 rtems_libio_lock();
0343 }
0344
0345 static inline void rtems_filesystem_mt_unlock( void )
0346 {
0347 rtems_libio_unlock();
0348 }
0349
0350 extern rtems_interrupt_lock rtems_filesystem_mt_entry_lock_control;
0351
0352 #define rtems_filesystem_mt_entry_declare_lock_context( ctx ) \
0353 rtems_interrupt_lock_context ctx
0354
0355 #define rtems_filesystem_mt_entry_lock( ctx ) \
0356 rtems_interrupt_lock_acquire( &rtems_filesystem_mt_entry_lock_control, &ctx )
0357
0358 #define rtems_filesystem_mt_entry_unlock( ctx ) \
0359 rtems_interrupt_lock_release( &rtems_filesystem_mt_entry_lock_control, &ctx )
0360
0361 static inline void rtems_filesystem_instance_lock(
0362 const rtems_filesystem_location_info_t *loc
0363 )
0364 {
0365 const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
0366
0367 (*mt_entry->ops->lock_h)( mt_entry );
0368 }
0369
0370 static inline void rtems_filesystem_instance_unlock(
0371 const rtems_filesystem_location_info_t *loc
0372 )
0373 {
0374 const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
0375
0376 (*mt_entry->ops->unlock_h)( mt_entry );
0377 }
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 bool rtems_filesystem_utime_tv_nsec_valid( struct timespec time );
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409 int rtems_filesystem_utime_check_permissions(
0410 const rtems_filesystem_location_info_t *currentloc,
0411 const struct timespec times[2]
0412 );
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 int rtems_filesystem_utime_update(
0434 const struct timespec times[2],
0435 struct timespec new_times[2]
0436 );
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446 rtems_libio_t *rtems_libio_allocate(void);
0447
0448
0449
0450
0451 unsigned int rtems_libio_fcntl_flags( int fcntl_flags );
0452
0453
0454
0455
0456 int rtems_libio_to_fcntl_flags( unsigned int flags );
0457
0458
0459
0460
0461
0462 void rtems_libio_free(
0463 rtems_libio_t *iop
0464 );
0465
0466
0467
0468
0469 int rtems_libio_count_open_iops( void );
0470
0471
0472
0473
0474
0475 rtems_filesystem_location_info_t *
0476 rtems_filesystem_eval_path_start(
0477 rtems_filesystem_eval_path_context_t *ctx,
0478 const char *path,
0479 int eval_flags
0480 );
0481
0482 rtems_filesystem_location_info_t *
0483 rtems_filesystem_eval_path_start_with_parent(
0484 rtems_filesystem_eval_path_context_t *ctx,
0485 const char *path,
0486 int eval_flags,
0487 rtems_filesystem_location_info_t *parentloc,
0488 int parent_eval_flags
0489 );
0490
0491 rtems_filesystem_location_info_t *
0492 rtems_filesystem_eval_path_start_with_root_and_current(
0493 rtems_filesystem_eval_path_context_t *ctx,
0494 const char *path,
0495 size_t pathlen,
0496 int eval_flags,
0497 rtems_filesystem_global_location_t *const *global_root_ptr,
0498 rtems_filesystem_global_location_t *const *global_current_ptr
0499 );
0500
0501 void rtems_filesystem_eval_path_continue(
0502 rtems_filesystem_eval_path_context_t *ctx
0503 );
0504
0505 void rtems_filesystem_eval_path_cleanup(
0506 rtems_filesystem_eval_path_context_t *ctx
0507 );
0508
0509 void rtems_filesystem_eval_path_recursive(
0510 rtems_filesystem_eval_path_context_t *ctx,
0511 const char *path,
0512 size_t pathlen
0513 );
0514
0515 void rtems_filesystem_eval_path_cleanup_with_parent(
0516 rtems_filesystem_eval_path_context_t *ctx,
0517 rtems_filesystem_location_info_t *parentloc
0518 );
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533 void rtems_filesystem_eval_path_restart(
0534 rtems_filesystem_eval_path_context_t *ctx,
0535 rtems_filesystem_global_location_t **newstartloc_ptr
0536 );
0537
0538 typedef enum {
0539 RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE,
0540 RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE,
0541 RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY
0542 } rtems_filesystem_eval_path_generic_status;
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555 typedef bool (*rtems_filesystem_eval_path_is_directory)(
0556 rtems_filesystem_eval_path_context_t *ctx,
0557 void *arg
0558 );
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 typedef rtems_filesystem_eval_path_generic_status
0573 (*rtems_filesystem_eval_path_eval_token)(
0574 rtems_filesystem_eval_path_context_t *ctx,
0575 void *arg,
0576 const char *token,
0577 size_t tokenlen
0578 );
0579
0580 typedef struct {
0581 rtems_filesystem_eval_path_is_directory is_directory;
0582 rtems_filesystem_eval_path_eval_token eval_token;
0583 } rtems_filesystem_eval_path_generic_config;
0584
0585 void rtems_filesystem_eval_path_generic(
0586 rtems_filesystem_eval_path_context_t *ctx,
0587 void *arg,
0588 const rtems_filesystem_eval_path_generic_config *config
0589 );
0590
0591 void rtems_filesystem_initialize(void);
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606 rtems_filesystem_location_info_t *rtems_filesystem_location_copy(
0607 rtems_filesystem_location_info_t *dst,
0608 const rtems_filesystem_location_info_t *src
0609 );
0610
0611 static inline rtems_filesystem_location_info_t *
0612 rtems_filesystem_location_initialize_to_null(
0613 rtems_filesystem_location_info_t *loc
0614 )
0615 {
0616 return rtems_filesystem_location_copy(
0617 loc,
0618 &rtems_filesystem_global_location_null.location
0619 );
0620 }
0621
0622 rtems_filesystem_global_location_t *
0623 rtems_filesystem_location_transform_to_global(
0624 rtems_filesystem_location_info_t *loc
0625 );
0626
0627
0628
0629
0630
0631
0632
0633
0634 void rtems_filesystem_global_location_assign(
0635 rtems_filesystem_global_location_t **lhs_global_loc_ptr,
0636 rtems_filesystem_global_location_t *rhs_global_loc
0637 );
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658 rtems_filesystem_global_location_t *rtems_filesystem_global_location_obtain(
0659 rtems_filesystem_global_location_t *const *global_loc_ptr
0660 );
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679 void rtems_filesystem_global_location_release(
0680 rtems_filesystem_global_location_t *global_loc,
0681 bool deferred
0682 );
0683
0684 void rtems_filesystem_location_detach(
0685 rtems_filesystem_location_info_t *detach
0686 );
0687
0688 void rtems_filesystem_location_copy_and_detach(
0689 rtems_filesystem_location_info_t *copy,
0690 rtems_filesystem_location_info_t *detach
0691 );
0692
0693 static inline rtems_filesystem_global_location_t *
0694 rtems_filesystem_global_location_obtain_null(void)
0695 {
0696 rtems_filesystem_global_location_t *global_loc = NULL;
0697
0698 return rtems_filesystem_global_location_obtain( &global_loc );
0699 }
0700
0701 static inline bool rtems_filesystem_location_is_null(
0702 const rtems_filesystem_location_info_t *loc
0703 )
0704 {
0705 return loc->handlers == &rtems_filesystem_null_handlers;
0706 }
0707
0708 static inline bool rtems_filesystem_global_location_is_null(
0709 const rtems_filesystem_global_location_t *global_loc
0710 )
0711 {
0712 return rtems_filesystem_location_is_null( &global_loc->location );
0713 }
0714
0715 static inline void rtems_filesystem_location_error(
0716 const rtems_filesystem_location_info_t *loc,
0717 int eno
0718 )
0719 {
0720 if ( !rtems_filesystem_location_is_null( loc ) ) {
0721 errno = eno;
0722 }
0723 }
0724
0725 int rtems_filesystem_mknod(
0726 const rtems_filesystem_location_info_t *parentloc,
0727 const char *name,
0728 size_t namelen,
0729 mode_t mode,
0730 dev_t dev
0731 );
0732
0733 int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc );
0734
0735 int rtems_filesystem_chmod(
0736 const rtems_filesystem_location_info_t *loc,
0737 mode_t mode
0738 );
0739
0740 int rtems_filesystem_chown(
0741 const rtems_filesystem_location_info_t *loc,
0742 uid_t owner,
0743 gid_t group
0744 );
0745
0746 static inline bool rtems_filesystem_is_ready_for_unmount(
0747 rtems_filesystem_mount_table_entry_t *mt_entry
0748 )
0749 {
0750 bool ready = !mt_entry->mounted
0751 && rtems_chain_has_only_one_node( &mt_entry->location_chain )
0752 && mt_entry->mt_fs_root->reference_count == 1;
0753
0754 if ( ready ) {
0755 rtems_chain_initialize_empty( &mt_entry->location_chain );
0756 }
0757
0758 return ready;
0759 }
0760
0761 static inline void rtems_filesystem_location_add_to_mt_entry(
0762 rtems_filesystem_location_info_t *loc
0763 )
0764 {
0765 rtems_filesystem_mt_entry_declare_lock_context( lock_context );
0766
0767 rtems_filesystem_mt_entry_lock( lock_context );
0768 rtems_chain_append_unprotected(
0769 &loc->mt_entry->location_chain,
0770 &loc->mt_entry_node
0771 );
0772 rtems_filesystem_mt_entry_unlock( lock_context );
0773 }
0774
0775 void rtems_filesystem_location_remove_from_mt_entry(
0776 rtems_filesystem_location_info_t *loc
0777 );
0778
0779 void rtems_filesystem_do_unmount(
0780 rtems_filesystem_mount_table_entry_t *mt_entry
0781 );
0782
0783 static inline bool rtems_filesystem_location_is_instance_root(
0784 const rtems_filesystem_location_info_t *loc
0785 )
0786 {
0787 const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
0788
0789 return (*mt_entry->ops->are_nodes_equal_h)(
0790 loc,
0791 &mt_entry->mt_fs_root->location
0792 );
0793 }
0794
0795 static inline const char *rtems_filesystem_eval_path_get_path(
0796 const rtems_filesystem_eval_path_context_t *ctx
0797 )
0798 {
0799 return ctx->path;
0800 }
0801
0802 static inline size_t rtems_filesystem_eval_path_get_pathlen(
0803 const rtems_filesystem_eval_path_context_t *ctx
0804 )
0805 {
0806 return ctx->pathlen;
0807 }
0808
0809 static inline void rtems_filesystem_eval_path_set_path(
0810 rtems_filesystem_eval_path_context_t *ctx,
0811 const char *path,
0812 size_t pathlen
0813 )
0814 {
0815 ctx->path = path;
0816 ctx->pathlen = pathlen;
0817 }
0818
0819 static inline void rtems_filesystem_eval_path_clear_path(
0820 rtems_filesystem_eval_path_context_t *ctx
0821 )
0822 {
0823 ctx->pathlen = 0;
0824 }
0825
0826 static inline const char *rtems_filesystem_eval_path_get_token(
0827 const rtems_filesystem_eval_path_context_t *ctx
0828 )
0829 {
0830 return ctx->token;
0831 }
0832
0833 static inline size_t rtems_filesystem_eval_path_get_tokenlen(
0834 const rtems_filesystem_eval_path_context_t *ctx
0835 )
0836 {
0837 return ctx->tokenlen;
0838 }
0839
0840 static inline void rtems_filesystem_eval_path_set_token(
0841 rtems_filesystem_eval_path_context_t *ctx,
0842 const char *token,
0843 size_t tokenlen
0844 )
0845 {
0846 ctx->token = token;
0847 ctx->tokenlen = tokenlen;
0848 }
0849
0850 static inline void rtems_filesystem_eval_path_clear_token(
0851 rtems_filesystem_eval_path_context_t *ctx
0852 )
0853 {
0854 ctx->tokenlen = 0;
0855 }
0856
0857 static inline void rtems_filesystem_eval_path_put_back_token(
0858 rtems_filesystem_eval_path_context_t *ctx
0859 )
0860 {
0861 size_t tokenlen = ctx->tokenlen;
0862
0863 ctx->path -= tokenlen;
0864 ctx->pathlen += tokenlen;
0865 ctx->tokenlen = 0;
0866 }
0867
0868 void rtems_filesystem_eval_path_eat_delimiter(
0869 rtems_filesystem_eval_path_context_t *ctx
0870 );
0871
0872 void rtems_filesystem_eval_path_next_token(
0873 rtems_filesystem_eval_path_context_t *ctx
0874 );
0875
0876 static inline void rtems_filesystem_eval_path_get_next_token(
0877 rtems_filesystem_eval_path_context_t *ctx,
0878 const char **token,
0879 size_t *tokenlen
0880 )
0881 {
0882 rtems_filesystem_eval_path_next_token(ctx);
0883 *token = ctx->token;
0884 *tokenlen = ctx->tokenlen;
0885 }
0886
0887 static inline rtems_filesystem_location_info_t *
0888 rtems_filesystem_eval_path_get_currentloc(
0889 rtems_filesystem_eval_path_context_t *ctx
0890 )
0891 {
0892 return &ctx->currentloc;
0893 }
0894
0895 static inline bool rtems_filesystem_eval_path_has_path(
0896 const rtems_filesystem_eval_path_context_t *ctx
0897 )
0898 {
0899 return ctx->pathlen > 0;
0900 }
0901
0902 static inline bool rtems_filesystem_eval_path_has_token(
0903 const rtems_filesystem_eval_path_context_t *ctx
0904 )
0905 {
0906 return ctx->tokenlen > 0;
0907 }
0908
0909 static inline int rtems_filesystem_eval_path_get_flags(
0910 const rtems_filesystem_eval_path_context_t *ctx
0911 )
0912 {
0913 return ctx->flags;
0914 }
0915
0916 static inline void rtems_filesystem_eval_path_set_flags(
0917 rtems_filesystem_eval_path_context_t *ctx,
0918 int flags
0919 )
0920 {
0921 ctx->flags = flags;
0922 }
0923
0924 static inline void rtems_filesystem_eval_path_clear_and_set_flags(
0925 rtems_filesystem_eval_path_context_t *ctx,
0926 int clear,
0927 int set
0928 )
0929 {
0930 int flags = ctx->flags;
0931
0932 flags &= ~clear;
0933 flags |= set;
0934
0935 ctx->flags = flags;
0936 }
0937
0938 static inline void rtems_filesystem_eval_path_extract_currentloc(
0939 rtems_filesystem_eval_path_context_t *ctx,
0940 rtems_filesystem_location_info_t *get
0941 )
0942 {
0943 rtems_filesystem_location_copy_and_detach(
0944 get,
0945 &ctx->currentloc
0946 );
0947 }
0948
0949 void rtems_filesystem_eval_path_error(
0950 rtems_filesystem_eval_path_context_t *ctx,
0951 int eno
0952 );
0953
0954
0955
0956
0957
0958
0959
0960 int rtems_filesystem_location_exists_in_same_instance_as(
0961 const rtems_filesystem_location_info_t *a,
0962 const rtems_filesystem_location_info_t *b
0963 );
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984 bool rtems_filesystem_check_access(
0985 int flags,
0986 mode_t object_mode,
0987 uid_t object_uid,
0988 gid_t object_gid
0989 );
0990
0991 bool rtems_filesystem_eval_path_check_access(
0992 rtems_filesystem_eval_path_context_t *ctx,
0993 int eval_flags,
0994 mode_t node_mode,
0995 uid_t node_uid,
0996 gid_t node_gid
0997 );
0998
0999 static inline bool rtems_filesystem_is_delimiter(char c)
1000 {
1001 return c == '/' || c == '\\';
1002 }
1003
1004 static inline bool rtems_filesystem_is_current_directory(
1005 const char *token,
1006 size_t tokenlen
1007 )
1008 {
1009 return tokenlen == 1 && token [0] == '.';
1010 }
1011
1012 static inline bool rtems_filesystem_is_parent_directory(
1013 const char *token,
1014 size_t tokenlen
1015 )
1016 {
1017 return tokenlen == 2 && token [0] == '.' && token [1] == '.';
1018 }
1019
1020 typedef ssize_t ( *rtems_libio_iovec_adapter )(
1021 rtems_libio_t *iop,
1022 const struct iovec *iov,
1023 int iovcnt,
1024 ssize_t total
1025 );
1026
1027 static inline ssize_t rtems_libio_iovec_eval(
1028 int fd,
1029 const struct iovec *iov,
1030 int iovcnt,
1031 unsigned int flags,
1032 rtems_libio_iovec_adapter adapter
1033 )
1034 {
1035 ssize_t total;
1036 int v;
1037 rtems_libio_t *iop;
1038
1039
1040
1041
1042 if ( iov == NULL )
1043 rtems_set_errno_and_return_minus_one( EINVAL );
1044
1045 if ( iovcnt <= 0 )
1046 rtems_set_errno_and_return_minus_one( EINVAL );
1047
1048 if ( iovcnt > IOV_MAX )
1049 rtems_set_errno_and_return_minus_one( EINVAL );
1050
1051
1052
1053
1054
1055
1056 total = 0;
1057 for ( v = 0 ; v < iovcnt ; ++v ) {
1058 size_t len = iov[ v ].iov_len;
1059
1060 if ( len > ( size_t ) ( SSIZE_MAX - total ) ) {
1061 rtems_set_errno_and_return_minus_one( EINVAL );
1062 }
1063
1064 total += ( ssize_t ) len;
1065
1066 if ( iov[ v ].iov_base == NULL && len != 0 ) {
1067 rtems_set_errno_and_return_minus_one( EINVAL );
1068 }
1069 }
1070
1071 LIBIO_GET_IOP_WITH_ACCESS( fd, iop, flags, EBADF );
1072
1073 if ( total > 0 ) {
1074 total = ( *adapter )( iop, iov, iovcnt, total );
1075 }
1076
1077 rtems_libio_iop_drop( iop );
1078 return total;
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089 static inline mode_t rtems_filesystem_location_type(
1090 const rtems_filesystem_location_info_t *loc
1091 )
1092 {
1093 struct stat st;
1094
1095 st.st_mode = 0;
1096 (void) ( *loc->handlers->fstat_h )( loc, &st );
1097
1098 return st.st_mode;
1099 }
1100
1101
1102
1103 #ifdef __cplusplus
1104 }
1105 #endif
1106
1107 #endif
1108