source: rtems/cpukit/libcsupport/src/libio.c @ bf95ccb5

4.104.114.95
Last change on this file since bf95ccb5 was bf95ccb5, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 05/27/08 at 10:34:15

Added const qualifier to various pointers and data tables to

reduce size of data area.
IMFS: Fixed creation of symbolic links to avoid a compiler warning.
DOSFS: Use LibBlock? instead of read() to read the boot record.

  • Property mode set to 100644
File size: 7.1 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 <rtems/libio_.h>               /* libio_.h pulls in rtems */
21#include <rtems.h>
22#include <rtems/assoc.h>                /* assoc.h not included by rtems.h */
23
24#include <stdio.h>                      /* O_RDONLY, et.al. */
25#include <fcntl.h>                      /* O_RDONLY, et.al. */
26#include <assert.h>
27#include <errno.h>
28
29/* define this to alias O_NDELAY to  O_NONBLOCK, i.e.,
30 * O_NDELAY is accepted on input but fcntl(F_GETFL) returns
31 * O_NONBLOCK. This is because rtems has no distinction
32 * between the two (but some systems have).
33 * Note that accepting this alias creates a problem:
34 * an application trying to clear the non-blocking flag
35 * using a
36 *
37 *    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NDELAY);
38 *
39 * does (silently) ignore the operation.
40 */
41#undef ACCEPT_O_NDELAY_ALIAS
42
43#include <errno.h>
44#include <string.h>                     /* strcmp */
45#include <unistd.h>
46#include <stdlib.h>                     /* calloc() */
47
48#include <rtems/libio.h>                /* libio.h not pulled in by rtems */
49
50/*
51 *  File descriptor Table Information
52 */
53
54extern uint32_t       rtems_libio_number_iops;
55extern rtems_id       rtems_libio_semaphore;
56extern rtems_libio_t *rtems_libio_iops;
57extern rtems_libio_t *rtems_libio_iop_freelist;
58
59/*
60 *  rtems_libio_fcntl_flags
61 *
62 *  Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
63 */
64
65const rtems_assoc_t access_modes_assoc[] = {
66  { "READ",       LIBIO_FLAGS_READ,  O_RDONLY },
67  { "WRITE",      LIBIO_FLAGS_WRITE, O_WRONLY },
68  { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
69  { 0, 0, 0 },
70};
71
72const rtems_assoc_t status_flags_assoc[] = {
73#ifdef ACCEPT_O_NDELAY_ALIAS
74  { "NO DELAY",  LIBIO_FLAGS_NO_DELAY,  O_NDELAY },
75#endif
76  { "NONBLOCK",  LIBIO_FLAGS_NO_DELAY,  O_NONBLOCK },
77  { "APPEND",    LIBIO_FLAGS_APPEND,    O_APPEND },
78  { "CREATE",    LIBIO_FLAGS_CREATE,    O_CREAT },
79  { 0, 0, 0 },
80};
81
82uint32_t   rtems_libio_fcntl_flags(
83  uint32_t   fcntl_flags
84)
85{
86  uint32_t   flags = 0;
87  uint32_t   access_modes;
88
89  /*
90   * Access mode is a small integer
91   */
92
93  access_modes = fcntl_flags & O_ACCMODE;
94  fcntl_flags &= ~O_ACCMODE;
95  flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
96
97  /*
98   * Everything else is single bits
99   */
100
101  flags |=
102     rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
103  return flags;
104}
105
106/*
107 *  rtems_libio_to_fcntl_flags
108 *
109 *  Convert RTEMS internal flags to UNIX fnctl(2) flags
110 */
111
112uint32_t   rtems_libio_to_fcntl_flags(
113  uint32_t   flags
114)
115{
116  uint32_t   fcntl_flags = 0;
117
118  if ( (flags & LIBIO_FLAGS_READ_WRITE) == LIBIO_FLAGS_READ_WRITE ) {
119    fcntl_flags |= O_RDWR;
120  } else if ( (flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
121    fcntl_flags |= O_RDONLY;
122  } else if ( (flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
123    fcntl_flags |= O_WRONLY;
124  }
125
126  if ( (flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY ) {
127    fcntl_flags |= O_NONBLOCK;
128  }
129
130  if ( (flags & LIBIO_FLAGS_APPEND) == LIBIO_FLAGS_APPEND ) {
131    fcntl_flags |= O_APPEND;
132  }
133
134  if ( (flags & LIBIO_FLAGS_CREATE) == LIBIO_FLAGS_CREATE ) {
135    fcntl_flags |= O_CREAT;
136  }
137
138  return fcntl_flags;
139}
140
141/*
142 *  rtems_libio_allocate
143 *
144 *  This routine searches the IOP Table for an unused entry.  If it
145 *  finds one, it returns it.  Otherwise, it returns NULL.
146 */
147
148rtems_libio_t *rtems_libio_allocate( void )
149{
150  rtems_libio_t *iop, *next;
151  rtems_status_code rc;
152
153  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
154
155  if (rtems_libio_iop_freelist) {
156    iop = rtems_libio_iop_freelist;
157    next = iop->data1;
158    (void) memset( iop, 0, sizeof(rtems_libio_t) );
159    iop->flags = LIBIO_FLAGS_OPEN;
160    rc = rtems_semaphore_create(
161      RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
162      1,
163      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
164      RTEMS_NO_PRIORITY,
165      &iop->sem
166    );
167    if (rc != RTEMS_SUCCESSFUL)
168      goto failed;
169    rtems_libio_iop_freelist = next;
170    goto done;
171  }
172
173failed:
174  iop = 0;
175
176done:
177  rtems_semaphore_release( rtems_libio_semaphore );
178  return iop;
179}
180
181/*
182 *  rtems_libio_free
183 *
184 *  This routine frees the resources associated with an IOP (file descriptor)
185 *  and clears the slot in the IOP Table.
186 */
187
188void rtems_libio_free(
189  rtems_libio_t *iop
190)
191{
192  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
193
194    if (iop->sem)
195      rtems_semaphore_delete(iop->sem);
196
197    iop->flags &= ~LIBIO_FLAGS_OPEN;
198    iop->data1 = rtems_libio_iop_freelist;
199    rtems_libio_iop_freelist = iop;
200
201  rtems_semaphore_release(rtems_libio_semaphore);
202}
203
204/*
205 *  rtems_libio_is_open_files_in_fs
206 *
207 *  This routine scans the entire file descriptor table to determine if the
208 *  are any active file descriptors that refer to the at least one node in the
209 *  file system that we are trying to dismount.
210 *
211 *  If there is at least one node in the file system referenced by the mount
212 *  table entry a 1 is returned, otherwise a 0 is returned.
213 */
214
215int rtems_libio_is_open_files_in_fs(
216  rtems_filesystem_mount_table_entry_t * fs_mt_entry
217)
218{
219  rtems_libio_t     *iop;
220  int                result = 0;
221  int                i;
222
223  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
224
225  /*
226   *  Look for any active file descriptor entry.
227   */
228
229  for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
230
231    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
232
233       /*
234        *  Check if this node is under the file system that we
235        *  are trying to dismount.
236        */
237
238       if ( iop->pathinfo.mt_entry == fs_mt_entry ) {
239          result = 1;
240          break;
241       }
242    }
243  }
244
245  rtems_semaphore_release( rtems_libio_semaphore );
246
247  return result;
248}
249
250/*
251 *  rtems_libio_is_file_open
252 *
253 *  This routine scans the entire file descriptor table to determine if the
254 *  given file refers to an active file descriptor.
255 *
256 *  If the given file is open a 1 is returned, otherwise a 0 is returned.
257 */
258
259int rtems_libio_is_file_open(
260  void         *node_access
261)
262{
263  rtems_libio_t     *iop;
264  int                result=0;
265  int                i;
266
267  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
268
269  /*
270   *  Look for any active file descriptor entry.
271   */
272
273 for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
274    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
275
276       /*
277        *  Check if this node is under the file system that we
278        *  are trying to dismount.
279        */
280
281       if ( iop->pathinfo.node_access == node_access ) {
282          result = 1;
283          break;
284       }
285    }
286  }
287
288  rtems_semaphore_release( rtems_libio_semaphore );
289
290  return result;
291}
Note: See TracBrowser for help on using the repository browser.