source: rtems/cpukit/libcsupport/src/libio.c @ 3b7c123

4.115
Last change on this file since 3b7c123 was 3b7c123, checked in by Sebastian Huber <sebastian.huber@…>, on 03/13/12 at 10:33:51

Filesystem: Reference counting for locations

o A new data structure rtems_filesystem_global_location_t was

introduced to be used for

o the mount point location in the mount table entry,
o the file system root location in the mount table entry,
o the root directory location in the user environment, and
o the current directory location in the user environment.

During the path evaluation global start locations are obtained to
ensure that the current file system instance will be not unmounted in
the meantime.

o The user environment uses now reference counting and is protected

from concurrent access.

o The path evaluation process was completely rewritten and simplified.

The IMFS, RFS, NFS, and DOSFS use now a generic path evaluation
method. Recursive calls in the path evaluation have been replaced
with iteration to avoid stack overflows. Only the evaluation of
symbolic links is recursive. No dynamic memory allocations and
intermediate buffers are used in the high level path evaluation. No
global locks are held during the file system instance specific path
evaluation process.

o Recursive symbolic link evaluation is now limited by

RTEMS_FILESYSTEM_SYMLOOP_MAX. Applications can retrieve this value
via sysconf().

o The device file system (devFS) uses now no global variables and

allocation from the workspace. Node names are allocated from the
heap.

o The upper layer lseek() performs now some parameter checks.
o The upper layer ftruncate() performs now some parameter checks.
o unmask() is now restricted to the RWX flags and protected from

concurrent access.

o The fchmod_h and rmnod_h file system node handlers are now a file

system operation.

o The unlink_h operation has been removed. All nodes are now destroyed

with the rmnod_h operation.

o New lock_h, unlock_h, clonenod_h, and are_nodes_equal_h file system

operations.

o The path evaluation and file system operations are now protected by

per file system instance lock and unlock operations.

