source: rtems/cpukit/libcsupport/src/libio.c @ baef823c

5
Last change on this file since baef823c was baef823c, checked in by Sebastian Huber <sebastian.huber@…>, on 09/13/17 at 07:22:19

libio: Add hold/drop iop reference

Check iop reference count in close() and return -1 with errno set to
EBUSY in case the file descriptor is still in use.

Update #3132.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief File Descriptor Routines
5 *  @ingroup LibIOInternal
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <fcntl.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26
27#include <rtems.h>
28#include <rtems/libio_.h>
29#include <rtems/assoc.h>
30
31/* define this to alias O_NDELAY to  O_NONBLOCK, i.e.,
32 * O_NDELAY is accepted on input but fcntl(F_GETFL) returns
33 * O_NONBLOCK. This is because rtems has no distinction
34 * between the two (but some systems have).
35 * Note that accepting this alias creates a problem:
36 * an application trying to clear the non-blocking flag
37 * using a
38 *
39 *    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NDELAY);
40 *
41 * does (silently) ignore the operation.
42 */
43#undef ACCEPT_O_NDELAY_ALIAS
44
45static const rtems_assoc_t access_modes_assoc[] = {
46  { "READ",       LIBIO_FLAGS_READ,  O_RDONLY },
47  { "WRITE",      LIBIO_FLAGS_WRITE, O_WRONLY },
48  { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
49  { 0, 0, 0 },
50};
51
52static const rtems_assoc_t status_flags_assoc[] = {
53#ifdef ACCEPT_O_NDELAY_ALIAS
54  { "NO DELAY",  LIBIO_FLAGS_NO_DELAY,  O_NDELAY },
55#endif
56  { "NONBLOCK",  LIBIO_FLAGS_NO_DELAY,  O_NONBLOCK },
57  { "APPEND",    LIBIO_FLAGS_APPEND,    O_APPEND },
58  { 0, 0, 0 },
59};
60
61unsigned int rtems_libio_fcntl_flags( int fcntl_flags )
62{
63  unsigned int   flags = 0;
64  uint32_t   access_modes;
65
66  /*
67   * Access mode is a small integer
68   */
69
70  access_modes = (unsigned int) (fcntl_flags & O_ACCMODE);
71  fcntl_flags &= ~O_ACCMODE;
72  flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
73
74  /*
75   * Everything else is single bits
76   */
77
78  flags |= (unsigned int ) rtems_assoc_local_by_remote_bitfield(
79    status_flags_assoc,
80    (uint32_t) fcntl_flags
81  );
82
83  return flags;
84}
85
86int rtems_libio_to_fcntl_flags( unsigned int flags )
87{
88  int fcntl_flags = 0;
89
90  if ( (flags & LIBIO_FLAGS_READ_WRITE) == LIBIO_FLAGS_READ_WRITE ) {
91    fcntl_flags |= O_RDWR;
92  } else if ( (flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) {
93    fcntl_flags |= O_RDONLY;
94  } else if ( (flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) {
95    fcntl_flags |= O_WRONLY;
96  }
97
98  if ( (flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY ) {
99    fcntl_flags |= O_NONBLOCK;
100  }
101
102  if ( (flags & LIBIO_FLAGS_APPEND) == LIBIO_FLAGS_APPEND ) {
103    fcntl_flags |= O_APPEND;
104  }
105
106  return fcntl_flags;
107}
108
109rtems_libio_t *rtems_libio_allocate( void )
110{
111  rtems_libio_t *iop = NULL;
112
113  rtems_libio_lock();
114
115  if (rtems_libio_iop_freelist) {
116    iop = rtems_libio_iop_freelist;
117    rtems_libio_iop_freelist = iop->data1;
118    memset( iop, 0, sizeof(*iop) );
119  }
120
121  rtems_libio_unlock();
122
123  return iop;
124}
125
126void rtems_libio_free(
127  rtems_libio_t *iop
128)
129{
130  rtems_filesystem_location_free( &iop->pathinfo );
131
132  rtems_libio_lock();
133
134    iop->flags = 0;
135    iop->data1 = rtems_libio_iop_freelist;
136    rtems_libio_iop_freelist = iop;
137
138  rtems_libio_unlock();
139}
Note: See TracBrowser for help on using the repository browser.