OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libcsupport/] [src/] [libio.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
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
 *  libio.c,v 1.38 2001/10/26 19:22:03 joel Exp
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
 
51
extern unsigned32  rtems_libio_number_iops;
52
rtems_id           rtems_libio_semaphore;
53
rtems_libio_t     *rtems_libio_iops;
54
rtems_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
 
62
void 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
 
109
rtems_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
 
116
rtems_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
 
124
unsigned32 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
 
154
unsigned32 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
 
190
rtems_libio_t *rtems_libio_allocate( void )
191
{
192
  rtems_libio_t *iop, *next;
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
    next = iop->data1;
200
    (void) memset( iop, 0, sizeof(rtems_libio_t) );
201
    iop->flags = LIBIO_FLAGS_OPEN;
202
    rc = rtems_semaphore_create(
203
      RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
204
      1,
205
      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
206
      RTEMS_NO_PRIORITY,
207
      &iop->sem
208
    );
209
    if (rc != RTEMS_SUCCESSFUL)
210
      goto failed;
211
    rtems_libio_iop_freelist = next;
212
    goto done;
213
  }
214
 
215
failed:
216
  iop = 0;
217
 
218
done:
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
 
230
void 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->flags &= ~LIBIO_FLAGS_OPEN;
240
    iop->data1 = rtems_libio_iop_freelist;
241
    rtems_libio_iop_freelist = iop;
242
 
243
  rtems_semaphore_release(rtems_libio_semaphore);
244
}
245
 
246
/*
247
 *  rtems_libio_is_open_files_in_fs
248
 *
249
 *  This routine scans the entire file descriptor table to determine if the
250
 *  are any active file descriptors that refer to the at least one node in the
251
 *  file system that we are trying to dismount.
252
 *
253
 *  If there is at least one node in the file system referenced by the mount
254
 *  table entry a 1 is returned, otherwise a 0 is returned.
255
 */
256
 
257
int rtems_libio_is_open_files_in_fs(
258
  rtems_filesystem_mount_table_entry_t * fs_mt_entry
259
)
260
{
261
  rtems_libio_t     *iop;
262
  int                result = 0;
263
  int                i;
264
 
265
  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
266
 
267
  /*
268
   *  Look for any active file descriptor entry.
269
   */
270
 
271
  for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
272
 
273
    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
274
 
275
       /*
276
        *  Check if this node is under the file system that we
277
        *  are trying to dismount.
278
        */
279
 
280
       if ( iop->pathinfo.mt_entry == fs_mt_entry ) {
281
          result = 1;
282
          break;
283
       }
284
    }
285
  }
286
 
287
  rtems_semaphore_release( rtems_libio_semaphore );
288
 
289
  return result;
290
}
291
 
292
/*
293
 *  rtems_libio_is_file_open
294
 *
295
 *  This routine scans the entire file descriptor table to determine if the
296
 *  given file refers to an active file descriptor.
297
 *
298
 *  If the given file is open a 1 is returned, otherwise a 0 is returned.
299
 */
300
 
301
int rtems_libio_is_file_open(
302
  void         *node_access
303
)
304
{
305
  rtems_libio_t     *iop;
306
  int                result=0;
307
  int                i;
308
 
309
  rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
310
 
311
  /*
312
   *  Look for any active file descriptor entry.
313
   */
314
 
315
 for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){
316
    if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
317
 
318
       /*
319
        *  Check if this node is under the file system that we
320
        *  are trying to dismount.
321
        */
322
 
323
       if ( iop->pathinfo.node_access == node_access ) {
324
          result = 1;
325
          break;
326
       }
327
    }
328
  }
329
 
330
  rtems_semaphore_release( rtems_libio_semaphore );
331
 
332
  return result;
333
}
334
 
335
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.