source: rtems/cpukit/libcsupport/src/fcntl.c @ 856ede4f

5
Last change on this file since 856ede4f was 856ede4f, checked in by Sebastian Huber <sebastian.huber@…>, on 09/13/17 at 08:11:46

libio: Add iop set/clear flags

Update #3132.

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