source: rtems/c/src/exec/libcsupport/src/libio.c @ df49c60

4.104.114.84.95
Last change on this file since df49c60 was df49c60, checked in by Joel Sherrill <joel.sherrill@…>, on 06/12/00 at 15:00:15

Merged from 4.5.0-beta3a

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