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

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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