File indexing completed on 2025-05-11 08:24:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040
0041 #include <stdarg.h>
0042 #include <unistd.h>
0043 #include <fcntl.h>
0044
0045 #include <rtems/libio_.h>
0046
0047 static int duplicate_iop( rtems_libio_t *iop )
0048 {
0049 int rv;
0050 int oflag;
0051 rtems_libio_t *diop;
0052
0053 oflag = rtems_libio_to_fcntl_flags( rtems_libio_iop_flags( iop ) );
0054 diop = rtems_libio_allocate();
0055
0056 if (diop != NULL) {
0057 rtems_filesystem_instance_lock( &iop->pathinfo );
0058 rtems_filesystem_location_clone( &diop->pathinfo, &iop->pathinfo );
0059 rtems_filesystem_instance_unlock( &iop->pathinfo );
0060
0061 rtems_libio_iop_flags_set( diop, rtems_libio_fcntl_flags( oflag ) );
0062
0063
0064
0065
0066
0067 rv = (*diop->pathinfo.handlers->open_h)( diop, NULL, oflag, 0 );
0068 if ( rv == 0 ) {
0069 rtems_libio_iop_flags_set( diop, LIBIO_FLAGS_OPEN );
0070 rv = rtems_libio_iop_to_descriptor( diop );
0071 } else {
0072 rtems_libio_free( diop );
0073 }
0074 } else {
0075 rv = -1;
0076 }
0077
0078 return rv;
0079 }
0080
0081 static int duplicate2_iop( rtems_libio_t *iop, int fd2 )
0082 {
0083 rtems_libio_t *iop2;
0084 int rv = 0;
0085
0086 if ( (uint32_t) fd2 >= rtems_libio_number_iops ) {
0087 rtems_set_errno_and_return_minus_one( EBADF );
0088 }
0089
0090 iop2 = rtems_libio_iop( fd2 );
0091
0092 if (iop != iop2)
0093 {
0094 int oflag;
0095
0096 if ((rtems_libio_iop_flags( iop2 ) & LIBIO_FLAGS_OPEN) != 0) {
0097 rv = (*iop2->pathinfo.handlers->close_h)( iop2 );
0098 }
0099
0100 if (rv == 0) {
0101 oflag = rtems_libio_to_fcntl_flags( rtems_libio_iop_flags( iop ) );
0102 rtems_libio_iop_flags_set( iop2, rtems_libio_fcntl_flags( oflag ) );
0103
0104 rtems_filesystem_instance_lock( &iop->pathinfo );
0105 rtems_filesystem_location_clone( &iop2->pathinfo, &iop->pathinfo );
0106 rtems_filesystem_instance_unlock( &iop->pathinfo );
0107
0108
0109
0110
0111
0112
0113
0114 rv = (*iop2->pathinfo.handlers->open_h)( iop2, NULL, oflag, 0 );
0115 if ( rv == 0 ) {
0116 rv = fd2;
0117 }
0118 }
0119 }
0120
0121 return rv;
0122 }
0123
0124 static int vfcntl(
0125 int fd,
0126 int cmd,
0127 va_list ap
0128 )
0129 {
0130 rtems_libio_t *iop;
0131 int fd2;
0132 int flags;
0133 int mask;
0134 int ret = 0;
0135
0136 LIBIO_GET_IOP( fd, iop );
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146 switch ( cmd ) {
0147 case F_DUPFD:
0148 ret = duplicate_iop( iop );
0149 break;
0150
0151 case F_DUP2FD:
0152 fd2 = va_arg( ap, int );
0153 ret = duplicate2_iop( iop, fd2 );
0154 break;
0155
0156 case F_GETFD:
0157 ret = ((rtems_libio_iop_flags(iop) & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
0158 break;
0159
0160 case F_SETFD:
0161
0162
0163
0164
0165
0166
0167
0168
0169 if ( va_arg( ap, int ) )
0170 rtems_libio_iop_flags_set( iop, LIBIO_FLAGS_CLOSE_ON_EXEC );
0171 else
0172 rtems_libio_iop_flags_clear( iop, LIBIO_FLAGS_CLOSE_ON_EXEC );
0173 break;
0174
0175 case F_GETFL:
0176 ret = rtems_libio_to_fcntl_flags( rtems_libio_iop_flags( iop ) );
0177 break;
0178
0179 case F_SETFL:
0180 flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
0181 mask = LIBIO_FLAGS_NO_DELAY | LIBIO_FLAGS_APPEND;
0182
0183
0184
0185
0186
0187 rtems_libio_iop_flags_clear( iop, mask );
0188 rtems_libio_iop_flags_set( iop, flags & mask );
0189 break;
0190
0191 case F_GETLK:
0192 errno = ENOTSUP;
0193 ret = -1;
0194 break;
0195
0196 case F_SETLK:
0197 errno = ENOTSUP;
0198 ret = -1;
0199 break;
0200
0201 case F_SETLKW:
0202 errno = ENOTSUP;
0203 ret = -1;
0204 break;
0205
0206 case F_SETOWN:
0207 errno = ENOTSUP;
0208 ret = -1;
0209 break;
0210
0211 case F_GETOWN:
0212 errno = ENOTSUP;
0213 ret = -1;
0214 break;
0215
0216 default:
0217 errno = EINVAL;
0218 ret = -1;
0219 break;
0220 }
0221
0222
0223
0224
0225
0226
0227 if (ret >= 0) {
0228 int err = (*iop->pathinfo.handlers->fcntl_h)( iop, cmd );
0229 if (err) {
0230 errno = err;
0231 ret = -1;
0232 }
0233 }
0234
0235 rtems_libio_iop_drop( iop );
0236 return ret;
0237 }
0238
0239 int fcntl(
0240 int fd,
0241 int cmd,
0242 ...
0243 )
0244 {
0245 int ret;
0246 va_list ap;
0247 va_start( ap, cmd );
0248 ret = vfcntl(fd,cmd,ap);
0249 va_end(ap);
0250 return ret;
0251 }
0252
0253
0254
0255
0256
0257
0258
0259
0260 #if defined(RTEMS_NEWLIB) && !defined(HAVE_FCNTL_R)
0261
0262 #include <reent.h>
0263
0264 int _fcntl_r(
0265 struct _reent *ptr RTEMS_UNUSED,
0266 int fd,
0267 int cmd,
0268 int arg
0269 )
0270 {
0271 return fcntl( fd, cmd, arg );
0272 }
0273 #endif