source: rtems/cpukit/libcsupport/include/rtems/libio_.h @ c625a641

4.115
Last change on this file since c625a641 was c625a641, checked in by Sebastian Huber <sebastian.huber@…>, on 12/21/14 at 19:12:28

Filesystem: Delete node type operation

Use the fstat handler instead.

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