source: rtems/c/src/lib/libc/libio.c @ 4a238002

4.104.114.84.95
Last change on this file since 4a238002 was 08311cc3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/17/99 at 17:51:34

Updated copyright notice.

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