source: rtems/cpukit/libcsupport/src/libio.c @ 23c4bbf5

4.104.114.84.95
Last change on this file since 23c4bbf5 was 23c4bbf5, checked in by Joel Sherrill <joel.sherrill@…>, on 03/16/99 at 01:41:16

Use proper include for libio.h.

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