o Fix and test file descriptor duplicate in fcntl().
o New test fstests/fsnofs01.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 *  This file contains the support infrastructure used to manage the
3 *  table of integer style file descriptors used by the low level
4 *  POSIX system calls like open(), read, fstat(), etc.
5 *
6 *  COPYRIGHT (c) 1989-1999.
7 *  On-Line Applications Research Corporation (OAR).
8 *
9 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.rtems.com/license/LICENSE.
12 *
13 *  $Id$
14 */
15
16#if HAVE_CONFIG_H
17#include "config.h"
18#endif
19
20#include <fcntl.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26#include <rtems.h>
27#include <rtems/libio_.h>
28#include <rtems/assoc.h>
29
30/* define this to alias O_NDELAY to  O_NONBLOCK, i.e.,
31 * O_NDELAY is accepted on input but fcntl(F_GETFL) returns
32 * O_NONBLOCK. This is because rtems has no distinction
33 * between the two (but some systems have).
34 * Note that accepting this alias creates a problem:
35 * an application trying to clear the non-blocking flag
36 * using a
37 *
38 *    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NDELAY);
39 *
40 * does (silently) ignore the operation.
41 */
42#undef ACCEPT_O_NDELAY_ALIAS
43
44/*
45 *  rtems_libio_fcntl_flags
46 *
47 *  Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
48 */
49
50static const rtems_assoc_t access_modes_assoc[] = {
51  { "READ",       LIBIO_FLAGS_READ,  O_RDONLY },
52  { "WRITE",      LIBIO_FLAGS_WRITE, O_WRONLY },
53  { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
54  { 0, 0, 0 },
55};
56
57static const rtems_assoc_t status_flags_assoc[] = {
58#ifdef ACCEPT_O_NDELAY_ALIAS
59  { "NO DELAY",  LIBIO_FLAGS_NO_DELAY,  O_NDELAY },
60#endif
61  { "NONBLOCK",  LIBIO_FLAGS_NO_DELAY,  O_NONBLOCK },
62  { "APPEND",    LIBIO_FLAGS_APPEND,    O_APPEND },
63  { "CREATE",    LIBIO_FLAGS_CREATE,    O_CREAT },
64  { 0, 0, 0 },
65};
66
67uint32_t rtems_libio_fcntl_flags( int fcntl_flags )
68{
69  uint32_t   flags = 0;
70  uint32_t   access_modes;
71
72  /*
73   * Access mode is a small integer
74   */
75
76  access_modes = (uint32_t) (fcntl_flags & O_ACCMODE);
77  fcntl_flags &= ~O_ACCMODE;
78  flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
79
80  /*
81   * Everything else is single bits
82   */
83
84  flags |= rtems_assoc_local_by_remote_bitfield(
85    status_flags_assoc,
86    (uint32_t) fcntl_flags
87  );
88
89  return flags;
90}
91
92/*
93 *  rtems_libio_to_fcntl_flags
94 *
95 *  Convert RTEMS internal flags to UNIX fnctl(2) flags
96 */
97
98int rtems_libio_to_fcntl_flags( uint32_t flags )
99{
100  int fcntl_flags = 0;
101
102  if ( (flags & LIBIO_FLAGS_READ_WRITE) == LIBIO_FLAGS_READ_WRITE ) {
103    fcntl_flags |= O_RDWR;
104  } else if ( (flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
105    fcntl_flags |= O_RDONLY;
106  } else if ( (flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
107    fcntl_flags |= O_WRONLY;
108  }
109
110  if ( (flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY ) {
111    fcntl_flags |= O_NONBLOCK;
112  }
113
114  if ( (flags & LIBIO_FLAGS_APPEND) == LIBIO_FLAGS_APPEND ) {
115    fcntl_flags |= O_APPEND;
116  }
117
118  if ( (flags & LIBIO_FLAGS_CREATE) == LIBIO_FLAGS_CREATE ) {
119    fcntl_flags |= O_CREAT;
120  }
121
122  return fcntl_flags;
123}
124
125/*
126 *  rtems_libio_allocate
127 *
128 *  This routine searches the IOP Table for an unused entry.  If it
129 *  finds one, it returns it.  Otherwise, it returns NULL.
130 */
131
132rtems_libio_t *rtems_libio_allocate( void )
133{
134  rtems_libio_t *iop, *next;
135  rtems_status_code rc;
136  rtems_id sema;
137
138  rtems_libio_lock();
139
140  if (rtems_libio_iop_freelist) {
141    rc = rtems_semaphore_create(
142      RTEMS_LIBIO_IOP_SEM(rtems_libio_iop_freelist - rtems_libio_iops),
143      1,
144      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
145      0,
146      &sema
147    );
148    if (rc != RTEMS_SUCCESSFUL)
149      goto failed;
150    iop = rtems_libio_iop_freelist;
151    next = iop->data1;
152    (void) memset( iop, 0, sizeof(rtems_libio_t) );
153    iop->flags = LIBIO_FLAGS_OPEN;
154    iop->sem = sema;
155    rtems_libio_iop_freelist = next;
156    goto done;
157  }
158
159failed:
160  iop = 0;
161
162done:
163  rtems_libio_unlock();
164  return iop;
165}
166
167/*
168 *  rtems_libio_free
169 *
170 *  This routine frees the resources associated with an IOP (file descriptor)
171 *  and clears the slot in the IOP Table.
172 */
173
174void rtems_libio_free(
175  rtems_libio_t *iop
176)
177{
178  rtems_filesystem_location_free( &iop->pathinfo );
179
180  rtems_libio_lock();
181
182    if (iop->sem)
183      rtems_semaphore_delete(iop->sem);
184
185    iop->flags &= ~LIBIO_FLAGS_OPEN;
186    iop->data1 = rtems_libio_iop_freelist;
187    rtems_libio_iop_freelist = iop;
188
189  rtems_libio_unlock();
190}
Note: See TracBrowser for help on using the repository browser.