source: rtems/cpukit/libcsupport/src/fcntl.c @ e2b1db23

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

libio: Add rtems_libio_iop_flags()

Update #3132.

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