source: rtems/cpukit/libcsupport/src/fcntl.c @ 9012db8

5
Last change on this file since 9012db8 was 9012db8, checked in by Sebastian Huber <sebastian.huber@…>, on 09/13/17 at 09:33:25

libio: LIBIO_GET_IOP() LIBIO_GET_IOP_WITH_ACCESS()

Replace rtems_libio_check_fd(), rtems_libio_iop(),
rtems_libio_check_open() and rtems_libio_check_permissions()
combinations with new LIBIO_GET_IOP() and LIBIO_GET_IOP_WITH_ACCESS()
macros.

Update #3132.

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/**
2 * @file
3 *
4 * @brief POSIX 1003.1b 6.5.2 - File Control
5 * @ingroup libcsupport
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 <stdarg.h>
22#include <unistd.h>
23#include <fcntl.h>
24
25#include <rtems/libio_.h>
26
27static int duplicate_iop( rtems_libio_t *iop )
28{
29  int            rv;
30  int            oflag;
31  rtems_libio_t *diop;
32
33  oflag = rtems_libio_to_fcntl_flags( rtems_libio_iop_flags( iop ) );
34  diop = rtems_libio_allocate();
35
36  if (diop != NULL) {
37    rtems_filesystem_instance_lock( &iop->pathinfo );
38    rtems_filesystem_location_clone( &diop->pathinfo, &iop->pathinfo );
39    rtems_filesystem_instance_unlock( &iop->pathinfo );
40
41    /*
42     * XXX: We call the open handler here to have a proper open and close pair.
43     *
44     * FIXME: What to do with the path?
45     */
46    rv = (*diop->pathinfo.handlers->open_h)( diop, NULL, oflag, 0 );
47    if ( rv == 0 ) {
48      rtems_libio_iop_flags_initialize(
49        diop,
50        rtems_libio_fcntl_flags( oflag )
51      );
52      rv = rtems_libio_iop_to_descriptor( diop );
53    } else {
54      rtems_libio_free( diop );
55    }
56  } else {
57    rv = -1;
58  }
59
60  return rv;
61}
62
63static int duplicate2_iop( rtems_libio_t *iop, int fd2 )
64{
65  rtems_libio_t *iop2;
66  int            rv = 0;
67
68  if ( (uint32_t) fd2 >= rtems_libio_number_iops ) {
69    rtems_set_errno_and_return_minus_one( EBADF );
70  }
71
72  iop2 = rtems_libio_iop( fd2 );
73
74  if (iop != iop2)
75  {
76    int oflag;
77
78    if ((rtems_libio_iop_flags( iop2 ) & LIBIO_FLAGS_OPEN) != 0) {
79      rv = (*iop2->pathinfo.handlers->close_h)( iop2 );
80    }
81
82    if (rv == 0) {
83      oflag = rtems_libio_to_fcntl_flags( rtems_libio_iop_flags( iop ) );
84      rtems_libio_iop_flags_set( iop2, rtems_libio_fcntl_flags( oflag ) );
85
86      rtems_filesystem_instance_lock( &iop->pathinfo );
87      rtems_filesystem_location_clone( &iop2->pathinfo, &iop->pathinfo );
88      rtems_filesystem_instance_unlock( &iop->pathinfo );
89
90      /*
91       * XXX: We call the open handler here to have a proper open and close
92       *      pair.
93       *
94       * FIXME: What to do with the path?
95       */
96      rv = (*iop2->pathinfo.handlers->open_h)( iop2, NULL, oflag, 0 );
97      if ( rv == 0 ) {
98        rv = fd2;
99      }
100    }
101  }
102
103  return rv;
104}
105
106static int vfcntl(
107  int fd,
108  int cmd,
109  va_list ap
110)
111{
112  rtems_libio_t *iop;
113  int            fd2;
114  int            flags;
115  int            mask;
116  int            ret = 0;
117
118  LIBIO_GET_IOP( fd, iop );
119
120  /*
121   *  Now process the fcntl().
122   */
123
124  /*
125   *  This switch should contain all the cases from POSIX.
126   */
127
128  switch ( cmd ) {
129    case F_DUPFD:        /* dup */
130      ret = duplicate_iop( iop );
131      break;
132
133    case F_DUP2FD:       /* dup2 */
134      fd2 = va_arg( ap, int );
135      ret = duplicate2_iop( iop, fd2 );
136      break;
137
138    case F_GETFD:        /* get f_flags */
139      ret = ((rtems_libio_iop_flags(iop) & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
140      break;
141
142    case F_SETFD:        /* set f_flags */
143      /*
144       *  Interpret the third argument as the "close on exec()" flag.
145       *  If this argument is 1, then the file descriptor is to be closed
146       *  if a new process is exec()'ed.  Since RTEMS does not support
147       *  processes, then we can ignore this one except to make
148       *  F_GETFD work.
149       */
150
151      if ( va_arg( ap, int ) )
152        rtems_libio_iop_flags_set( iop, LIBIO_FLAGS_CLOSE_ON_EXEC );
153      else
154        rtems_libio_iop_flags_clear( iop, LIBIO_FLAGS_CLOSE_ON_EXEC );
155      break;
156
157    case F_GETFL:        /* more flags (cloexec) */
158      ret = rtems_libio_to_fcntl_flags( rtems_libio_iop_flags( iop ) );
159      break;
160
161    case F_SETFL:
162      flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
163      mask = LIBIO_FLAGS_NO_DELAY | LIBIO_FLAGS_APPEND;
164
165      /*
166       *  XXX If we are turning on append, should we seek to the end?
167       */
168
169      rtems_libio_iop_flags_clear( iop, mask );
170      rtems_libio_iop_flags_set( iop, flags & mask );
171      break;
172
173    case F_GETLK:
174      errno = ENOTSUP;
175      ret = -1;
176      break;
177
178    case F_SETLK:
179      errno = ENOTSUP;
180      ret = -1;
181      break;
182
183    case F_SETLKW:
184      errno = ENOTSUP;
185      ret = -1;
186      break;
187
188    case F_SETOWN:       /*  for sockets. */
189      errno = ENOTSUP;
190      ret = -1;
191      break;
192
193    case F_GETOWN:       /*  for sockets. */
194      errno = ENOTSUP;
195      ret = -1;
196      break;
197
198    default:
199      errno = EINVAL;
200      ret = -1;
201      break;
202  }
203
204  /*
205   *  If we got this far successfully, then we give the optional
206   *  filesystem specific handler a chance to process this.
207   */
208
209  if (ret >= 0) {
210    int err = (*iop->pathinfo.handlers->fcntl_h)( iop, cmd );
211    if (err) {
212      errno = err;
213      ret = -1;
214    }
215  }
216  return ret;
217}
218
219int fcntl(
220  int fd,
221  int cmd,
222  ...
223)
224{
225  int            ret;
226  va_list        ap;
227  va_start( ap, cmd );
228  ret = vfcntl(fd,cmd,ap);
229  va_end(ap);
230  return ret;
231}
232
233
234/*
235 *  _fcntl_r
236 *
237 *  This is the Newlib dependent reentrant version of fcntl().
238 */
239
240#if defined(RTEMS_NEWLIB) && !defined(HAVE_FCNTL_R)
241
242#include <reent.h>
243
244int _fcntl_r(
245  struct _reent *ptr RTEMS_UNUSED,
246  int fd,
247  int cmd,
248  int arg
249)
250{
251  return fcntl( fd, cmd, arg );
252}
253#endif
Note: See TracBrowser for help on using the repository browser.