source: rtems/cpukit/libcsupport/include/rtems/libio_.h @ 98041b68

5
Last change on this file since 98041b68 was 98041b68, checked in by Sebastian Huber <sebastian.huber@…>, on 09/13/17 at 13:19:14

libio: Unify readv() and writev()

Update #3132.

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