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

4.11
Last change on this file since ae55da72 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on May 3, 2012 at 3:09:24 PM

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 20.0 KB
Line 
1/**
2 * @file rtems/libio_.h
3 *
4 * This file is the libio internal interface.
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2011.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  Modifications to support reference counting in the file system are
12 *  Copyright (c) 2012 embedded brains GmbH.
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.com/license/LICENSE.
17 */
18
19#ifndef _RTEMS_RTEMS_LIBIO__H
20#define _RTEMS_RTEMS_LIBIO__H
21
22#include <errno.h>
23
24#include <rtems.h>
25#include <rtems/libio.h>
26#include <rtems/seterr.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#define RTEMS_FILESYSTEM_SYMLOOP_MAX 32
33
34/*
35 *  Semaphore to protect the io table
36 */
37
38#define RTEMS_LIBIO_SEM         rtems_build_name('L', 'B', 'I', 'O')
39#define RTEMS_LIBIO_IOP_SEM(n)  rtems_build_name('L', 'B', 'I', n)
40
41extern rtems_id                          rtems_libio_semaphore;
42
43/*
44 *  File descriptor Table Information
45 */
46
47extern uint32_t        rtems_libio_number_iops;
48extern rtems_libio_t  *rtems_libio_iops;
49extern rtems_libio_t  *rtems_libio_last_iop;
50extern rtems_libio_t *rtems_libio_iop_freelist;
51
52extern const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers;
53
54extern rtems_filesystem_mount_table_entry_t rtems_filesystem_null_mt_entry;
55
56/**
57 * @brief The global null location.
58 *
59 * Every operation and the open and fstat handlers of this location returns an
60 * error status.  The errno is not touched by these operations and handlers.
61 * The purpose of this location is to deliver the error return status for a
62 * previous error condition which must set the errno accordingly.
63 *
64 * The usage of this null location instead of the NULL pointer eliminates a lot
65 * of branches.
66 *
67 * The user environment root and current directory are statically initialized
68 * with the null location.  Due to that all file system services are in a
69 * defined state even if no root file system was mounted.
70 */
71extern rtems_filesystem_global_location_t rtems_filesystem_global_location_null;
72
73/*
74 *  rtems_libio_iop
75 *
76 *  Macro to return the file descriptor pointer.
77 */
78
79#define rtems_libio_iop(_fd) \
80  ((((uint32_t)(_fd)) < rtems_libio_number_iops) ? \
81         &rtems_libio_iops[_fd] : 0)
82
83/*
84 *  rtems_libio_iop_to_descriptor
85 *
86 *  Macro to convert an internal file descriptor pointer (iop) into
87 *  the integer file descriptor used by the "section 2" system calls.
88 */
89
90#define rtems_libio_iop_to_descriptor(_iop) \
91   ((!(_iop)) ? -1 : (_iop - rtems_libio_iops))
92
93/*
94 *  rtems_libio_check_is_open
95 *
96 *  Macro to check if a file descriptor is actually open.
97 */
98
99#define rtems_libio_check_is_open(_iop) \
100  do {                                               \
101      if (((_iop)->flags & LIBIO_FLAGS_OPEN) == 0) { \
102          errno = EBADF;                             \
103          return -1;                                 \
104      }                                              \
105  } while (0)
106
107/*
108 *  rtems_libio_check_fd
109 *
110 *  Macro to check if a file descriptor number is valid.
111 */
112
113#define rtems_libio_check_fd(_fd) \
114  do {                                                     \
115      if ((uint32_t) (_fd) >= rtems_libio_number_iops) {   \
116          errno = EBADF;                                   \
117          return -1;                                       \
118      }                                                    \
119  } while (0)
120
121/*
122 *  rtems_libio_check_buffer
123 *
124 *  Macro to check if a buffer pointer is valid.
125 */
126
127#define rtems_libio_check_buffer(_buffer) \
128  do {                                    \
129      if ((_buffer) == 0) {               \
130          errno = EINVAL;                 \
131          return -1;                      \
132      }                                   \
133  } while (0)
134
135/*
136 *  rtems_libio_check_count
137 *
138 *  Macro to check if a count or length is valid.
139 */
140
141#define rtems_libio_check_count(_count) \
142  do {                                  \
143      if ((_count) == 0) {              \
144          return 0;                     \
145      }                                 \
146  } while (0)
147
148/*
149 *  rtems_libio_check_permissions_with_error
150 *
151 *  Macro to check if a file descriptor is open for this operation.
152 *  On failure, return the user specified error.
153 */
154
155#define rtems_libio_check_permissions_with_error(_iop, _flag, _errno) \
156  do {                                                      \
157      if (((_iop)->flags & (_flag)) == 0) {                 \
158            rtems_set_errno_and_return_minus_one( _errno ); \
159            return -1;                                      \
160      }                                                     \
161  } while (0)
162
163/*
164 *  rtems_libio_check_permissions
165 *
166 *  Macro to check if a file descriptor is open for this operation.
167 *  On failure, return EINVAL
168 */
169
170#define rtems_libio_check_permissions(_iop, _flag) \
171   rtems_libio_check_permissions_with_error(_iop, _flag, EINVAL )
172
173/**
174 * @brief Clones a node.
175 *
176 * The caller must hold the file system instance lock.
177 *
178 * @param[out] clone The cloned location.
179 * @param[in] master The master location.
180 *
181 * @see rtems_filesystem_instance_lock().
182 */
183void rtems_filesystem_location_clone(
184  rtems_filesystem_location_info_t *clone,
185  const rtems_filesystem_location_info_t *master
186);
187
188/**
189 * @brief Returns the type of a node.
190 *
191 * This function obtains and releases the file system instance lock.
192 *
193 * @param[in] loc The location of the node.
194 *
195 * @return The node type.
196 *
197 * @see rtems_filesystem_instance_lock().
198 */
199rtems_filesystem_node_types_t rtems_filesystem_node_type(
200  const rtems_filesystem_location_info_t *loc
201);
202
203/**
204 * @brief Releases all resources of a location.
205 *
206 * This function may block on a mutex and may complete an unmount process.
207 *
208 * @param[in] loc The location to free.
209 *
210 * @note The file system root location is released by the file system instance
211 * destruction handler (see @ref rtems_filesystem_fsunmount_me_t).
212 *
213 * @see rtems_filesystem_freenode_t.
214 */
215void rtems_filesystem_location_free( rtems_filesystem_location_info_t *loc );
216
217/*
218 *  External structures
219 */
220#include <rtems/userenv.h>
221
222static inline void rtems_libio_lock( void )
223{
224  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
225}
226
227static inline void rtems_libio_unlock( void )
228{
229  rtems_semaphore_release( rtems_libio_semaphore );
230}
231
232static inline void rtems_filesystem_mt_lock( void )
233{
234  rtems_libio_lock();
235}
236
237static inline void rtems_filesystem_mt_unlock( void )
238{
239  rtems_libio_unlock();
240}
241
242#define rtems_filesystem_mt_entry_declare_lock_context( ctx ) \
243  rtems_interrupt_level ctx
244
245#define rtems_filesystem_mt_entry_lock( ctx ) rtems_interrupt_disable( ctx )
246
247#define rtems_filesystem_mt_entry_unlock( ctx ) rtems_interrupt_enable( ctx )
248
249static inline void rtems_filesystem_instance_lock(
250  const rtems_filesystem_location_info_t *loc
251)
252{
253  (*loc->ops->lock_h)( loc->mt_entry );
254}
255
256static inline void rtems_filesystem_instance_unlock(
257  const rtems_filesystem_location_info_t *loc
258)
259{
260  (*loc->ops->unlock_h)( loc->mt_entry );
261}
262
263/*
264 *  File Descriptor Routine Prototypes
265 */
266
267rtems_libio_t *rtems_libio_allocate(void);
268
269uint32_t rtems_libio_fcntl_flags( int fcntl_flags );
270
271int rtems_libio_to_fcntl_flags( uint32_t flags );
272
273void rtems_libio_free(
274  rtems_libio_t *iop
275);
276
277/*
278 *  File System Routine Prototypes
279 */
280
281rtems_filesystem_location_info_t *
282rtems_filesystem_eval_path_start(
283  rtems_filesystem_eval_path_context_t *ctx,
284  const char *path,
285  int eval_flags
286);
287
288rtems_filesystem_location_info_t *
289rtems_filesystem_eval_path_start_with_parent(
290  rtems_filesystem_eval_path_context_t *ctx,
291  const char *path,
292  int eval_flags,
293  rtems_filesystem_location_info_t *parentloc,
294  int parent_eval_flags
295);
296
297rtems_filesystem_location_info_t *
298rtems_filesystem_eval_path_start_with_root_and_current(
299  rtems_filesystem_eval_path_context_t *ctx,
300  const char *path,
301  int eval_flags,
302  rtems_filesystem_global_location_t *const *global_root_ptr,
303  rtems_filesystem_global_location_t *const *global_current_ptr
304);
305
306void rtems_filesystem_eval_path_continue(
307  rtems_filesystem_eval_path_context_t *ctx
308);
309
310void rtems_filesystem_eval_path_cleanup(
311  rtems_filesystem_eval_path_context_t *ctx
312);
313
314void rtems_filesystem_eval_path_recursive(
315  rtems_filesystem_eval_path_context_t *ctx,
316  const char *path,
317  size_t pathlen
318);
319
320void rtems_filesystem_eval_path_cleanup_with_parent(
321  rtems_filesystem_eval_path_context_t *ctx,
322  rtems_filesystem_location_info_t *parentloc
323);
324
325/**
326 * @brief Requests a path evaluation restart.
327 *
328 * Sets the start and current location to the new start location.  The caller
329 * must terminate its current evaluation process.  The path evaluation
330 * continues in the next loop iteration within
331 * rtems_filesystem_eval_path_continue().  This avoids recursive invokations.
332 * The function obtains the new start location and clones it to set the new
333 * current location.  The previous start and current locations are released.
334 *
335 * @param[in, out] ctx The path evaluation context.
336 * @param[in, out] newstartloc_ptr Pointer to new start location.
337 */
338void rtems_filesystem_eval_path_restart(
339  rtems_filesystem_eval_path_context_t *ctx,
340  rtems_filesystem_global_location_t **newstartloc_ptr
341);
342
343typedef enum {
344  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE,
345  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE,
346  RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY
347} rtems_filesystem_eval_path_generic_status;
348
349/**
350 * @brief Tests if the current location is a directory.
351 *
352 * @param[in, out] ctx The path evaluation context.
353 * @param[in, out] arg The handler argument.
354 *
355 * @retval true The current location is a directory.
356 * @retval false Otherwise.
357 *
358 * @see rtems_filesystem_eval_path_generic().
359 */
360typedef bool (*rtems_filesystem_eval_path_is_directory)(
361  rtems_filesystem_eval_path_context_t *ctx,
362  void *arg
363);
364
365/**
366 * @brief Evaluates a token.
367 *
368 * @param[in, out] ctx The path evaluation context.
369 * @param[in, out] arg The handler argument.
370 * @param[in] token The token contents.
371 * @param[in] tokenlen The token length in characters.
372 *
373 * @retval status The generic path evaluation status.
374 *
375 * @see rtems_filesystem_eval_path_generic().
376 */
377typedef rtems_filesystem_eval_path_generic_status
378(*rtems_filesystem_eval_path_eval_token)(
379  rtems_filesystem_eval_path_context_t *ctx,
380  void *arg,
381  const char *token,
382  size_t tokenlen
383);
384
385typedef struct {
386  rtems_filesystem_eval_path_is_directory is_directory;
387  rtems_filesystem_eval_path_eval_token eval_token;
388} rtems_filesystem_eval_path_generic_config;
389
390void rtems_filesystem_eval_path_generic(
391  rtems_filesystem_eval_path_context_t *ctx,
392  void *arg,
393  const rtems_filesystem_eval_path_generic_config *config
394);
395
396void rtems_filesystem_initialize(void);
397
398/**
399 * @brief Copies a location.
400 *
401 * A bitwise copy is performed.  The destination location will be added to the
402 * corresponding mount entry.
403 *
404 * @param[out] dst The destination location.
405 * @param[in] src The source location.
406 *
407 * @retval dst The destination location.
408 *
409 * @see rtems_filesystem_location_clone().
410 */
411rtems_filesystem_location_info_t *rtems_filesystem_location_copy(
412  rtems_filesystem_location_info_t *dst,
413  const rtems_filesystem_location_info_t *src
414);
415
416static inline rtems_filesystem_location_info_t *
417rtems_filesystem_location_initialize_to_null(
418  rtems_filesystem_location_info_t *loc
419)
420{
421  return rtems_filesystem_location_copy(
422    loc,
423    &rtems_filesystem_global_location_null.location
424  );
425}
426
427rtems_filesystem_global_location_t *
428rtems_filesystem_location_transform_to_global(
429  rtems_filesystem_location_info_t *loc
430);
431
432/**
433 * @brief Assigns a global file system location.
434 *
435 * @param[in, out] lhs_global_loc_ptr Pointer to the global left hand side file
436 * system location.  The current left hand side location will be released.
437 * @param[in] rhs_global_loc The global right hand side file system location.
438 */
439void rtems_filesystem_global_location_assign(
440  rtems_filesystem_global_location_t **lhs_global_loc_ptr,
441  rtems_filesystem_global_location_t *rhs_global_loc
442);
443
444/**
445 * @brief Obtains a global file system location.
446 *
447 * Deferred releases will be processed in this function.
448 *
449 * This function must be called from normal thread context and may block on a
450 * mutex.  Thread dispatching is disabled to protect some critical sections.
451 *
452 * @param[in] global_loc_ptr Pointer to the global file system location.
453 *
454 * @return A global file system location.  It returns always a valid object.
455 * In case of an error, the global null location will be returned.  Each
456 * operation or handler of the null location returns an error status.  The
457 * errno indicates the error.  The NULL pointer is never returned.
458 *
459 * @see rtems_filesystem_location_transform_to_global(),
460 * rtems_filesystem_global_location_obtain_null(), and
461 * rtems_filesystem_global_location_release().
462 */
463rtems_filesystem_global_location_t *rtems_filesystem_global_location_obtain(
464  rtems_filesystem_global_location_t *const *global_loc_ptr
465);
466
467/**
468 * @brief Releases a global file system location.
469 *
470 * In case the reference count reaches zero, all associated resources will be
471 * released.  This may include the complete unmount of the corresponding file
472 * system instance.
473 *
474 * This function may block on a mutex.  It may be called within critical
475 * sections of the operating system.  In this case the release will be
476 * deferred.  The next obtain call will do the actual release.
477 *
478 * @param[in] global_loc The global file system location.  It must not be NULL.
479 *
480 * @see rtems_filesystem_global_location_obtain().
481 */
482void rtems_filesystem_global_location_release(
483  rtems_filesystem_global_location_t *global_loc
484);
485
486void rtems_filesystem_location_detach(
487  rtems_filesystem_location_info_t *detach
488);
489
490void rtems_filesystem_location_copy_and_detach(
491  rtems_filesystem_location_info_t *copy,
492  rtems_filesystem_location_info_t *detach
493);
494
495static inline rtems_filesystem_global_location_t *
496rtems_filesystem_global_location_obtain_null(void)
497{
498  rtems_filesystem_global_location_t *global_loc = NULL;
499
500  return rtems_filesystem_global_location_obtain( &global_loc );
501}
502
503static inline bool rtems_filesystem_location_is_null(
504  const rtems_filesystem_location_info_t *loc
505)
506{
507  return loc->handlers == &rtems_filesystem_null_handlers;
508}
509
510static inline bool rtems_filesystem_global_location_is_null(
511  const rtems_filesystem_global_location_t *global_loc
512)
513{
514  return rtems_filesystem_location_is_null( &global_loc->location );
515}
516
517static inline void rtems_filesystem_location_error(
518  const rtems_filesystem_location_info_t *loc,
519  int eno
520)
521{
522  if ( !rtems_filesystem_location_is_null( loc ) ) {
523    errno = eno;
524  }
525}
526
527int rtems_filesystem_mknod(
528  const rtems_filesystem_location_info_t *parentloc,
529  const char *name,
530  size_t namelen,
531  mode_t mode,
532  dev_t dev
533);
534
535int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc );
536
537int rtems_filesystem_chown(
538  const char *path,
539  uid_t owner,
540  gid_t group,
541  int eval_follow_link
542);
543
544static inline bool rtems_filesystem_is_ready_for_unmount(
545  rtems_filesystem_mount_table_entry_t *mt_entry
546)
547{
548  bool ready = !mt_entry->mounted
549    && rtems_chain_has_only_one_node( &mt_entry->location_chain )
550    && mt_entry->mt_fs_root->reference_count == 1;
551
552  if ( ready ) {
553    rtems_chain_initialize_empty( &mt_entry->location_chain );
554  }
555
556  return ready;
557}
558
559static inline void rtems_filesystem_location_add_to_mt_entry(
560  rtems_filesystem_location_info_t *loc
561)
562{
563  rtems_filesystem_mt_entry_declare_lock_context( lock_context );
564
565  rtems_filesystem_mt_entry_lock( lock_context );
566  rtems_chain_append_unprotected(
567    &loc->mt_entry->location_chain,
568    &loc->mt_entry_node
569  );
570  rtems_filesystem_mt_entry_unlock( lock_context );
571}
572
573void rtems_filesystem_location_remove_from_mt_entry(
574  rtems_filesystem_location_info_t *loc
575);
576
577void rtems_filesystem_do_unmount(
578  rtems_filesystem_mount_table_entry_t *mt_entry
579);
580
581static inline bool rtems_filesystem_location_is_root(
582  const rtems_filesystem_location_info_t *loc
583)
584{
585  return (*loc->ops->are_nodes_equal_h)(
586    loc,
587    &loc->mt_entry->mt_fs_root->location
588  );
589}
590
591static inline const char *rtems_filesystem_eval_path_get_path(
592  rtems_filesystem_eval_path_context_t *ctx
593)
594{
595  return ctx->path;
596}
597
598static inline size_t rtems_filesystem_eval_path_get_pathlen(
599  rtems_filesystem_eval_path_context_t *ctx
600)
601{
602  return ctx->pathlen;
603}
604
605static inline void rtems_filesystem_eval_path_set_path(
606  rtems_filesystem_eval_path_context_t *ctx,
607  const char *path,
608  size_t pathlen
609)
610{
611  ctx->path = path;
612  ctx->pathlen = pathlen;
613}
614
615static inline void rtems_filesystem_eval_path_clear_path(
616  rtems_filesystem_eval_path_context_t *ctx
617)
618{
619  ctx->pathlen = 0;
620}
621
622static inline const char *rtems_filesystem_eval_path_get_token(
623  rtems_filesystem_eval_path_context_t *ctx
624)
625{
626  return ctx->token;
627}
628
629static inline size_t rtems_filesystem_eval_path_get_tokenlen(
630  rtems_filesystem_eval_path_context_t *ctx
631)
632{
633  return ctx->tokenlen;
634}
635
636static inline void rtems_filesystem_eval_path_set_token(
637  rtems_filesystem_eval_path_context_t *ctx,
638  const char *token,
639  size_t tokenlen
640)
641{
642  ctx->token = token;
643  ctx->tokenlen = tokenlen;
644}
645
646static inline void rtems_filesystem_eval_path_clear_token(
647  rtems_filesystem_eval_path_context_t *ctx
648)
649{
650  ctx->tokenlen = 0;
651}
652
653static inline void rtems_filesystem_eval_path_put_back_token(
654  rtems_filesystem_eval_path_context_t *ctx
655)
656{
657  size_t tokenlen = ctx->tokenlen;
658
659  ctx->path -= tokenlen;
660  ctx->pathlen += tokenlen;
661  ctx->tokenlen = 0;
662}
663
664void rtems_filesystem_eval_path_eat_delimiter(
665  rtems_filesystem_eval_path_context_t *ctx
666);
667
668void rtems_filesystem_eval_path_next_token(
669  rtems_filesystem_eval_path_context_t *ctx
670);
671
672static inline void rtems_filesystem_eval_path_get_next_token(
673  rtems_filesystem_eval_path_context_t *ctx,
674  const char **token,
675  size_t *tokenlen
676)
677{
678  rtems_filesystem_eval_path_next_token(ctx);
679  *token = ctx->token;
680  *tokenlen = ctx->tokenlen;
681}
682
683static inline rtems_filesystem_location_info_t *
684rtems_filesystem_eval_path_get_currentloc(
685  rtems_filesystem_eval_path_context_t *ctx
686)
687{
688  return &ctx->currentloc;
689}
690
691static inline bool rtems_filesystem_eval_path_has_path(
692  const rtems_filesystem_eval_path_context_t *ctx
693)
694{
695  return ctx->pathlen > 0;
696}
697
698static inline bool rtems_filesystem_eval_path_has_token(
699  const rtems_filesystem_eval_path_context_t *ctx
700)
701{
702  return ctx->tokenlen > 0;
703}
704
705static inline int rtems_filesystem_eval_path_get_flags(
706  const rtems_filesystem_eval_path_context_t *ctx
707)
708{
709  return ctx->flags;
710}
711
712static inline void rtems_filesystem_eval_path_set_flags(
713  rtems_filesystem_eval_path_context_t *ctx,
714  int flags
715)
716{
717  ctx->flags = flags;
718}
719
720static inline void rtems_filesystem_eval_path_clear_and_set_flags(
721  rtems_filesystem_eval_path_context_t *ctx,
722  int clear,
723  int set
724)
725{
726  int flags = ctx->flags;
727
728  flags &= ~clear;
729  flags |= set;
730
731  ctx->flags = flags;
732}
733
734static inline void rtems_filesystem_eval_path_extract_currentloc(
735  rtems_filesystem_eval_path_context_t *ctx,
736  rtems_filesystem_location_info_t *get
737)
738{
739  rtems_filesystem_location_copy_and_detach(
740    get,
741    &ctx->currentloc
742  );
743}
744
745void rtems_filesystem_eval_path_error(
746  rtems_filesystem_eval_path_context_t *ctx,
747  int eno
748);
749
750/**
751 * @brief Checks that the locations exist in the same file system instance.
752 *
753 * @retval 0 The locations exist and are in the same file system instance.
754 * @retval -1 An error occured.  The @c errno indicates the error.
755 */
756int rtems_filesystem_location_exists_in_same_fs_instance_as(
757  const rtems_filesystem_location_info_t *a,
758  const rtems_filesystem_location_info_t *b
759);
760
761bool rtems_filesystem_check_access(
762  int eval_flags,
763  mode_t node_mode,
764  uid_t node_uid,
765  gid_t node_gid
766);
767
768bool rtems_filesystem_eval_path_check_access(
769  rtems_filesystem_eval_path_context_t *ctx,
770  int eval_flags,
771  mode_t node_mode,
772  uid_t node_uid,
773  gid_t node_gid
774);
775
776static inline bool rtems_filesystem_is_delimiter(char c)
777{
778  return c == '/' || c == '\\';
779}
780
781static inline bool rtems_filesystem_is_current_directory(
782  const char *token,
783  size_t tokenlen
784)
785{
786  return tokenlen == 1 && token [0] == '.';
787}
788
789static inline bool rtems_filesystem_is_parent_directory(
790  const char *token,
791  size_t tokenlen
792)
793{
794  return tokenlen == 2 && token [0] == '.' && token [1] == '.';
795}
796
797#ifdef __cplusplus
798}
799#endif
800
801#endif
802/* end of include file */
Note: See TracBrowser for help on using the repository browser.