source: rtems/cpukit/libcsupport/include/rtems/libio_.h @ 7b45202

5
Last change on this file since 7b45202 was 7b45202, checked in by Sebastian Huber <sebastian.huber@…>, on 09/13/17 at 06:25:33

libio: Simplify rtems_libio_iop()

Remove the file descriptor validation. This is the job of
rtems_libio_check_fd(). Use an inline function instread of a macro.

Update #3132.

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