source: rtems/c/src/lib/libc/libio.c @ 2e7ed911

4.104.114.84.95
Last change on this file since 2e7ed911 was 6f43d82, checked in by Joel Sherrill <joel.sherrill@…>, on 04/24/01 at 23:10:04

2001-04-24 Joel Sherrill <joel@…>

  • libc/libio.c (rtems_libio_allocate): Make sure size and offset

fields are cleared on each file open. Before this field was cleared,
this resulted in the value from the last time that IOP was used
being still in place. Discovered by Andrew Bythell
<abythell@…>.

  • libc/open.c: Remove redundant setting of iop->offset.
  • Property mode set to 100644
File size: 7.9 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#if HAVE_CONFIG_H
17#include "config.h"
18#endif
19
20#include <rtems/libio_.h>               /* libio_.h pulls in rtems */
21#include <rtems.h>
22#include <rtems/assoc.h>                /* assoc.h not included by rtems.h */
23
24#include <stdio.h>                      /* O_RDONLY, et.al. */
25#include <fcntl.h>                      /* O_RDONLY, et.al. */
26#include <assert.h>
27#include <errno.h>
28
29#if ! defined(O_NDELAY)
30# if defined(solaris2)
31#  define O_NDELAY O_NONBLOCK
32# elif defined(__CYGWIN__)
33#   define O_NDELAY _FNBIO
34# elif defined(RTEMS_NEWLIB)
35#  define O_NDELAY _FNBIO
36# endif
37#endif
38
39
40#include <errno.h>
41#include <string.h>                     /* strcmp */
42#include <unistd.h>
43#include <stdlib.h>                     /* calloc() */
44
45#include <rtems/libio.h>                /* libio.h not pulled in by rtems */
46
47/*                           
48 *  File descriptor Table Information
49 */         
50
51extern unsigned32  rtems_libio_number_iops;
52rtems_id           rtems_libio_semaphore;
53rtems_libio_t     *rtems_libio_iops;
54rtems_libio_t     *rtems_libio_iop_freelist;
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  { "NONBLOCK",  LIBIO_FLAGS_NO_DELAY,  O_NONBLOCK },
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    iop->size = 0;
212    iop->offset = 0;
213    goto done;
214  }
215 
216failed:
217  iop = 0;
218 
219done:
220  rtems_semaphore_release( rtems_libio_semaphore );
221  return iop;
222}
223
224/*
225 *  rtems_libio_free
226 *
227 *  This routine frees the resources associated with an IOP (file descriptor)
228 *  and clears the slot in the IOP Table.
229 */
230
231void rtems_libio_free(
232  rtems_libio_t *iop
233)
234{
235  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
236
237    if (iop->sem)
238      rtems_semaphore_delete(iop->sem);
239
240    iop->flags &= ~LIBIO_FLAGS_OPEN;
241    iop->data1 = rtems_libio_iop_freelist;
242    rtems_libio_iop_freelist = iop;
243
244  rtems_semaphore_release(rtems_libio_semaphore);
245}
246
247/*
248 *  rtems_libio_is_open_files_in_fs
249 *
250 *  This routine scans the entire file descriptor table to determine if the
251 *  are any active file descriptors that refer to the at least one node in the
252 *  file system that we are trying to dismount.
253 *
254 *  If there is at least one node in the file system referenced by the mount
255 *  table entry a 1 is returned, otherwise a 0 is returned.
256 */
257
258int rtems_libio_is_open_files_in_fs(
259  rtems_filesystem_mount_table_entry_t * fs_mt_entry
260)
261{
262  rtems_libio_t     *iop;
263  int                result = 0;
264  int                i;
265
266  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
267             
268  /*
269   *  Look for any active file descriptor entry.
270   */         
271     
272  for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
273       
274    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
275       
276       /*
277        *  Check if this node is under the file system that we
278        *  are trying to dismount.
279        */
280
281       if ( iop->pathinfo.mt_entry == fs_mt_entry ) {
282          result = 1;
283          break;
284       }
285    }
286  }
287
288  rtems_semaphore_release( rtems_libio_semaphore );
289 
290  return result;
291}
292
293/*
294 *  rtems_libio_is_file_open
295 *
296 *  This routine scans the entire file descriptor table to determine if the
297 *  given file refers to an active file descriptor.
298 *
299 *  If the given file is open a 1 is returned, otherwise a 0 is returned.
300 */
301
302int rtems_libio_is_file_open(
303  void         *node_access
304)
305{
306  rtems_libio_t     *iop;
307  int                result=0;
308  int                i;
309
310  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
311
312  /*
313   *  Look for any active file descriptor entry.
314   */
315 
316 for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
317    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
318 
319       /*
320        *  Check if this node is under the file system that we
321        *  are trying to dismount.
322        */
323
324       if ( iop->pathinfo.node_access == node_access ) {
325          result = 1;
326          break;
327       }
328    }
329  }
330
331  rtems_semaphore_release( rtems_libio_semaphore );
332
333  return result;
334}
335
336
Note: See TracBrowser for help on using the repository browser.