source: rtems/c/src/lib/libc/libio.c @ cca4400

4.104.114.84.95
Last change on this file since cca4400 was cca4400, checked in by Joel Sherrill <joel.sherrill@…>, on 12/10/98 at 23:31:54

Merged Eric Norum's select patch that was based on 4.0 and resolved
all conflicts.

  • Property mode set to 100644
File size: 7.9 KB
RevLine 
[b06e68ef]1/*
[07a3253d]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-1998.
7 *  On-Line Applications Research Corporation (OAR).
8 *  Copyright assigned to U.S. Government, 1994.
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.OARcorp.com/rtems/license.html.
[b06e68ef]13 *
14 *  $Id$
15 */
16
[07a3253d]17#include "libio_.h"                   /* libio_.h pulls in rtems */
[cca4400]18#include <rtems.h>
19#include <rtems/assoc.h>                /* assoc.h not included by rtems.h */
20
21#include <stdio.h>                      /* O_RDONLY, et.al. */
22#include <fcntl.h>                      /* O_RDONLY, et.al. */
23#include <assert.h>
24#include <errno.h>
25
26#if ! defined(O_NDELAY)
27# if defined(solaris2)
28#  define O_NDELAY O_NONBLOCK
29# elif defined(RTEMS_NEWLIB)
30#  define O_NDELAY _FNBIO
31# endif
32#endif
33
34
35#include <errno.h>
36#include <string.h>                     /* strcmp */
37#include <unistd.h>
38#include <stdlib.h>                     /* calloc() */
39
40#include "libio.h"                      /* libio.h not pulled in by rtems */
41
42/*                           
43 *  File descriptor Table Information
44 */         
45
46extern unsigned32  rtems_libio_number_iops;
47rtems_id           rtems_libio_semaphore;
48rtems_libio_t     *rtems_libio_iops;
49rtems_libio_t     *rtems_libio_last_iop;
50rtems_libio_t     *rtems_libio_iop_freelist;
[b06e68ef]51
52/*
[cca4400]53 *  External I/O Handlers Table
54 *
55 *  Space for all possible handlers is preallocated
56 *  to speed up dispatch to external handlers.
[b06e68ef]57 */
58
[07a3253d]59rtems_libio_handler_t   rtems_libio_handlers[15];
[b06e68ef]60
[cca4400]61/*
62 *  Default mode for all files.
63 */
64
65mode_t    rtems_filesystem_umask;
66
[e2d79559]67/*
[07a3253d]68 *  rtems_register_libio_handler
69 *
70 *  This function registers an external IO handler set.  This lets
71 *  other subsystems have their own versions of many of the system
72 *  calls.  For example, the networking code registers handlers which
73 *  map the system calls for read() and write() to socket calls.
74 *
[e2d79559]75 */
76
[07a3253d]77void rtems_register_libio_handler(
78  int                          handler_flag,
79  const rtems_libio_handler_t *handler
[e2d79559]80)
81{
[cca4400]82  int handler_index = (handler_flag >> LIBIO_FLAGS_HANDLER_SHIFT) - 1;
[e2d79559]83
84  if ((handler_index < 0) || (handler_index >= 15))
85    rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
[b06e68ef]86
[07a3253d]87  rtems_libio_handlers[handler_index] = *handler;
[b06e68ef]88}
89
90/*
[07a3253d]91 *  rtems_libio_init
92 *
93 *  Called by BSP startup code to initialize the libio subsystem.
[b06e68ef]94 */
95
[07a3253d]96void rtems_libio_init( void )
[b06e68ef]97{
[cca4400]98    rtems_status_code rc;
99    int i;
100    rtems_libio_t *iop;
101
102    if (rtems_libio_number_iops > 0)
103    {
104        rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
105                                                    sizeof(rtems_libio_t));
106        if (rtems_libio_iops == NULL)
107            rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
108
109        iop = rtems_libio_iop_freelist = rtems_libio_iops;
110        for (i = 0 ; i < (rtems_libio_number_iops - 1) ; i++, iop++)
111                iop->data1 = iop + 1;
112        iop->data1 = NULL;
113    }
[07a3253d]114
115  /*
116   *  Create the binary semaphore used to provide mutual exclusion
117   *  on the IOP Table.
118   */
119
120  rc = rtems_semaphore_create(
121    RTEMS_LIBIO_SEM,
122    1,
123    RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
124    RTEMS_NO_PRIORITY,
125    &rtems_libio_semaphore
126  );
127  if ( rc != RTEMS_SUCCESSFUL )
128    rtems_fatal_error_occurred( rc );
129
130  /*
131   *  Initialize the base file system infrastructure.
132   */
133
134  rtems_filesystem_initialize();
[b06e68ef]135}
136
137/*
[07a3253d]138 *  rtems_libio_fcntl_flags
139 *
140 *  Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
[b06e68ef]141 */
142
143rtems_assoc_t access_modes_assoc[] = {
[07a3253d]144  { "READ",       LIBIO_FLAGS_READ,  O_RDONLY },
145  { "WRITE",      LIBIO_FLAGS_WRITE, O_WRONLY },
146  { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
147  { 0, 0, 0 },
[b06e68ef]148};
149
150rtems_assoc_t status_flags_assoc[] = {
[07a3253d]151  { "NO DELAY",  LIBIO_FLAGS_NO_DELAY,  O_NDELAY },
152  { "APPEND",    LIBIO_FLAGS_APPEND,    O_APPEND },
153  { "CREATE",    LIBIO_FLAGS_CREATE,    O_CREAT },
154  { 0, 0, 0 },
[b06e68ef]155};
156
[07a3253d]157unsigned32 rtems_libio_fcntl_flags(
158  unsigned32 fcntl_flags
159)
[b06e68ef]160{
[07a3253d]161  unsigned32 flags = 0;
162  unsigned32 access_modes;
[b06e68ef]163
[07a3253d]164  /*
165   * Access mode is a small integer
166   */
167 
168  access_modes = fcntl_flags & O_ACCMODE;
169  fcntl_flags &= ~O_ACCMODE;
170  flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
[b06e68ef]171
[07a3253d]172  /*
173   * Everything else is single bits
174   */
[b06e68ef]175
[07a3253d]176  flags |=
177     rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
178  return flags;
[b06e68ef]179}
180
[07a3253d]181/*
182 *  rtems_libio_allocate
183 *
184 *  This routine searches the IOP Table for an unused entry.  If it
185 *  finds one, it returns it.  Otherwise, it returns NULL.
186 */
[b06e68ef]187
[07a3253d]188rtems_libio_t *rtems_libio_allocate( void )
[b06e68ef]189{
[07a3253d]190  rtems_libio_t *iop;
191  rtems_status_code rc;
192 
193  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
194
[cca4400]195  if (rtems_libio_iop_freelist) {
196    iop = rtems_libio_iop_freelist;
197    rc = rtems_semaphore_create(
198      RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
199      1,
200      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
201      RTEMS_NO_PRIORITY,
202      &iop->sem
203    );
204    if (rc != RTEMS_SUCCESSFUL)
205      goto failed;
206    rtems_libio_iop_freelist = iop->data1;
207    iop->data1 = 0;
208    iop->flags = LIBIO_FLAGS_OPEN;
209    goto done;
[07a3253d]210  }
211 
[b06e68ef]212failed:
[07a3253d]213  iop = 0;
214 
[b06e68ef]215done:
[07a3253d]216  rtems_semaphore_release( rtems_libio_semaphore );
217  return iop;
[b06e68ef]218}
219
[07a3253d]220/*
221 *  rtems_libio_free
222 *
223 *  This routine frees the resources associated with an IOP (file descriptor)
224 *  and clears the slot in the IOP Table.
225 */
[b06e68ef]226
[07a3253d]227void rtems_libio_free(
228  rtems_libio_t *iop
229)
[b06e68ef]230{
[07a3253d]231  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
[b06e68ef]232
[cca4400]233    if (iop->sem)
234      rtems_semaphore_delete(iop->sem);
[b06e68ef]235
[cca4400]236    iop->data1 = rtems_libio_iop_freelist;
237    rtems_libio_iop_freelist = iop;
[b06e68ef]238
[cca4400]239  rtems_semaphore_release(rtems_libio_semaphore);
[07a3253d]240}
[b06e68ef]241
[07a3253d]242/*
243 *  rtems_libio_is_open_files_in_fs
244 *
245 *  This routine scans the entire file descriptor table to determine if the
[cca4400]246 *  are any active file descriptors that refer to the at least one node in the
[07a3253d]247 *  file system that we are trying to dismount.
248 *
249 *  If there is at least one node in the file system referenced by the mount
250 *  table entry a 1 is returned, otherwise a 0 is returned.
251 */
[78d87bd]252
[07a3253d]253int rtems_libio_is_open_files_in_fs(
254  rtems_filesystem_mount_table_entry_t * fs_mt_entry
255)
[b06e68ef]256{
[07a3253d]257  rtems_libio_t     *iop;
258  int                result = 0;
[b06e68ef]259
[07a3253d]260  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
[cca4400]261             
[07a3253d]262  /*
263   *  Look for any active file descriptor entry.
[cca4400]264   */         
265     
[07a3253d]266  for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) {
[cca4400]267       
[07a3253d]268    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
[cca4400]269       
[07a3253d]270       /*
271        *  Check if this node is under the file system that we
272        *  are trying to dismount.
[cca4400]273        */
[b06e68ef]274
[07a3253d]275       if ( iop->pathinfo.mt_entry == fs_mt_entry ) {
276          result = 1;
277          break;
278       }
[e2d79559]279    }
[07a3253d]280  }
[b06e68ef]281
[07a3253d]282  rtems_semaphore_release( rtems_libio_semaphore );
[cca4400]283 
[07a3253d]284  return result;
[b06e68ef]285}
286
[07a3253d]287/*
288 *  rtems_libio_is_file_open
289 *
290 *  This routine scans the entire file descriptor table to determine if the
291 *  given file refers to an active file descriptor.
[cca4400]292 *
[07a3253d]293 *  If the given file is open a 1 is returned, otherwise a 0 is returned.
294 */
[b06e68ef]295
[07a3253d]296int rtems_libio_is_file_open(
297  void         *node_access
298)
299{
300  rtems_libio_t     *iop;
[cca4400]301  int                result=0;
[b06e68ef]302
[07a3253d]303  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
[b06e68ef]304
[07a3253d]305  /*
306   *  Look for any active file descriptor entry.
307   */
[cca4400]308 
[07a3253d]309  for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) {
[cca4400]310 
[07a3253d]311    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
[cca4400]312 
[07a3253d]313       /*
314        *  Check if this node is under the file system that we
315        *  are trying to dismount.
[cca4400]316        */
[b06e68ef]317
[07a3253d]318       if ( iop->pathinfo.node_access == node_access ) {
319          result = 1;
320          break;
321       }
322    }
323  }
[e2d79559]324
[07a3253d]325  rtems_semaphore_release( rtems_libio_semaphore );
[b06e68ef]326
[07a3253d]327  return result;
[b06e68ef]328}
[cca4400]329
330
Note: See TracBrowser for help on using the repository browser.