source: rtems/cpukit/include/rtems/libio_.h @ 7e86e00

5
Last change on this file since 7e86e00 was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

  • Property mode set to 100644
File size: 25.9 KB
Line 
1/**
2 * @file
3 *
4 * @brief LibIO Internal Interface
5 *
6 * This file is the libio internal interface.
7 */
8
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#include <rtems/score/assert.h>
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38/**
39 * @defgroup LibIOInternal IO Internal Library
40 *
41 * @brief Internal IO library API and implementation.
42 *
43 */
44/**@{**/
45
46#define RTEMS_FILESYSTEM_SYMLOOP_MAX 32
47
48/*
49 * Not defined in newlib so provide here. Users should use dup2 and
50 * not this non-portable fcntl command. Provided here to allow the
51 * RTEMS implementation to work.
52 */
53#define F_DUP2FD 20
54
55/*
56 *  File descriptor Table Information
57 */
58
59extern const uint32_t rtems_libio_number_iops;
60extern rtems_libio_t rtems_libio_iops[];
61extern void *rtems_libio_iop_free_head;
62extern void **rtems_libio_iop_free_tail;
63
64extern const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers;
65
66extern rtems_filesystem_mount_table_entry_t rtems_filesystem_null_mt_entry;
67
68/**
69 * @brief The global null location.
70 *
71 * Every operation and the open and fstat handlers of this location returns an
72 * error status.  The errno is not touched by these operations and handlers.
73 * The purpose of this location is to deliver the error return status for a
74 * previous error condition which must set the errno accordingly.
75 *
76 * The usage of this null location instead of the NULL pointer eliminates
77 * a lot of branches.
78 *
79 * The user environment root and current directory are statically initialized
80 * with the null location.  Due to that all file system services are in a
81 * defined state even if no root file system was mounted.
82 */
83extern rtems_filesystem_global_location_t rtems_filesystem_global_location_null;
84
85/**
86 * @brief Sets the iop flags to the specified flags together with
87 * LIBIO_FLAGS_OPEN.
88 *
89 * Use this once a file descriptor allocated via rtems_libio_allocate() is
90 * fully initialized.
91 *
92 * @param[in] iop The iop.
93 * @param[in] flags The flags.
94 */
95static inline void rtems_libio_iop_flags_initialize(
96  rtems_libio_t *iop,
97  uint32_t       flags
98)
99{
100  _Atomic_Store_uint(
101    &iop->flags,
102    LIBIO_FLAGS_OPEN | flags,
103    ATOMIC_ORDER_RELEASE
104  );
105}
106
107/**
108 * @brief Sets the specified flags in the iop.
109 *
110 * @param[in] iop The iop.
111 * @param[in] set The flags to set.
112 *
113 * @return The previous flags.
114 */
115static inline unsigned int rtems_libio_iop_flags_set(
116  rtems_libio_t *iop,
117  unsigned int   set
118)
119{
120  return _Atomic_Fetch_or_uint( &iop->flags, set, ATOMIC_ORDER_RELAXED );
121}
122
123/**
124 * @brief Clears the specified flags in the iop.
125 *
126 * @param[in] iop The iop.
127 * @param[in] clear The flags to clear.
128 *
129 * @return The previous flags.
130 */
131static inline unsigned int rtems_libio_iop_flags_clear(
132  rtems_libio_t *iop,
133  unsigned int   clear
134)
135{
136  return _Atomic_Fetch_and_uint( &iop->flags, ~clear, ATOMIC_ORDER_RELAXED );
137}
138
139/**
140 * @brief Maps a file descriptor to the iop.
141 *
142 * The file descriptor must be a valid index into the iop table.
143 *
144 * @param[in] fd The file descriptor.
145 *
146 * @return The iop corresponding to the specified file descriptor.
147 */
148static inline rtems_libio_t *rtems_libio_iop( int fd )
149{
150  return &rtems_libio_iops[ fd ];
151}
152
153/**
154 * @brief Holds a refernece to the iop.
155 *
156 * @param[in] iop The iop.
157 *
158 * @return The flags corresponding to the specified iop.
159 */
160static inline unsigned int rtems_libio_iop_hold( rtems_libio_t *iop )
161{
162  return _Atomic_Fetch_add_uint(
163    &iop->flags,
164    LIBIO_FLAGS_REFERENCE_INC,
165    ATOMIC_ORDER_ACQUIRE
166  );
167}
168
169/**
170 * @brief Drops a refernece to the iop.
171 *
172 * @param[in] iop The iop.
173 */
174static inline void rtems_libio_iop_drop( rtems_libio_t *iop )
175{
176#if defined(RTEMS_DEBUG)
177  unsigned int flags;
178  bool         success;
179
180  flags = _Atomic_Load_uint( &iop->flags, ATOMIC_ORDER_RELAXED );
181
182  do {
183    unsigned int desired;
184
185    _Assert( flags >= LIBIO_FLAGS_REFERENCE_INC );
186
187    desired = flags - LIBIO_FLAGS_REFERENCE_INC;
188    success = _Atomic_Compare_exchange_uint(
189      &iop->flags,
190      &flags,
191      desired,
192      ATOMIC_ORDER_RELEASE,
193      ATOMIC_ORDER_RELAXED
194    );
195  } while ( !success );
196#else
197  _Atomic_Fetch_sub_uint(
198    &iop->flags,
199    LIBIO_FLAGS_REFERENCE_INC,
200    ATOMIC_ORDER_RELEASE
201  );
202#endif
203}
204
205/*
206 *  rtems_libio_iop_to_descriptor
207 *
208 *  Macro to convert an internal file descriptor pointer (iop) into
209 *  the integer file descriptor used by the "section 2" system calls.
210 */
211
212#define rtems_libio_iop_to_descriptor(_iop) \
213  ((_iop) - &rtems_libio_iops[0])
214
215/*
216 *  rtems_libio_check_is_open
217 *
218 *  Macro to check if a file descriptor is actually open.
219 */
220
221#define rtems_libio_check_is_open(_iop) \
222  do {                                               \
223      if (((_iop)->flags & LIBIO_FLAGS_OPEN) == 0) { \
224          errno = EBADF;                             \
225          return -1;                                 \
226      }                                              \
227  } while (0)
228
229/**
230 * @brief Macro to get the iop for the specified file descriptor.
231 *
232 * Checks that the file descriptor is in the valid range and open.
233 */
234#define LIBIO_GET_IOP( _fd, _iop ) \
235  do { \
236    unsigned int _flags; \
237    if ( (uint32_t) ( _fd ) >= rtems_libio_number_iops ) { \
238      rtems_set_errno_and_return_minus_one( EBADF ); \
239    } \
240    _iop = rtems_libio_iop( _fd ); \
241    _flags = rtems_libio_iop_hold( _iop ); \
242    if ( ( _flags & LIBIO_FLAGS_OPEN ) == 0 ) { \
243      rtems_libio_iop_drop( _iop ); \
244      rtems_set_errno_and_return_minus_one( EBADF ); \
245    } \
246  } while ( 0 )
247
248/**
249 * @brief Macro to get the iop for the specified file descriptor with access
250 * flags and error.
251 *
252 * Checks that the file descriptor is in the valid range and open.
253 */
254#define LIBIO_GET_IOP_WITH_ACCESS( _fd, _iop, _access_flags, _access_error ) \
255  do { \
256    unsigned int _flags; \
257    unsigned int _mandatory; \
258    if ( (uint32_t) ( _fd ) >= rtems_libio_number_iops ) { \
259      rtems_set_errno_and_return_minus_one( EBADF ); \
260    } \
261    _iop = rtems_libio_iop( _fd ); \
262    _flags = rtems_libio_iop_hold( _iop ); \
263    _mandatory = LIBIO_FLAGS_OPEN | ( _access_flags ); \
264    if ( ( _flags & _mandatory ) != _mandatory ) { \
265      int _error; \
266      rtems_libio_iop_drop( _iop ); \
267      if ( ( _flags & LIBIO_FLAGS_OPEN ) == 0 ) { \
268        _error = EBADF; \
269      } else { \
270        _error = _access_error; \
271      } \
272      rtems_set_errno_and_return_minus_one( _error ); \
273    } \
274  } while ( 0 )
275
276/*
277 *  rtems_libio_check_buffer
278 *
279 *  Macro to check if a buffer pointer is valid.
280 */
281
282#define rtems_libio_check_buffer(_buffer) \
283  do {                                    \
284      if ((_buffer) == 0) {               \
285          errno = EINVAL;                 \
286          return -1;                      \
287      }                                   \
288  } while (0)
289
290/*
291 *  rtems_libio_check_count
292 *
293 *  Macro to check if a count or length is valid.
294 */
295
296#define rtems_libio_check_count(_count) \
297  do {                                  \
298      if ((_count) == 0) {              \
299          return 0;                     \
300      }                                 \
301  } while (0)
302
303/**
304 * @brief Clones a node.
305 *
306 * The caller must hold the file system instance lock.
307 *
308 * @param[out] clone The cloned location.
309 * @param[in] master The master location.
310 *
311 * @see rtems_filesystem_instance_lock().
312 */
313void rtems_filesystem_location_clone(
314  rtems_filesystem_location_info_t *clone,
315  const rtems_filesystem_location_info_t *master
316);
317
318/**
319 * @brief Releases all resources of a location.
320 *
321 * This function may block on a mutex and may complete an unmount process.
322 *
323 * @param[in] loc The location to free.
324 *
325 * @note The file system root location is released by the file system
326 * instance destruction handler (see @ref rtems_filesystem_fsunmount_me_t).
327 *
328 * @see rtems_filesystem_freenode_t.
329 */
330void rtems_filesystem_location_free( rtems_filesystem_location_info_t *loc );
331
332/*
333 *  External structures
334 */
335#include <rtems/userenv.h>
336
337void rtems_libio_free_user_env( void *env );
338
339extern pthread_key_t rtems_current_user_env_key;
340
341void rtems_libio_lock( void );
342
343void rtems_libio_unlock( void );
344
345static inline void rtems_filesystem_mt_lock( void )
346{
347  rtems_libio_lock();
348}
349
350static inline void rtems_filesystem_mt_unlock( void )
351{
352  rtems_libio_unlock();
353}
354
355extern rtems_interrupt_lock rtems_filesystem_mt_entry_lock_control;
356
357#define rtems_filesystem_mt_entry_declare_lock_context( ctx ) \
358  rtems_interrupt_lock_context ctx
359
360#define rtems_filesystem_mt_entry_lock( ctx ) \
361  rtems_interrupt_lock_acquire( &rtems_filesystem_mt_entry_lock_control, &ctx )
362
363#define rtems_filesystem_mt_entry_unlock( ctx ) \
364  rtems_interrupt_lock_release( &rtems_filesystem_mt_entry_lock_control, &ctx )
365
366static inline void rtems_filesystem_instance_lock(
367  const rtems_filesystem_location_info_t *loc
368)
369{
370  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
371
372  (*mt_entry->ops->lock_h)( mt_entry );
373}
374
375static inline void rtems_filesystem_instance_unlock(
376  const rtems_filesystem_location_info_t *loc
377)
378{
379  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
380
381  (*mt_entry->ops->unlock_h)( mt_entry );
382}
383
384/*
385 *  File Descriptor Routine Prototypes
386 */
387
388/**
389 * This routine searches the IOP Table for an unused entry.  If it
390 * finds one, it returns it.  Otherwise, it returns NULL.
391 */
392rtems_libio_t *rtems_libio_allocate(void);
393
394/**
395 * Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
396 */
397unsigned int rtems_libio_fcntl_flags( int fcntl_flags );
398
399/**
400 * Convert RTEMS internal flags to UNIX fnctl(2) flags
401 */
402int rtems_libio_to_fcntl_flags( unsigned int flags );
403
404/**
405 * This routine frees the resources associated with an IOP (file descriptor)
406 * and clears the slot in the IOP Table.
407 */
408void rtems_libio_free(
409  rtems_libio_t *iop
410);
411
412/*
413 *  File System Routine Prototypes
414 */
415
416rtems_filesystem_location_info_t *
417rtems_filesystem_eval_path_start(
418  rtems_filesystem_eval_path_context_t *ctx,
419  const char *path,
420  int eval_flags
421);
422
423rtems_filesystem_location_info_t *
424rtems_filesystem_eval_path_start_with_parent(
425  rtems_filesystem_eval_path_context_t *ctx,
426  const char *path,
427  int eval_flags,
428  rtems_filesystem_location_info_t *parentloc,
429  int parent_eval_flags
430);
431
432rtems_filesystem_location_info_t *
433rtems_filesystem_eval_path_start_with_root_and_current(
434  rtems_filesystem_eval_path_context_t *ctx,
435  const char *path,
436  size_t pathlen,
437  int eval_flags,
438  rtems_filesystem_global_location_t *const *global_root_ptr,
439  rtems_filesystem_global_location_t *const *global_current_ptr
440);
441
442void rtems_filesystem_eval_path_continue(
443  rtems_filesystem_eval_path_context_t *ctx
444);
445
446void rtems_filesystem_eval_path_cleanup(
447  rtems_filesystem_eval_path_context_t *ctx
448);
449
450void rtems_filesystem_eval_path_recursive(
451  rtems_filesystem_eval_path_context_t *ctx,
452  const char *path,
453  size_t pathlen
454);
455
456void rtems_filesystem_eval_path_cleanup_with_parent(
457  rtems_filesystem_eval_path_context_t *ctx,
458  rtems_filesystem_location_info_t *parentloc
459);
460
461/**
462 * @brief Requests a path evaluation restart.
463 *
464 * Sets the start and current location to the new start location.  The caller
465 * must terminate its current evaluation process.  The path evaluation
466 * continues in the next loop iteration within
467 * rtems_filesystem_eval_path_continue().  This avoids recursive invocations.
468 * The function obtains the new start location and clones it to set the new
469 * current location.  The previous start and current locations are released.
470 *
471 * @param[in, out] ctx The path evaluation context.
472 * @param[in, out] newstartloc_ptr Pointer to the new start location.
473 */
474void rtems_filesystem_eval_path_restart(
475  rtems_filesystem_eval_path_context_t *ctx,
476  rtems_filesystem_global_location_t **newstartloc_ptr
477);
478
479typedef enum {
480  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE,
481  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE,
482  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY
483} rtems_filesystem_eval_path_generic_status;
484
485/**
486 * @brief Tests if the current location is a directory.
487 *
488 * @param[in, out] ctx The path evaluation context.
489 * @param[in, out] arg The handler argument.
490 *
491 * @retval true The current location is a directory.
492 * @retval false Otherwise.
493 *
494 * @see rtems_filesystem_eval_path_generic().
495 */
496typedef bool (*rtems_filesystem_eval_path_is_directory)(
497  rtems_filesystem_eval_path_context_t *ctx,
498  void *arg
499);
500
501/**
502 * @brief Evaluates a token.
503 *
504 * @param[in, out] ctx The path evaluation context.
505 * @param[in, out] arg The handler argument.
506 * @param[in] token The token contents.
507 * @param[in] tokenlen The token length in characters.
508 *
509 * @retval status The generic path evaluation status.
510 *
511 * @see rtems_filesystem_eval_path_generic().
512 */
513typedef rtems_filesystem_eval_path_generic_status
514(*rtems_filesystem_eval_path_eval_token)(
515  rtems_filesystem_eval_path_context_t *ctx,
516  void *arg,
517  const char *token,
518  size_t tokenlen
519);
520
521typedef struct {
522  rtems_filesystem_eval_path_is_directory is_directory;
523  rtems_filesystem_eval_path_eval_token eval_token;
524} rtems_filesystem_eval_path_generic_config;
525
526void rtems_filesystem_eval_path_generic(
527  rtems_filesystem_eval_path_context_t *ctx,
528  void *arg,
529  const rtems_filesystem_eval_path_generic_config *config
530);
531
532void rtems_filesystem_initialize(void);
533
534/**
535 * @brief Copies a location.
536 *
537 * A bitwise copy is performed.  The destination location will be added to the
538 * corresponding mount entry.
539 *
540 * @param[out] dst The destination location.
541 * @param[in] src The  source location.
542 *
543 * @retval dst The destination location.
544 *
545 * @see rtems_filesystem_location_clone().
546 */
547rtems_filesystem_location_info_t *rtems_filesystem_location_copy(
548  rtems_filesystem_location_info_t *dst,
549  const rtems_filesystem_location_info_t *src
550);
551
552static inline rtems_filesystem_location_info_t *
553rtems_filesystem_location_initialize_to_null(
554  rtems_filesystem_location_info_t *loc
555)
556{
557  return rtems_filesystem_location_copy(
558    loc,
559    &rtems_filesystem_global_location_null.location
560  );
561}
562
563rtems_filesystem_global_location_t *
564rtems_filesystem_location_transform_to_global(
565  rtems_filesystem_location_info_t *loc
566);
567
568/**
569 * @brief Assigns a global file system location.
570 *
571 * @param[in, out] lhs_global_loc_ptr Pointer to the global left hand side file
572 * system location.  The current left hand side location will be released.
573 * @param[in] rhs_global_loc The global right hand side file system location.
574 */
575void rtems_filesystem_global_location_assign(
576  rtems_filesystem_global_location_t **lhs_global_loc_ptr,
577  rtems_filesystem_global_location_t *rhs_global_loc
578);
579
580/**
581 * @brief Obtains a global file system location.
582 *
583 * Deferred releases will be processed in this function.
584 *
585 * This function must be called from normal thread context and may block on a
586 * mutex.  Thread dispatching is disabled to protect some critical sections.
587 *
588 * @param[in] global_loc_ptr Pointer to the global file system location.
589 *
590 * @return A global file system location.  It returns always a valid object.
591 * In case of an error, the global null location will be returned.  Each
592 * operation or handler of the null location returns an error status.  The
593 * errno indicates the error.  The NULL pointer is never returned.
594 *
595 * @see rtems_filesystem_location_transform_to_global(),
596 * rtems_filesystem_global_location_obtain_null(), and
597 * rtems_filesystem_global_location_release().
598 */
599rtems_filesystem_global_location_t *rtems_filesystem_global_location_obtain(
600  rtems_filesystem_global_location_t *const *global_loc_ptr
601);
602
603/**
604 * @brief Releases a global file system location.
605 *
606 * In case the reference count reaches zero, all associated resources will be
607 * released.  This may include the complete unmount of the corresponding file
608 * system instance.
609 *
610 * This function may block on a mutex.  It may be called within critical
611 * sections of the operating system.  In this case the release will be
612 * deferred.  The next obtain call will do the actual release.
613 *
614 * @param[in] global_loc The global file system location.  It must not be NULL.
615 * @param[in] deferred If true, then do a deferred release, otherwise release
616 *   it immediately.
617 *
618 * @see rtems_filesystem_global_location_obtain().
619 */
620void rtems_filesystem_global_location_release(
621  rtems_filesystem_global_location_t *global_loc,
622  bool deferred
623);
624
625void rtems_filesystem_location_detach(
626  rtems_filesystem_location_info_t *detach
627);
628
629void rtems_filesystem_location_copy_and_detach(
630  rtems_filesystem_location_info_t *copy,
631  rtems_filesystem_location_info_t *detach
632);
633
634static inline rtems_filesystem_global_location_t *
635rtems_filesystem_global_location_obtain_null(void)
636{
637  rtems_filesystem_global_location_t *global_loc = NULL;
638
639  return rtems_filesystem_global_location_obtain( &global_loc );
640}
641
642static inline bool rtems_filesystem_location_is_null(
643  const rtems_filesystem_location_info_t *loc
644)
645{
646  return loc->handlers == &rtems_filesystem_null_handlers;
647}
648
649static inline bool rtems_filesystem_global_location_is_null(
650  const rtems_filesystem_global_location_t *global_loc
651)
652{
653  return rtems_filesystem_location_is_null( &global_loc->location );
654}
655
656static inline void rtems_filesystem_location_error(
657  const rtems_filesystem_location_info_t *loc,
658  int eno
659)
660{
661  if ( !rtems_filesystem_location_is_null( loc ) ) {
662    errno = eno;
663  }
664}
665
666int rtems_filesystem_mknod(
667  const rtems_filesystem_location_info_t *parentloc,
668  const char *name,
669  size_t namelen,
670  mode_t mode,
671  dev_t dev
672);
673
674int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc );
675
676int rtems_filesystem_chmod(
677  const rtems_filesystem_location_info_t *loc,
678  mode_t mode
679);
680
681int rtems_filesystem_chown(
682  const rtems_filesystem_location_info_t *loc,
683  uid_t owner,
684  gid_t group
685);
686
687static inline bool rtems_filesystem_is_ready_for_unmount(
688  rtems_filesystem_mount_table_entry_t *mt_entry
689)
690{
691  bool ready = !mt_entry->mounted
692    && rtems_chain_has_only_one_node( &mt_entry->location_chain )
693    && mt_entry->mt_fs_root->reference_count == 1;
694
695  if ( ready ) {
696    rtems_chain_initialize_empty( &mt_entry->location_chain );
697  }
698
699  return ready;
700}
701
702static inline void rtems_filesystem_location_add_to_mt_entry(
703  rtems_filesystem_location_info_t *loc
704)
705{
706  rtems_filesystem_mt_entry_declare_lock_context( lock_context );
707
708  rtems_filesystem_mt_entry_lock( lock_context );
709  rtems_chain_append_unprotected(
710    &loc->mt_entry->location_chain,
711    &loc->mt_entry_node
712  );
713  rtems_filesystem_mt_entry_unlock( lock_context );
714}
715
716void rtems_filesystem_location_remove_from_mt_entry(
717  rtems_filesystem_location_info_t *loc
718);
719
720void rtems_filesystem_do_unmount(
721  rtems_filesystem_mount_table_entry_t *mt_entry
722);
723
724static inline bool rtems_filesystem_location_is_instance_root(
725  const rtems_filesystem_location_info_t *loc
726)
727{
728  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
729
730  return (*mt_entry->ops->are_nodes_equal_h)(
731    loc,
732    &mt_entry->mt_fs_root->location
733  );
734}
735
736static inline const char *rtems_filesystem_eval_path_get_path(
737  rtems_filesystem_eval_path_context_t *ctx
738)
739{
740  return ctx->path;
741}
742
743static inline size_t rtems_filesystem_eval_path_get_pathlen(
744  rtems_filesystem_eval_path_context_t *ctx
745)
746{
747  return ctx->pathlen;
748}
749
750static inline void rtems_filesystem_eval_path_set_path(
751  rtems_filesystem_eval_path_context_t *ctx,
752  const char *path,
753  size_t pathlen
754)
755{
756  ctx->path = path;
757  ctx->pathlen = pathlen;
758}
759
760static inline void rtems_filesystem_eval_path_clear_path(
761  rtems_filesystem_eval_path_context_t *ctx
762)
763{
764  ctx->pathlen = 0;
765}
766
767static inline const char *rtems_filesystem_eval_path_get_token(
768  rtems_filesystem_eval_path_context_t *ctx
769)
770{
771  return ctx->token;
772}
773
774static inline size_t rtems_filesystem_eval_path_get_tokenlen(
775  rtems_filesystem_eval_path_context_t *ctx
776)
777{
778  return ctx->tokenlen;
779}
780
781static inline void rtems_filesystem_eval_path_set_token(
782  rtems_filesystem_eval_path_context_t *ctx,
783  const char *token,
784  size_t tokenlen
785)
786{
787  ctx->token = token;
788  ctx->tokenlen = tokenlen;
789}
790
791static inline void rtems_filesystem_eval_path_clear_token(
792  rtems_filesystem_eval_path_context_t *ctx
793)
794{
795  ctx->tokenlen = 0;
796}
797
798static inline void rtems_filesystem_eval_path_put_back_token(
799  rtems_filesystem_eval_path_context_t *ctx
800)
801{
802  size_t tokenlen = ctx->tokenlen;
803
804  ctx->path -= tokenlen;
805  ctx->pathlen += tokenlen;
806  ctx->tokenlen = 0;
807}
808
809void rtems_filesystem_eval_path_eat_delimiter(
810  rtems_filesystem_eval_path_context_t *ctx
811);
812
813void rtems_filesystem_eval_path_next_token(
814  rtems_filesystem_eval_path_context_t *ctx
815);
816
817static inline void rtems_filesystem_eval_path_get_next_token(
818  rtems_filesystem_eval_path_context_t *ctx,
819  const char **token,
820  size_t *tokenlen
821)
822{
823  rtems_filesystem_eval_path_next_token(ctx);
824  *token = ctx->token;
825  *tokenlen = ctx->tokenlen;
826}
827
828static inline rtems_filesystem_location_info_t *
829rtems_filesystem_eval_path_get_currentloc(
830  rtems_filesystem_eval_path_context_t *ctx
831)
832{
833  return &ctx->currentloc;
834}
835
836static inline bool rtems_filesystem_eval_path_has_path(
837  const rtems_filesystem_eval_path_context_t *ctx
838)
839{
840  return ctx->pathlen > 0;
841}
842
843static inline bool rtems_filesystem_eval_path_has_token(
844  const rtems_filesystem_eval_path_context_t *ctx
845)
846{
847  return ctx->tokenlen > 0;
848}
849
850static inline int rtems_filesystem_eval_path_get_flags(
851  const rtems_filesystem_eval_path_context_t *ctx
852)
853{
854  return ctx->flags;
855}
856
857static inline void rtems_filesystem_eval_path_set_flags(
858  rtems_filesystem_eval_path_context_t *ctx,
859  int flags
860)
861{
862  ctx->flags = flags;
863}
864
865static inline void rtems_filesystem_eval_path_clear_and_set_flags(
866  rtems_filesystem_eval_path_context_t *ctx,
867  int clear,
868  int set
869)
870{
871  int flags = ctx->flags;
872
873  flags &= ~clear;
874  flags |= set;
875
876  ctx->flags = flags;
877}
878
879static inline void rtems_filesystem_eval_path_extract_currentloc(
880  rtems_filesystem_eval_path_context_t *ctx,
881  rtems_filesystem_location_info_t *get
882)
883{
884  rtems_filesystem_location_copy_and_detach(
885    get,
886    &ctx->currentloc
887  );
888}
889
890void rtems_filesystem_eval_path_error(
891  rtems_filesystem_eval_path_context_t *ctx,
892  int eno
893);
894
895/**
896 * @brief Checks that the locations exist in the same file system instance.
897 *
898 * @retval 0 The locations exist and are in the same file system instance.
899 * @retval -1 An error occurred.  The @c errno indicates the error.
900 */
901int rtems_filesystem_location_exists_in_same_instance_as(
902  const rtems_filesystem_location_info_t *a,
903  const rtems_filesystem_location_info_t *b
904);
905
906/**
907 * @brief Checks if access to an object is allowed for the current user.
908 *
909 * If the effective UID is zero or equals the UID of the object, then the user
910 * permission flags of the object will be used.  Otherwise if the effective GID
911 * is zero or equals the GID of the object or one of the supplementary group
912 * IDs is equal to the GID of the object, then the group permission flags of
913 * the object will be used.  Otherwise the other permission flags of the object
914 * will be used.
915 *
916 * @param[in] flags The flags determining the access type.  It can be
917 *   RTEMS_FS_PERMS_READ, RTEMS_FS_PERMS_WRITE or RTEMS_FS_PERMS_EXEC.
918 * @param[in] object_mode The mode of the object specifying the permission flags.
919 * @param[in] object_uid The UID of the object.
920 * @param[in] object_gid The GID of the object.
921 *
922 * @retval true Access is allowed.
923 * @retval false Otherwise.
924 */
925bool rtems_filesystem_check_access(
926  int flags,
927  mode_t object_mode,
928  uid_t object_uid,
929  gid_t object_gid
930);
931
932bool rtems_filesystem_eval_path_check_access(
933  rtems_filesystem_eval_path_context_t *ctx,
934  int eval_flags,
935  mode_t node_mode,
936  uid_t node_uid,
937  gid_t node_gid
938);
939
940static inline bool rtems_filesystem_is_delimiter(char c)
941{
942  return c == '/' || c == '\\';
943}
944
945static inline bool rtems_filesystem_is_current_directory(
946  const char *token,
947  size_t tokenlen
948)
949{
950  return tokenlen == 1 && token [0] == '.';
951}
952
953static inline bool rtems_filesystem_is_parent_directory(
954  const char *token,
955  size_t tokenlen
956)
957{
958  return tokenlen == 2 && token [0] == '.' && token [1] == '.';
959}
960
961typedef ssize_t ( *rtems_libio_iovec_adapter )(
962  rtems_libio_t      *iop,
963  const struct iovec *iov,
964  int                 iovcnt,
965  ssize_t             total
966);
967
968static inline ssize_t rtems_libio_iovec_eval(
969  int                        fd,
970  const struct iovec        *iov,
971  int                        iovcnt,
972  unsigned int               flags,
973  rtems_libio_iovec_adapter  adapter
974)
975{
976  ssize_t        total;
977  int            v;
978  rtems_libio_t *iop;
979
980  /*
981   *  Argument validation on IO vector
982   */
983  if ( iov == NULL )
984    rtems_set_errno_and_return_minus_one( EINVAL );
985
986  if ( iovcnt <= 0 )
987    rtems_set_errno_and_return_minus_one( EINVAL );
988
989  if ( iovcnt > IOV_MAX )
990    rtems_set_errno_and_return_minus_one( EINVAL );
991
992  /*
993   *  OpenGroup says that you are supposed to return EINVAL if the
994   *  sum of the iov_len values in the iov array would overflow a
995   *  ssize_t.
996   */
997  total = 0;
998  for ( v = 0 ; v < iovcnt ; ++v ) {
999    size_t len = iov[ v ].iov_len;
1000
1001    if ( len > ( size_t ) ( SSIZE_MAX - total ) ) {
1002      rtems_set_errno_and_return_minus_one( EINVAL );
1003    }
1004
1005    total += ( ssize_t ) len;
1006
1007    if ( iov[ v ].iov_base == NULL && len != 0 ) {
1008      rtems_set_errno_and_return_minus_one( EINVAL );
1009    }
1010  }
1011
1012  LIBIO_GET_IOP_WITH_ACCESS( fd, iop, flags, EBADF );
1013
1014  if ( total > 0 ) {
1015    total = ( *adapter )( iop, iov, iovcnt, total );
1016  }
1017
1018  rtems_libio_iop_drop( iop );
1019  return total;
1020}
1021
1022/**
1023 * @brief Returns the file type of the file referenced by the filesystem
1024 * location.
1025 *
1026 * @brief[in] loc The filesystem location.
1027 *
1028 * @return The type of the file or an invalid file type in case of an error.
1029 */
1030static inline mode_t rtems_filesystem_location_type(
1031  const rtems_filesystem_location_info_t *loc
1032)
1033{
1034  struct stat st;
1035
1036  st.st_mode = 0;
1037  (void) ( *loc->handlers->fstat_h )( loc, &st );
1038
1039  return st.st_mode;
1040}
1041
1042/** @} */
1043
1044#ifdef __cplusplus
1045}
1046#endif
1047
1048#endif
1049/* end of include file */
Note: See TracBrowser for help on using the repository browser.