source: rtems/c/src/lib/libc/libio.c @ 0cb7cb9

4.104.114.84.95
Last change on this file since 0cb7cb9 was 77c81fd2, checked in by Jennifer Averett <Jennifer.Averett@…>, on 03/29/99 at 18:24:34

Removed an uninitialized variable.

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