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

4.115
Last change on this file since ec0f2df was ec0f2df, checked in by Sebastian Huber <sebastian.huber@…>, on 02/02/15 at 14:25:25

Filesystem: Use rtems_libio_iop_to_descriptor()

Drop parameter check from previously unused
rtems_libio_iop_to_descriptor().

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