source: rtems/c/src/lib/libc/libio.c @ 1af79634

4.104.114.84.95
Last change on this file since 1af79634 was 1af79634, checked in by Joel Sherrill <joel.sherrill@…>, on 10/25/01 at 17:38:55

2001-10-25 Jennifer Averett <jennifer@…>

  • libc/libio.c: Initialize more fields to NULL/0 during initialiation.
  • include/rtems/libio_.h: Fix freenode macro so it works for sockets which do not have the full set of filesystem operations and are initialized via something other than open().
  • Property mode set to 100644
File size: 8.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.OARcorp.com/rtems/license.html.
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#if ! defined(O_NDELAY)
30# if defined(solaris2)
31#  define O_NDELAY O_NONBLOCK
32# elif defined(__CYGWIN__)
33#   define O_NDELAY _FNBIO
34# elif defined(RTEMS_NEWLIB)
35#  define O_NDELAY _FNBIO
36# endif
37#endif
38
39
40#include <errno.h>
41#include <string.h>                     /* strcmp */
42#include <unistd.h>
43#include <stdlib.h>                     /* calloc() */
44
45#include <rtems/libio.h>                /* libio.h not pulled in by rtems */
46
47/*                           
48 *  File descriptor Table Information
49 */         
50
51extern unsigned32  rtems_libio_number_iops;
52rtems_id           rtems_libio_semaphore;
53rtems_libio_t     *rtems_libio_iops;
54rtems_libio_t     *rtems_libio_iop_freelist;
55
56/*
57 *  rtems_libio_init
58 *
59 *  Called by BSP startup code to initialize the libio subsystem.
60 */
61
62void rtems_libio_init( void )
63{
64    rtems_status_code rc;
65    int i;
66    rtems_libio_t *iop;
67
68    if (rtems_libio_number_iops > 0)
69    {
70        rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
71                                                    sizeof(rtems_libio_t));
72        if (rtems_libio_iops == NULL)
73            rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
74
75        iop = rtems_libio_iop_freelist = rtems_libio_iops;
76        for (i = 0 ; i < (rtems_libio_number_iops - 1) ; i++, iop++)
77                iop->data1 = iop + 1;
78        iop->data1 = NULL;
79    }
80
81  /*
82   *  Create the binary semaphore used to provide mutual exclusion
83   *  on the IOP Table.
84   */
85
86  rc = rtems_semaphore_create(
87    RTEMS_LIBIO_SEM,
88    1,
89    RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
90    RTEMS_NO_PRIORITY,
91    &rtems_libio_semaphore
92  );
93  if ( rc != RTEMS_SUCCESSFUL )
94    rtems_fatal_error_occurred( rc );
95
96  /*
97   *  Initialize the base file system infrastructure.
98   */
99
100  rtems_filesystem_initialize();
101}
102
103/*
104 *  rtems_libio_fcntl_flags
105 *
106 *  Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
107 */
108
109rtems_assoc_t access_modes_assoc[] = {
110  { "READ",       LIBIO_FLAGS_READ,  O_RDONLY },
111  { "WRITE",      LIBIO_FLAGS_WRITE, O_WRONLY },
112  { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
113  { 0, 0, 0 },
114};
115
116rtems_assoc_t status_flags_assoc[] = {
117  { "NO DELAY",  LIBIO_FLAGS_NO_DELAY,  O_NDELAY },
118  { "NONBLOCK",  LIBIO_FLAGS_NO_DELAY,  O_NONBLOCK },
119  { "APPEND",    LIBIO_FLAGS_APPEND,    O_APPEND },
120  { "CREATE",    LIBIO_FLAGS_CREATE,    O_CREAT },
121  { 0, 0, 0 },
122};
123
124unsigned32 rtems_libio_fcntl_flags(
125  unsigned32 fcntl_flags
126)
127{
128  unsigned32 flags = 0;
129  unsigned32 access_modes;
130
131  /*
132   * Access mode is a small integer
133   */
134 
135  access_modes = fcntl_flags & O_ACCMODE;
136  fcntl_flags &= ~O_ACCMODE;
137  flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
138
139  /*
140   * Everything else is single bits
141   */
142
143  flags |=
144     rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
145  return flags;
146}
147
148/*
149 *  rtems_libio_to_fcntl_flags
150 *
151 *  Convert RTEMS internal flags to UNIX fnctl(2) flags
152 */
153
154unsigned32 rtems_libio_to_fcntl_flags(
155  unsigned32 flags
156)
157{
158  unsigned32 fcntl_flags = 0;
159
160  if ( (flags & LIBIO_FLAGS_READ_WRITE) == LIBIO_FLAGS_READ_WRITE ) {
161    fcntl_flags |= O_RDWR;
162  } else if ( (flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
163    fcntl_flags |= O_RDONLY;
164  } else if ( (flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
165    fcntl_flags |= O_WRONLY;
166  }
167
168  if ( (flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY ) {
169    fcntl_flags |= O_NDELAY;
170  }
171
172  if ( (flags & LIBIO_FLAGS_APPEND) == LIBIO_FLAGS_APPEND ) {
173    fcntl_flags |= O_APPEND;
174  }
175
176  if ( (flags & LIBIO_FLAGS_CREATE) == LIBIO_FLAGS_CREATE ) {
177    fcntl_flags |= O_CREAT;
178  }
179
180  return fcntl_flags;
181}
182
183/*
184 *  rtems_libio_allocate
185 *
186 *  This routine searches the IOP Table for an unused entry.  If it
187 *  finds one, it returns it.  Otherwise, it returns NULL.
188 */
189
190rtems_libio_t *rtems_libio_allocate( void )
191{
192  rtems_libio_t *iop;
193  rtems_status_code rc;
194 
195  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
196
197  if (rtems_libio_iop_freelist) {
198    iop = rtems_libio_iop_freelist;
199    rc = rtems_semaphore_create(
200      RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
201      1,
202      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
203      RTEMS_NO_PRIORITY,
204      &iop->sem
205    );
206    if (rc != RTEMS_SUCCESSFUL)
207      goto failed;
208    rtems_libio_iop_freelist = iop->data1;
209
210    iop->driver               = NULL;
211    iop->size                 = 0;
212    iop->offset               = 0;
213    iop->flags                = LIBIO_FLAGS_OPEN;
214    iop->pathinfo.node_access = NULL;
215    iop->pathinfo.handlers    = NULL;
216    iop->pathinfo.ops         = NULL;
217    iop->pathinfo.mt_entry    = NULL;
218    iop->data0                = 0;
219    iop->data1                = NULL;
220    iop->file_info            = NULL;
221    iop->handlers             = NULL;
222   
223    goto done;
224  }
225 
226failed:
227  iop = 0;
228 
229done:
230  rtems_semaphore_release( rtems_libio_semaphore );
231  return iop;
232}
233
234/*
235 *  rtems_libio_free
236 *
237 *  This routine frees the resources associated with an IOP (file descriptor)
238 *  and clears the slot in the IOP Table.
239 */
240
241void rtems_libio_free(
242  rtems_libio_t *iop
243)
244{
245  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
246
247    if (iop->sem)
248      rtems_semaphore_delete(iop->sem);
249
250    iop->flags &= ~LIBIO_FLAGS_OPEN;
251    iop->data1 = rtems_libio_iop_freelist;
252    rtems_libio_iop_freelist = iop;
253
254  rtems_semaphore_release(rtems_libio_semaphore);
255}
256
257/*
258 *  rtems_libio_is_open_files_in_fs
259 *
260 *  This routine scans the entire file descriptor table to determine if the
261 *  are any active file descriptors that refer to the at least one node in the
262 *  file system that we are trying to dismount.
263 *
264 *  If there is at least one node in the file system referenced by the mount
265 *  table entry a 1 is returned, otherwise a 0 is returned.
266 */
267
268int rtems_libio_is_open_files_in_fs(
269  rtems_filesystem_mount_table_entry_t * fs_mt_entry
270)
271{
272  rtems_libio_t     *iop;
273  int                result = 0;
274  int                i;
275
276  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
277             
278  /*
279   *  Look for any active file descriptor entry.
280   */         
281     
282  for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
283       
284    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
285       
286       /*
287        *  Check if this node is under the file system that we
288        *  are trying to dismount.
289        */
290
291       if ( iop->pathinfo.mt_entry == fs_mt_entry ) {
292          result = 1;
293          break;
294       }
295    }
296  }
297
298  rtems_semaphore_release( rtems_libio_semaphore );
299 
300  return result;
301}
302
303/*
304 *  rtems_libio_is_file_open
305 *
306 *  This routine scans the entire file descriptor table to determine if the
307 *  given file refers to an active file descriptor.
308 *
309 *  If the given file is open a 1 is returned, otherwise a 0 is returned.
310 */
311
312int rtems_libio_is_file_open(
313  void         *node_access
314)
315{
316  rtems_libio_t     *iop;
317  int                result=0;
318  int                i;
319
320  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
321
322  /*
323   *  Look for any active file descriptor entry.
324   */
325 
326 for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
327    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
328 
329       /*
330        *  Check if this node is under the file system that we
331        *  are trying to dismount.
332        */
333
334       if ( iop->pathinfo.node_access == node_access ) {
335          result = 1;
336          break;
337       }
338    }
339  }
340
341  rtems_semaphore_release( rtems_libio_semaphore );
342
343  return result;
344}
345
346
Note: See TracBrowser for help on using the repository browser.