source: rtems/cpukit/libcsupport/include/rtems/libio_.h @ 856ede4f

5
Last change on this file since 856ede4f was 856ede4f, checked in by Sebastian Huber <sebastian.huber@…>, on 09/13/17 at 08:11:46

libio: Add iop set/clear flags

Update #3132.

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