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

4.104.114.84.95
Last change on this file since 5a9a5ec was 5a9a5ec, checked in by Joel Sherrill <joel.sherrill@…>, on 09/05/00 at 15:46:02

2000-09-05 Joel Sherrill <joel@…>

  • libio.c: Added O_NONBLOCK to list of flags.
  • 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
[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 },
[5a9a5ec]112  { "NONBLOCK",  LIBIO_FLAGS_NO_DELAY,  O_NONBLOCK },
[07a3253d]113  { "APPEND",    LIBIO_FLAGS_APPEND,    O_APPEND },
114  { "CREATE",    LIBIO_FLAGS_CREATE,    O_CREAT },
115  { 0, 0, 0 },
[b06e68ef]116};
117
[07a3253d]118unsigned32 rtems_libio_fcntl_flags(
119  unsigned32 fcntl_flags
120)
[b06e68ef]121{
[07a3253d]122  unsigned32 flags = 0;
123  unsigned32 access_modes;
[b06e68ef]124
[07a3253d]125  /*
126   * Access mode is a small integer
127   */
128 
129  access_modes = fcntl_flags & O_ACCMODE;
130  fcntl_flags &= ~O_ACCMODE;
131  flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
[b06e68ef]132
[07a3253d]133  /*
134   * Everything else is single bits
135   */
[b06e68ef]136
[07a3253d]137  flags |=
138     rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
139  return flags;
[b06e68ef]140}
141
[3ef8798]142/*
143 *  rtems_libio_to_fcntl_flags
144 *
145 *  Convert RTEMS internal flags to UNIX fnctl(2) flags
146 */
147
148unsigned32 rtems_libio_to_fcntl_flags(
149  unsigned32 flags
150)
151{
152  unsigned32 fcntl_flags = 0;
153
[3195d9c]154  if ( (flags & LIBIO_FLAGS_READ_WRITE) == LIBIO_FLAGS_READ_WRITE ) {
155    fcntl_flags |= O_RDWR;
156  } else if ( (flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
157    fcntl_flags |= O_RDONLY;
158  } else if ( (flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
159    fcntl_flags |= O_WRONLY;
160  }
161
162  if ( (flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY ) {
163    fcntl_flags |= O_NDELAY;
164  }
165
166  if ( (flags & LIBIO_FLAGS_APPEND) == LIBIO_FLAGS_APPEND ) {
167    fcntl_flags |= O_APPEND;
168  }
169
170  if ( (flags & LIBIO_FLAGS_CREATE) == LIBIO_FLAGS_CREATE ) {
171    fcntl_flags |= O_CREAT;
172  }
173
[3ef8798]174  return fcntl_flags;
175}
176
[07a3253d]177/*
178 *  rtems_libio_allocate
179 *
180 *  This routine searches the IOP Table for an unused entry.  If it
181 *  finds one, it returns it.  Otherwise, it returns NULL.
182 */
[b06e68ef]183
[07a3253d]184rtems_libio_t *rtems_libio_allocate( void )
[b06e68ef]185{
[07a3253d]186  rtems_libio_t *iop;
187  rtems_status_code rc;
188 
189  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
190
[cca4400]191  if (rtems_libio_iop_freelist) {
192    iop = rtems_libio_iop_freelist;
193    rc = rtems_semaphore_create(
194      RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
195      1,
196      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
197      RTEMS_NO_PRIORITY,
198      &iop->sem
199    );
200    if (rc != RTEMS_SUCCESSFUL)
201      goto failed;
202    rtems_libio_iop_freelist = iop->data1;
203    iop->data1 = 0;
204    iop->flags = LIBIO_FLAGS_OPEN;
205    goto done;
[07a3253d]206  }
207 
[b06e68ef]208failed:
[07a3253d]209  iop = 0;
210 
[b06e68ef]211done:
[07a3253d]212  rtems_semaphore_release( rtems_libio_semaphore );
213  return iop;
[b06e68ef]214}
215
[07a3253d]216/*
217 *  rtems_libio_free
218 *
219 *  This routine frees the resources associated with an IOP (file descriptor)
220 *  and clears the slot in the IOP Table.
221 */
[b06e68ef]222
[07a3253d]223void rtems_libio_free(
224  rtems_libio_t *iop
225)
[b06e68ef]226{
[07a3253d]227  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
[b06e68ef]228
[cca4400]229    if (iop->sem)
230      rtems_semaphore_delete(iop->sem);
[b06e68ef]231
[77c81fd2]232    iop->flags &= ~LIBIO_FLAGS_OPEN;
[cca4400]233    iop->data1 = rtems_libio_iop_freelist;
234    rtems_libio_iop_freelist = iop;
[b06e68ef]235
[cca4400]236  rtems_semaphore_release(rtems_libio_semaphore);
[07a3253d]237}
[b06e68ef]238
[07a3253d]239/*
240 *  rtems_libio_is_open_files_in_fs
241 *
242 *  This routine scans the entire file descriptor table to determine if the
[cca4400]243 *  are any active file descriptors that refer to the at least one node in the
[07a3253d]244 *  file system that we are trying to dismount.
245 *
246 *  If there is at least one node in the file system referenced by the mount
247 *  table entry a 1 is returned, otherwise a 0 is returned.
248 */
[78d87bd]249
[07a3253d]250int rtems_libio_is_open_files_in_fs(
251  rtems_filesystem_mount_table_entry_t * fs_mt_entry
252)
[b06e68ef]253{
[07a3253d]254  rtems_libio_t     *iop;
255  int                result = 0;
[77c81fd2]256  int                i;
[b06e68ef]257
[07a3253d]258  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
[cca4400]259             
[07a3253d]260  /*
261   *  Look for any active file descriptor entry.
[cca4400]262   */         
263     
[df49c60]264  for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
[cca4400]265       
[07a3253d]266    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
[cca4400]267       
[07a3253d]268       /*
269        *  Check if this node is under the file system that we
270        *  are trying to dismount.
[cca4400]271        */
[b06e68ef]272
[07a3253d]273       if ( iop->pathinfo.mt_entry == fs_mt_entry ) {
274          result = 1;
275          break;
276       }
[e2d79559]277    }
[07a3253d]278  }
[b06e68ef]279
[07a3253d]280  rtems_semaphore_release( rtems_libio_semaphore );
[cca4400]281 
[07a3253d]282  return result;
[b06e68ef]283}
284
[07a3253d]285/*
286 *  rtems_libio_is_file_open
287 *
288 *  This routine scans the entire file descriptor table to determine if the
289 *  given file refers to an active file descriptor.
[cca4400]290 *
[07a3253d]291 *  If the given file is open a 1 is returned, otherwise a 0 is returned.
292 */
[b06e68ef]293
[07a3253d]294int rtems_libio_is_file_open(
295  void         *node_access
296)
297{
298  rtems_libio_t     *iop;
[cca4400]299  int                result=0;
[77c81fd2]300  int                i;
[b06e68ef]301
[07a3253d]302  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
[b06e68ef]303
[07a3253d]304  /*
305   *  Look for any active file descriptor entry.
306   */
[cca4400]307 
[df49c60]308 for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
[07a3253d]309    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
[cca4400]310 
[07a3253d]311       /*
312        *  Check if this node is under the file system that we
313        *  are trying to dismount.
[cca4400]314        */
[b06e68ef]315
[07a3253d]316       if ( iop->pathinfo.node_access == node_access ) {
317          result = 1;
318          break;
319       }
320    }
321  }
[e2d79559]322
[07a3253d]323  rtems_semaphore_release( rtems_libio_semaphore );
[b06e68ef]324
[07a3253d]325  return result;
[b06e68ef]326}
[cca4400]327
328
Note: See TracBrowser for help on using the repository browser.