source: rtems/cpukit/libcsupport/src/libio.c @ 5dc2b66d

4.104.114.84.95
Last change on this file since 5dc2b66d was 5dc2b66d, checked in by Joel Sherrill <joel.sherrill@…>, on 11/10/00 at 14:23:46

2000-11-10 Ralf Corsepius <corsepiu@…>

  • libc/libio.c: Special treatment of O_NDELAY for Cygwin.
  • Property mode set to 100644
File size: 7.8 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
[3ba74c73]16#include <rtems/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
[5dc2b66d]28# elif defined(__CYGWIN__)
29#   define O_NDELAY _FNBIO
[cca4400]30# elif defined(RTEMS_NEWLIB)
31#  define O_NDELAY _FNBIO
32# endif
33#endif
34
35
36#include <errno.h>
37#include <string.h>                     /* strcmp */
38#include <unistd.h>
39#include <stdlib.h>                     /* calloc() */
40
[23c4bbf5]41#include <rtems/libio.h>                /* libio.h not pulled in by rtems */
[cca4400]42
43/*                           
44 *  File descriptor Table Information
45 */         
46
47extern unsigned32  rtems_libio_number_iops;
48rtems_id           rtems_libio_semaphore;
49rtems_libio_t     *rtems_libio_iops;
50rtems_libio_t     *rtems_libio_iop_freelist;
[b06e68ef]51
52/*
[07a3253d]53 *  rtems_libio_init
54 *
55 *  Called by BSP startup code to initialize the libio subsystem.
[b06e68ef]56 */
57
[07a3253d]58void rtems_libio_init( void )
[b06e68ef]59{
[cca4400]60    rtems_status_code rc;
61    int i;
62    rtems_libio_t *iop;
63
64    if (rtems_libio_number_iops > 0)
65    {
66        rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
67                                                    sizeof(rtems_libio_t));
68        if (rtems_libio_iops == NULL)
69            rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
70
71        iop = rtems_libio_iop_freelist = rtems_libio_iops;
72        for (i = 0 ; i < (rtems_libio_number_iops - 1) ; i++, iop++)
73                iop->data1 = iop + 1;
74        iop->data1 = NULL;
75    }
[07a3253d]76
77  /*
78   *  Create the binary semaphore used to provide mutual exclusion
79   *  on the IOP Table.
80   */
81
82  rc = rtems_semaphore_create(
83    RTEMS_LIBIO_SEM,
84    1,
85    RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
86    RTEMS_NO_PRIORITY,
87    &rtems_libio_semaphore
88  );
89  if ( rc != RTEMS_SUCCESSFUL )
90    rtems_fatal_error_occurred( rc );
91
92  /*
93   *  Initialize the base file system infrastructure.
94   */
95
96  rtems_filesystem_initialize();
[b06e68ef]97}
98
99/*
[07a3253d]100 *  rtems_libio_fcntl_flags
101 *
102 *  Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
[b06e68ef]103 */
104
105rtems_assoc_t access_modes_assoc[] = {
[07a3253d]106  { "READ",       LIBIO_FLAGS_READ,  O_RDONLY },
107  { "WRITE",      LIBIO_FLAGS_WRITE, O_WRONLY },
108  { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
109  { 0, 0, 0 },
[b06e68ef]110};
111
112rtems_assoc_t status_flags_assoc[] = {
[07a3253d]113  { "NO DELAY",  LIBIO_FLAGS_NO_DELAY,  O_NDELAY },
[5a9a5ec]114  { "NONBLOCK",  LIBIO_FLAGS_NO_DELAY,  O_NONBLOCK },
[07a3253d]115  { "APPEND",    LIBIO_FLAGS_APPEND,    O_APPEND },
116  { "CREATE",    LIBIO_FLAGS_CREATE,    O_CREAT },
117  { 0, 0, 0 },
[b06e68ef]118};
119
[07a3253d]120unsigned32 rtems_libio_fcntl_flags(
121  unsigned32 fcntl_flags
122)
[b06e68ef]123{
[07a3253d]124  unsigned32 flags = 0;
125  unsigned32 access_modes;
[b06e68ef]126
[07a3253d]127  /*
128   * Access mode is a small integer
129   */
130 
131  access_modes = fcntl_flags & O_ACCMODE;
132  fcntl_flags &= ~O_ACCMODE;
133  flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
[b06e68ef]134
[07a3253d]135  /*
136   * Everything else is single bits
137   */
[b06e68ef]138
[07a3253d]139  flags |=
140     rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
141  return flags;
[b06e68ef]142}
143
[3ef8798]144/*
145 *  rtems_libio_to_fcntl_flags
146 *
147 *  Convert RTEMS internal flags to UNIX fnctl(2) flags
148 */
149
150unsigned32 rtems_libio_to_fcntl_flags(
151  unsigned32 flags
152)
153{
154  unsigned32 fcntl_flags = 0;
155
[3195d9c]156  if ( (flags & LIBIO_FLAGS_READ_WRITE) == LIBIO_FLAGS_READ_WRITE ) {
157    fcntl_flags |= O_RDWR;
158  } else if ( (flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
159    fcntl_flags |= O_RDONLY;
160  } else if ( (flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
161    fcntl_flags |= O_WRONLY;
162  }
163
164  if ( (flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY ) {
165    fcntl_flags |= O_NDELAY;
166  }
167
168  if ( (flags & LIBIO_FLAGS_APPEND) == LIBIO_FLAGS_APPEND ) {
169    fcntl_flags |= O_APPEND;
170  }
171
172  if ( (flags & LIBIO_FLAGS_CREATE) == LIBIO_FLAGS_CREATE ) {
173    fcntl_flags |= O_CREAT;
174  }
175
[3ef8798]176  return fcntl_flags;
177}
178
[07a3253d]179/*
180 *  rtems_libio_allocate
181 *
182 *  This routine searches the IOP Table for an unused entry.  If it
183 *  finds one, it returns it.  Otherwise, it returns NULL.
184 */
[b06e68ef]185
[07a3253d]186rtems_libio_t *rtems_libio_allocate( void )
[b06e68ef]187{
[07a3253d]188  rtems_libio_t *iop;
189  rtems_status_code rc;
190 
191  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
192
[cca4400]193  if (rtems_libio_iop_freelist) {
194    iop = rtems_libio_iop_freelist;
195    rc = rtems_semaphore_create(
196      RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
197      1,
198      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
199      RTEMS_NO_PRIORITY,
200      &iop->sem
201    );
202    if (rc != RTEMS_SUCCESSFUL)
203      goto failed;
204    rtems_libio_iop_freelist = iop->data1;
205    iop->data1 = 0;
206    iop->flags = LIBIO_FLAGS_OPEN;
207    goto done;
[07a3253d]208  }
209 
[b06e68ef]210failed:
[07a3253d]211  iop = 0;
212 
[b06e68ef]213done:
[07a3253d]214  rtems_semaphore_release( rtems_libio_semaphore );
215  return iop;
[b06e68ef]216}
217
[07a3253d]218/*
219 *  rtems_libio_free
220 *
221 *  This routine frees the resources associated with an IOP (file descriptor)
222 *  and clears the slot in the IOP Table.
223 */
[b06e68ef]224
[07a3253d]225void rtems_libio_free(
226  rtems_libio_t *iop
227)
[b06e68ef]228{
[07a3253d]229  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
[b06e68ef]230
[cca4400]231    if (iop->sem)
232      rtems_semaphore_delete(iop->sem);
[b06e68ef]233
[77c81fd2]234    iop->flags &= ~LIBIO_FLAGS_OPEN;
[cca4400]235    iop->data1 = rtems_libio_iop_freelist;
236    rtems_libio_iop_freelist = iop;
[b06e68ef]237
[cca4400]238  rtems_semaphore_release(rtems_libio_semaphore);
[07a3253d]239}
[b06e68ef]240
[07a3253d]241/*
242 *  rtems_libio_is_open_files_in_fs
243 *
244 *  This routine scans the entire file descriptor table to determine if the
[cca4400]245 *  are any active file descriptors that refer to the at least one node in the
[07a3253d]246 *  file system that we are trying to dismount.
247 *
248 *  If there is at least one node in the file system referenced by the mount
249 *  table entry a 1 is returned, otherwise a 0 is returned.
250 */
[78d87bd]251
[07a3253d]252int rtems_libio_is_open_files_in_fs(
253  rtems_filesystem_mount_table_entry_t * fs_mt_entry
254)
[b06e68ef]255{
[07a3253d]256  rtems_libio_t     *iop;
257  int                result = 0;
[77c81fd2]258  int                i;
[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     
[df49c60]266  for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
[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;
[77c81fd2]302  int                i;
[b06e68ef]303
[07a3253d]304  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
[b06e68ef]305
[07a3253d]306  /*
307   *  Look for any active file descriptor entry.
308   */
[cca4400]309 
[df49c60]310 for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
[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.