RTEMS CPU Kit with SuperCore  4.11.99.0
libio_.h
Go to the documentation of this file.
1 
9 /*
10  * COPYRIGHT (c) 1989-2011.
11  * On-Line Applications Research Corporation (OAR).
12  *
13  * Modifications to support reference counting in the file system are
14  * Copyright (c) 2012 embedded brains GmbH.
15  *
16  * The license and distribution terms for this file may be
17  * found in the file LICENSE in this distribution or at
18  * http://www.rtems.org/license/LICENSE.
19  */
20 
21 #ifndef _RTEMS_RTEMS_LIBIO__H
22 #define _RTEMS_RTEMS_LIBIO__H
23 
24 #include <sys/uio.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <pthread.h>
28 
29 #include <rtems.h>
30 #include <rtems/libio.h>
31 #include <rtems/seterr.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
45 #define RTEMS_FILESYSTEM_SYMLOOP_MAX 32
46 
47 /*
48  * Not defined in newlib so provide here. Users should use dup2 and
49  * not this non-portable fcntl command. Provided here to allow the
50  * RTEMS implementation to work.
51  */
52 #define F_DUP2FD 20
53 
54 /*
55  * Semaphore to protect the io table
56  */
57 
58 #define RTEMS_LIBIO_SEM rtems_build_name('L', 'B', 'I', 'O')
59 #define RTEMS_LIBIO_IOP_SEM(n) rtems_build_name('L', 'B', 'I', n)
60 
61 extern rtems_id rtems_libio_semaphore;
62 
63 /*
64  * File descriptor Table Information
65  */
66 
67 extern const uint32_t rtems_libio_number_iops;
68 extern rtems_libio_t rtems_libio_iops[];
69 extern rtems_libio_t *rtems_libio_iop_freelist;
70 
71 extern const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers;
72 
73 extern rtems_filesystem_mount_table_entry_t rtems_filesystem_null_mt_entry;
74 
91 
92 /*
93  * rtems_libio_iop
94  *
95  * Macro to return the file descriptor pointer.
96  */
97 
98 #define rtems_libio_iop(_fd) \
99  ((((uint32_t)(_fd)) < rtems_libio_number_iops) ? \
100  &rtems_libio_iops[_fd] : 0)
101 
102 /*
103  * rtems_libio_iop_to_descriptor
104  *
105  * Macro to convert an internal file descriptor pointer (iop) into
106  * the integer file descriptor used by the "section 2" system calls.
107  */
108 
109 #define rtems_libio_iop_to_descriptor(_iop) \
110  ((_iop) - &rtems_libio_iops[0])
111 
112 /*
113  * rtems_libio_check_is_open
114  *
115  * Macro to check if a file descriptor is actually open.
116  */
117 
118 #define rtems_libio_check_is_open(_iop) \
119  do { \
120  if (((_iop)->flags & LIBIO_FLAGS_OPEN) == 0) { \
121  errno = EBADF; \
122  return -1; \
123  } \
124  } while (0)
125 
126 /*
127  * rtems_libio_check_fd
128  *
129  * Macro to check if a file descriptor number is valid.
130  */
131 
132 #define rtems_libio_check_fd(_fd) \
133  do { \
134  if ((uint32_t) (_fd) >= rtems_libio_number_iops) { \
135  errno = EBADF; \
136  return -1; \
137  } \
138  } while (0)
139 
140 /*
141  * rtems_libio_check_buffer
142  *
143  * Macro to check if a buffer pointer is valid.
144  */
145 
146 #define rtems_libio_check_buffer(_buffer) \
147  do { \
148  if ((_buffer) == 0) { \
149  errno = EINVAL; \
150  return -1; \
151  } \
152  } while (0)
153 
154 /*
155  * rtems_libio_check_count
156  *
157  * Macro to check if a count or length is valid.
158  */
159 
160 #define rtems_libio_check_count(_count) \
161  do { \
162  if ((_count) == 0) { \
163  return 0; \
164  } \
165  } while (0)
166 
167 /*
168  * rtems_libio_check_permissions_with_error
169  *
170  * Macro to check if a file descriptor is open for this operation.
171  * On failure, return the user specified error.
172  */
173 
174 #define rtems_libio_check_permissions_with_error(_iop, _flag, _errno) \
175  do { \
176  if (((_iop)->flags & (_flag)) == 0) { \
177  rtems_set_errno_and_return_minus_one( _errno ); \
178  return -1; \
179  } \
180  } while (0)
181 
182 /*
183  * rtems_libio_check_permissions
184  *
185  * Macro to check if a file descriptor is open for this operation.
186  * On failure, return EINVAL
187  */
188 
189 #define rtems_libio_check_permissions(_iop, _flag) \
190  rtems_libio_check_permissions_with_error(_iop, _flag, EINVAL )
191 
205 );
206 
220 
221 /*
222  * External structures
223  */
224 #include <rtems/userenv.h>
225 
226 void rtems_libio_free_user_env( void *env );
227 
228 extern pthread_key_t rtems_current_user_env_key;
229 
230 static inline void rtems_libio_lock( void )
231 {
232  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
233 }
234 
235 static inline void rtems_libio_unlock( void )
236 {
237  rtems_semaphore_release( rtems_libio_semaphore );
238 }
239 
240 static inline void rtems_filesystem_mt_lock( void )
241 {
242  rtems_libio_lock();
243 }
244 
245 static inline void rtems_filesystem_mt_unlock( void )
246 {
247  rtems_libio_unlock();
248 }
249 
250 extern rtems_interrupt_lock rtems_filesystem_mt_entry_lock_control;
251 
252 #define rtems_filesystem_mt_entry_declare_lock_context( ctx ) \
253  rtems_interrupt_lock_context ctx
254 
255 #define rtems_filesystem_mt_entry_lock( ctx ) \
256  rtems_interrupt_lock_acquire( &rtems_filesystem_mt_entry_lock_control, &ctx )
257 
258 #define rtems_filesystem_mt_entry_unlock( ctx ) \
259  rtems_interrupt_lock_release( &rtems_filesystem_mt_entry_lock_control, &ctx )
260 
261 static inline void rtems_filesystem_instance_lock(
263 )
264 {
265  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
266 
267  (*mt_entry->ops->lock_h)( mt_entry );
268 }
269 
270 static inline void rtems_filesystem_instance_unlock(
272 )
273 {
274  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
275 
276  (*mt_entry->ops->unlock_h)( mt_entry );
277 }
278 
279 /*
280  * File Descriptor Routine Prototypes
281  */
282 
288 
292 uint32_t rtems_libio_fcntl_flags( int fcntl_flags );
293 
297 int rtems_libio_to_fcntl_flags( uint32_t flags );
298 
303 void rtems_libio_free(
304  rtems_libio_t *iop
305 );
306 
307 /*
308  * File System Routine Prototypes
309  */
310 
312 rtems_filesystem_eval_path_start(
314  const char *path,
315  int eval_flags
316 );
317 
319 rtems_filesystem_eval_path_start_with_parent(
321  const char *path,
322  int eval_flags,
324  int parent_eval_flags
325 );
326 
328 rtems_filesystem_eval_path_start_with_root_and_current(
330  const char *path,
331  int eval_flags,
332  rtems_filesystem_global_location_t *const *global_root_ptr,
333  rtems_filesystem_global_location_t *const *global_current_ptr
334 );
335 
336 void rtems_filesystem_eval_path_continue(
338 );
339 
340 void rtems_filesystem_eval_path_cleanup(
342 );
343 
344 void rtems_filesystem_eval_path_recursive(
346  const char *path,
347  size_t pathlen
348 );
349 
350 void rtems_filesystem_eval_path_cleanup_with_parent(
353 );
354 
370  rtems_filesystem_global_location_t **newstartloc_ptr
371 );
372 
373 typedef enum {
374  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE,
375  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE,
376  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY
377 } rtems_filesystem_eval_path_generic_status;
378 
392  void *arg
393 );
394 
407 typedef rtems_filesystem_eval_path_generic_status
410  void *arg,
411  const char *token,
412  size_t tokenlen
413 );
414 
415 typedef struct {
419 
420 void rtems_filesystem_eval_path_generic(
422  void *arg,
424 );
425 
426 void rtems_filesystem_initialize(void);
427 
444 );
445 
446 static inline rtems_filesystem_location_info_t *
447 rtems_filesystem_location_initialize_to_null(
449 )
450 {
452  loc,
453  &rtems_filesystem_global_location_null.location
454  );
455 }
456 
458 rtems_filesystem_location_transform_to_global(
460 );
461 
470  rtems_filesystem_global_location_t **lhs_global_loc_ptr,
471  rtems_filesystem_global_location_t *rhs_global_loc
472 );
473 
494  rtems_filesystem_global_location_t *const *global_loc_ptr
495 );
496 
514 );
515 
516 void rtems_filesystem_location_detach(
518 );
519 
520 void rtems_filesystem_location_copy_and_detach(
523 );
524 
526 rtems_filesystem_global_location_obtain_null(void)
527 {
528  rtems_filesystem_global_location_t *global_loc = NULL;
529 
530  return rtems_filesystem_global_location_obtain( &global_loc );
531 }
532 
533 static inline bool rtems_filesystem_location_is_null(
535 )
536 {
537  return loc->handlers == &rtems_filesystem_null_handlers;
538 }
539 
540 static inline bool rtems_filesystem_global_location_is_null(
541  const rtems_filesystem_global_location_t *global_loc
542 )
543 {
544  return rtems_filesystem_location_is_null( &global_loc->location );
545 }
546 
547 static inline void rtems_filesystem_location_error(
549  int eno
550 )
551 {
552  if ( !rtems_filesystem_location_is_null( loc ) ) {
553  errno = eno;
554  }
555 }
556 
557 int rtems_filesystem_mknod(
558  const rtems_filesystem_location_info_t *parentloc,
559  const char *name,
560  size_t namelen,
561  mode_t mode,
562  dev_t dev
563 );
564 
565 int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc );
566 
567 int rtems_filesystem_chmod(
569  mode_t mode
570 );
571 
572 int rtems_filesystem_chown(
574  uid_t owner,
575  gid_t group
576 );
577 
578 static inline bool rtems_filesystem_is_ready_for_unmount(
580 )
581 {
582  bool ready = !mt_entry->mounted
583  && rtems_chain_has_only_one_node( &mt_entry->location_chain )
584  && mt_entry->mt_fs_root->reference_count == 1;
585 
586  if ( ready ) {
587  rtems_chain_initialize_empty( &mt_entry->location_chain );
588  }
589 
590  return ready;
591 }
592 
593 static inline void rtems_filesystem_location_add_to_mt_entry(
595 )
596 {
597  rtems_filesystem_mt_entry_declare_lock_context( lock_context );
598 
599  rtems_filesystem_mt_entry_lock( lock_context );
601  &loc->mt_entry->location_chain,
602  &loc->mt_entry_node
603  );
604  rtems_filesystem_mt_entry_unlock( lock_context );
605 }
606 
607 void rtems_filesystem_location_remove_from_mt_entry(
609 );
610 
611 void rtems_filesystem_do_unmount(
613 );
614 
615 static inline bool rtems_filesystem_location_is_instance_root(
617 )
618 {
619  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
620 
621  return (*mt_entry->ops->are_nodes_equal_h)(
622  loc,
623  &mt_entry->mt_fs_root->location
624  );
625 }
626 
627 static inline const char *rtems_filesystem_eval_path_get_path(
629 )
630 {
631  return ctx->path;
632 }
633 
634 static inline size_t rtems_filesystem_eval_path_get_pathlen(
636 )
637 {
638  return ctx->pathlen;
639 }
640 
641 static inline void rtems_filesystem_eval_path_set_path(
643  const char *path,
644  size_t pathlen
645 )
646 {
647  ctx->path = path;
648  ctx->pathlen = pathlen;
649 }
650 
651 static inline void rtems_filesystem_eval_path_clear_path(
653 )
654 {
655  ctx->pathlen = 0;
656 }
657 
658 static inline const char *rtems_filesystem_eval_path_get_token(
660 )
661 {
662  return ctx->token;
663 }
664 
665 static inline size_t rtems_filesystem_eval_path_get_tokenlen(
667 )
668 {
669  return ctx->tokenlen;
670 }
671 
672 static inline void rtems_filesystem_eval_path_set_token(
674  const char *token,
675  size_t tokenlen
676 )
677 {
678  ctx->token = token;
679  ctx->tokenlen = tokenlen;
680 }
681 
682 static inline void rtems_filesystem_eval_path_clear_token(
684 )
685 {
686  ctx->tokenlen = 0;
687 }
688 
689 static inline void rtems_filesystem_eval_path_put_back_token(
691 )
692 {
693  size_t tokenlen = ctx->tokenlen;
694 
695  ctx->path -= tokenlen;
696  ctx->pathlen += tokenlen;
697  ctx->tokenlen = 0;
698 }
699 
700 void rtems_filesystem_eval_path_eat_delimiter(
702 );
703 
704 void rtems_filesystem_eval_path_next_token(
706 );
707 
708 static inline void rtems_filesystem_eval_path_get_next_token(
710  const char **token,
711  size_t *tokenlen
712 )
713 {
714  rtems_filesystem_eval_path_next_token(ctx);
715  *token = ctx->token;
716  *tokenlen = ctx->tokenlen;
717 }
718 
719 static inline rtems_filesystem_location_info_t *
720 rtems_filesystem_eval_path_get_currentloc(
722 )
723 {
724  return &ctx->currentloc;
725 }
726 
727 static inline bool rtems_filesystem_eval_path_has_path(
729 )
730 {
731  return ctx->pathlen > 0;
732 }
733 
734 static inline bool rtems_filesystem_eval_path_has_token(
736 )
737 {
738  return ctx->tokenlen > 0;
739 }
740 
741 static inline int rtems_filesystem_eval_path_get_flags(
743 )
744 {
745  return ctx->flags;
746 }
747 
748 static inline void rtems_filesystem_eval_path_set_flags(
750  int flags
751 )
752 {
753  ctx->flags = flags;
754 }
755 
756 static inline void rtems_filesystem_eval_path_clear_and_set_flags(
758  int clear,
759  int set
760 )
761 {
762  int flags = ctx->flags;
763 
764  flags &= ~clear;
765  flags |= set;
766 
767  ctx->flags = flags;
768 }
769 
770 static inline void rtems_filesystem_eval_path_extract_currentloc(
773 )
774 {
775  rtems_filesystem_location_copy_and_detach(
776  get,
777  &ctx->currentloc
778  );
779 }
780 
781 void rtems_filesystem_eval_path_error(
783  int eno
784 );
785 
795 );
796 
817  int flags,
818  mode_t object_mode,
819  uid_t object_uid,
820  gid_t object_gid
821 );
822 
823 bool rtems_filesystem_eval_path_check_access(
825  int eval_flags,
826  mode_t node_mode,
827  uid_t node_uid,
828  gid_t node_gid
829 );
830 
831 static inline bool rtems_filesystem_is_delimiter(char c)
832 {
833  return c == '/' || c == '\\';
834 }
835 
836 static inline bool rtems_filesystem_is_current_directory(
837  const char *token,
838  size_t tokenlen
839 )
840 {
841  return tokenlen == 1 && token [0] == '.';
842 }
843 
844 static inline bool rtems_filesystem_is_parent_directory(
845  const char *token,
846  size_t tokenlen
847 )
848 {
849  return tokenlen == 2 && token [0] == '.' && token [1] == '.';
850 }
851 
852 static inline ssize_t rtems_libio_iovec_eval(
853  int fd,
854  const struct iovec *iov,
855  int iovcnt,
856  uint32_t flags,
857  rtems_libio_t **iopp
858 )
859 {
860  ssize_t total;
861  int v;
862  rtems_libio_t *iop;
863 
864  rtems_libio_check_fd( fd );
865  iop = rtems_libio_iop( fd );
866  rtems_libio_check_is_open( iop );
867  rtems_libio_check_permissions_with_error( iop, flags, EBADF );
868 
869  *iopp = iop;
870 
871  /*
872  * Argument validation on IO vector
873  */
874  if ( iov == NULL )
876 
877  if ( iovcnt <= 0 )
879 
880  if ( iovcnt > IOV_MAX )
882 
883  /*
884  * OpenGroup says that you are supposed to return EINVAL if the
885  * sum of the iov_len values in the iov array would overflow a
886  * ssize_t.
887  */
888  total = 0;
889  for ( v = 0 ; v < iovcnt ; ++v ) {
890  size_t len = iov[ v ].iov_len;
891 
892  if ( len > ( size_t ) ( SSIZE_MAX - total ) ) {
894  }
895 
896  total += ( ssize_t ) len;
897 
898  if ( iov[ v ].iov_base == NULL && len != 0 ) {
900  }
901  }
902 
903  return total;
904 }
905 
914 static inline mode_t rtems_filesystem_location_type(
916 )
917 {
918  struct stat st;
919 
920  st.st_mode = 0;
921  (void) ( *loc->handlers->fstat_h )( loc, &st );
922 
923  return st.st_mode;
924 }
925 
928 #ifdef __cplusplus
929 }
930 #endif
931 
932 #endif
933 /* end of include file */
void rtems_filesystem_initialize(void)
Base File System Initialization.
RTEMS_INLINE_ROUTINE bool rtems_chain_has_only_one_node(const rtems_chain_control *the_chain)
Does this chain have only one node.
Definition: chain.h:507
const char * token
The contents of the token to be evaluated with respect to the current location.
Definition: libio.h:98
RTEMS_INLINE_ROUTINE void rtems_chain_initialize_empty(rtems_chain_control *the_chain)
Initialize this chain as empty.
Definition: chain.h:168
int rtems_filesystem_location_exists_in_same_instance_as(const rtems_filesystem_location_info_t *a, const rtems_filesystem_location_info_t *b)
Checks that the locations exist in the same file system instance.
Basic IO API.
Data which Ease the Burden of Consistently Setting Errno.
Objects_Id rtems_id
Used to manage and manipulate RTEMS object identifiers.
Definition: types.h:80
User Environment Support.
int flags
The path evaluation is controlled by the following flags.
Definition: libio.h:118
void rtems_filesystem_global_location_release(rtems_filesystem_global_location_t *global_loc)
Releases a global file system location.
POSIX Threads Private Support.
rtems_filesystem_global_location_t rtems_filesystem_global_location_null
The global null location.
void rtems_libio_free(rtems_libio_t *iop)
This routine frees the resources associated with an IOP (file descriptor) and clears the slot in the ...
void rtems_filesystem_global_location_assign(rtems_filesystem_global_location_t **lhs_global_loc_ptr, rtems_filesystem_global_location_t *rhs_global_loc)
Assigns a global file system location.
size_t tokenlen
The length of the token to be evaluated with respect to the current location.
Definition: libio.h:104
ISR lock control.
Definition: isrlock.h:56
File system node operations table.
Definition: libio.h:982
RTEMS_INLINE_ROUTINE void rtems_chain_append_unprotected(rtems_chain_control *the_chain, rtems_chain_node *the_node)
Append a node on the end of a chain (unprotected).
Definition: chain.h:702
void rtems_filesystem_location_clone(rtems_filesystem_location_info_t *clone, const rtems_filesystem_location_info_t *master)
Clones a node.
bool(* rtems_filesystem_eval_path_is_directory)(rtems_filesystem_eval_path_context_t *ctx, void *arg)
Tests if the current location is a directory.
Definition: libio_.h:390
#define rtems_set_errno_and_return_minus_one(_error)
This is a helper macro which will set the variable errno and return -1 to the caller.
Definition: seterr.h:48
rtems_status_code rtems_semaphore_release(rtems_id id)
RTEMS Semaphore Release.
rtems_filesystem_location_info_t currentloc
This is the current file system location of the evaluation process.
Definition: libio.h:134
rtems_status_code rtems_semaphore_obtain(rtems_id id, rtems_option option_set, rtems_interval timeout)
RTEMS Obtain Semaphore.
void rtems_filesystem_location_free(rtems_filesystem_location_info_t *loc)
Releases all resources of a location.
uint32_t rtems_libio_fcntl_flags(int fcntl_flags)
Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand.
#define RTEMS_NO_TIMEOUT
Constant for indefinite wait.
Definition: rtems.h:169
#define RTEMS_WAIT
This option constants indicates that the task is to wait on resource.
Definition: options.h:56
rtems_filesystem_eval_path_generic_status(* rtems_filesystem_eval_path_eval_token)(rtems_filesystem_eval_path_context_t *ctx, void *arg, const char *token, size_t tokenlen)
Evaluates a token.
Definition: libio_.h:408
Mount table entry.
Definition: libio.h:1542
Path evaluation context.
Definition: libio.h:83
int rtems_libio_to_fcntl_flags(uint32_t flags)
Convert RTEMS internal flags to UNIX fnctl(2) flags.
An open file data structure.
Definition: libio.h:1281
bool rtems_filesystem_check_access(int flags, mode_t object_mode, uid_t object_uid, gid_t object_gid)
Checks if access to an object is allowed for the current user.
const char * path
The contents of the remaining path to be evaluated.
Definition: libio.h:87
rtems_libio_t * rtems_libio_allocate(void)
This routine searches the IOP Table for an unused entry.
rtems_filesystem_global_location_t * rtems_filesystem_global_location_obtain(rtems_filesystem_global_location_t *const *global_loc_ptr)
Obtains a global file system location.
size_t pathlen
The length of the remaining path to be evaluated.
Definition: libio.h:92
void rtems_filesystem_eval_path_restart(rtems_filesystem_eval_path_context_t *ctx, rtems_filesystem_global_location_t **newstartloc_ptr)
Requests a path evaluation restart.
rtems_filesystem_location_info_t * rtems_filesystem_location_copy(rtems_filesystem_location_info_t *dst, const rtems_filesystem_location_info_t *src)
Copies a location.
Global file system location.
Definition: fs.h:81
File system location.
Definition: fs.h:53