diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-09-13 09:22:19 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-09-15 10:29:34 +0200 |
commit | baef823cd550449bfbcc36625b9571389d8ad1af (patch) | |
tree | 238c1952d23dc09d41ae99d186d0656f78ed857b /cpukit/libcsupport/src | |
parent | libio: Unify readv() and writev() (diff) | |
download | rtems-baef823cd550449bfbcc36625b9571389d8ad1af.tar.bz2 |
libio: Add hold/drop iop reference
Check iop reference count in close() and return -1 with errno set to
EBUSY in case the file descriptor is still in use.
Update #3132.
Diffstat (limited to 'cpukit/libcsupport/src')
-rw-r--r-- | cpukit/libcsupport/src/close.c | 41 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fchdir.c | 1 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fchmod.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fchown.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fcntl.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fdatasync.c | 5 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fpathconf.c | 4 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fstat.c | 5 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fsync.c | 5 | ||||
-rw-r--r-- | cpukit/libcsupport/src/ftruncate.c | 1 | ||||
-rw-r--r-- | cpukit/libcsupport/src/ioctl.c | 1 | ||||
-rw-r--r-- | cpukit/libcsupport/src/libio.c | 10 | ||||
-rw-r--r-- | cpukit/libcsupport/src/lseek.c | 5 | ||||
-rw-r--r-- | cpukit/libcsupport/src/open.c | 6 | ||||
-rw-r--r-- | cpukit/libcsupport/src/read.c | 5 | ||||
-rw-r--r-- | cpukit/libcsupport/src/write.c | 5 |
16 files changed, 83 insertions, 17 deletions
diff --git a/cpukit/libcsupport/src/close.c b/cpukit/libcsupport/src/close.c index 7eaeb64fea..d478e231c6 100644 --- a/cpukit/libcsupport/src/close.c +++ b/cpukit/libcsupport/src/close.c @@ -24,12 +24,45 @@ int close( int fd ) { - rtems_libio_t *iop; - int rc; + rtems_libio_t *iop; + unsigned int flags; + int rc; - LIBIO_GET_IOP( fd, iop ); + if ( (uint32_t) fd >= rtems_libio_number_iops ) { + rtems_set_errno_and_return_minus_one( EBADF ); + } - rtems_libio_iop_flags_clear( iop, LIBIO_FLAGS_OPEN ); + iop = rtems_libio_iop( fd ); + flags = rtems_libio_iop_flags( iop ); + + while ( true ) { + unsigned int desired; + bool success; + + if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) { + rtems_set_errno_and_return_minus_one( EBADF ); + } + + /* The expected flags */ + flags &= LIBIO_FLAGS_REFERENCE_INC - 1U; + + desired = flags & ~LIBIO_FLAGS_OPEN; + success = _Atomic_Compare_exchange_uint( + &iop->flags, + &flags, + desired, + ATOMIC_ORDER_ACQ_REL, + ATOMIC_ORDER_RELAXED + ); + + if ( success ) { + break; + } + + if ( ( flags & ~( LIBIO_FLAGS_REFERENCE_INC - 1U ) ) != 0 ) { + rtems_set_errno_and_return_minus_one( EBUSY ); + } + } rc = (*iop->pathinfo.handlers->close_h)( iop ); diff --git a/cpukit/libcsupport/src/fchdir.c b/cpukit/libcsupport/src/fchdir.c index ece73ab3ec..df37458ead 100644 --- a/cpukit/libcsupport/src/fchdir.c +++ b/cpukit/libcsupport/src/fchdir.c @@ -59,6 +59,7 @@ int fchdir( int fd ) } } rtems_filesystem_instance_unlock( &iop->pathinfo ); + rtems_libio_iop_drop( iop ); if ( rv == 0 ) { rv = rtems_filesystem_chdir( &loc ); diff --git a/cpukit/libcsupport/src/fchmod.c b/cpukit/libcsupport/src/fchmod.c index 126b015501..13e7fdd380 100644 --- a/cpukit/libcsupport/src/fchmod.c +++ b/cpukit/libcsupport/src/fchmod.c @@ -75,5 +75,7 @@ int fchmod( int fd, mode_t mode ) rtems_filesystem_instance_unlock( &iop->pathinfo ); + rtems_libio_iop_drop( iop ); + return rv; } diff --git a/cpukit/libcsupport/src/fchown.c b/cpukit/libcsupport/src/fchown.c index bd787d89e3..8c3d9b2c6c 100644 --- a/cpukit/libcsupport/src/fchown.c +++ b/cpukit/libcsupport/src/fchown.c @@ -72,5 +72,7 @@ int fchown( int fd, uid_t owner, gid_t group ) rtems_filesystem_instance_unlock( &iop->pathinfo ); + rtems_libio_iop_drop( iop ); + return rv; } diff --git a/cpukit/libcsupport/src/fcntl.c b/cpukit/libcsupport/src/fcntl.c index a7fcfbc041..ddbf5538f9 100644 --- a/cpukit/libcsupport/src/fcntl.c +++ b/cpukit/libcsupport/src/fcntl.c @@ -213,6 +213,8 @@ static int vfcntl( ret = -1; } } + + rtems_libio_iop_drop( iop ); return ret; } diff --git a/cpukit/libcsupport/src/fdatasync.c b/cpukit/libcsupport/src/fdatasync.c index 14e66726e6..bf90957f0f 100644 --- a/cpukit/libcsupport/src/fdatasync.c +++ b/cpukit/libcsupport/src/fdatasync.c @@ -28,6 +28,7 @@ int fdatasync( ) { rtems_libio_t *iop; + int rv; LIBIO_GET_IOP_WITH_ACCESS( fd, iop, LIBIO_FLAGS_WRITE, EBADF ); @@ -35,5 +36,7 @@ int fdatasync( * Now process the fdatasync(). */ - return (*iop->pathinfo.handlers->fdatasync_h)( iop ); + rv = (*iop->pathinfo.handlers->fdatasync_h)( iop ); + rtems_libio_iop_drop( iop ); + return rv; } diff --git a/cpukit/libcsupport/src/fpathconf.c b/cpukit/libcsupport/src/fpathconf.c index db323136c7..d08ac9c776 100644 --- a/cpukit/libcsupport/src/fpathconf.c +++ b/cpukit/libcsupport/src/fpathconf.c @@ -82,9 +82,11 @@ long fpathconf( return_value = the_limits->posix_sync_io; break; default: - rtems_set_errno_and_return_minus_one( EINVAL ); + errno = EINVAL; + return_value = -1; break; } + rtems_libio_iop_drop( iop ); return return_value; } diff --git a/cpukit/libcsupport/src/fstat.c b/cpukit/libcsupport/src/fstat.c index 4a10d166bd..3a1241a862 100644 --- a/cpukit/libcsupport/src/fstat.c +++ b/cpukit/libcsupport/src/fstat.c @@ -26,6 +26,7 @@ int fstat( ) { rtems_libio_t *iop; + int rv; /* * Check to see if we were passed a valid pointer. @@ -44,7 +45,9 @@ int fstat( */ memset( sbuf, 0, sizeof(struct stat) ); - return (*iop->pathinfo.handlers->fstat_h)( &iop->pathinfo, sbuf ); + rv = (*iop->pathinfo.handlers->fstat_h)( &iop->pathinfo, sbuf ); + rtems_libio_iop_drop( iop ); + return rv; } /* diff --git a/cpukit/libcsupport/src/fsync.c b/cpukit/libcsupport/src/fsync.c index 6332180721..428f82abd0 100644 --- a/cpukit/libcsupport/src/fsync.c +++ b/cpukit/libcsupport/src/fsync.c @@ -31,6 +31,7 @@ int fsync( ) { rtems_libio_t *iop; + int rv; LIBIO_GET_IOP( fd, iop ); @@ -38,5 +39,7 @@ int fsync( * Now process the fsync(). */ - return (*iop->pathinfo.handlers->fsync_h)( iop ); + rv = (*iop->pathinfo.handlers->fsync_h)( iop ); + rtems_libio_iop_drop( iop ); + return rv; } diff --git a/cpukit/libcsupport/src/ftruncate.c b/cpukit/libcsupport/src/ftruncate.c index 401510b2ff..99a9c6b5ef 100644 --- a/cpukit/libcsupport/src/ftruncate.c +++ b/cpukit/libcsupport/src/ftruncate.c @@ -32,6 +32,7 @@ int ftruncate( int fd, off_t length ) LIBIO_GET_IOP_WITH_ACCESS( fd, iop, LIBIO_FLAGS_WRITE, EINVAL ); rv = (*iop->pathinfo.handlers->ftruncate_h)( iop, length ); + rtems_libio_iop_drop( iop ); } else { errno = EINVAL; rv = -1; diff --git a/cpukit/libcsupport/src/ioctl.c b/cpukit/libcsupport/src/ioctl.c index 9fa7fa15a2..b2be524075 100644 --- a/cpukit/libcsupport/src/ioctl.c +++ b/cpukit/libcsupport/src/ioctl.c @@ -51,5 +51,6 @@ int ioctl( rc = (*iop->pathinfo.handlers->ioctl_h)( iop, command, buffer ); va_end( ap ); + rtems_libio_iop_drop( iop ); return rc; } diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c index 0cc2b98c0b..26fa7b2f67 100644 --- a/cpukit/libcsupport/src/libio.c +++ b/cpukit/libcsupport/src/libio.c @@ -58,16 +58,16 @@ static const rtems_assoc_t status_flags_assoc[] = { { 0, 0, 0 }, }; -uint32_t rtems_libio_fcntl_flags( int fcntl_flags ) +unsigned int rtems_libio_fcntl_flags( int fcntl_flags ) { - uint32_t flags = 0; + unsigned int flags = 0; uint32_t access_modes; /* * Access mode is a small integer */ - access_modes = (uint32_t) (fcntl_flags & O_ACCMODE); + access_modes = (unsigned int) (fcntl_flags & O_ACCMODE); fcntl_flags &= ~O_ACCMODE; flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes ); @@ -75,7 +75,7 @@ uint32_t rtems_libio_fcntl_flags( int fcntl_flags ) * Everything else is single bits */ - flags |= rtems_assoc_local_by_remote_bitfield( + flags |= (unsigned int ) rtems_assoc_local_by_remote_bitfield( status_flags_assoc, (uint32_t) fcntl_flags ); @@ -83,7 +83,7 @@ uint32_t rtems_libio_fcntl_flags( int fcntl_flags ) return flags; } -int rtems_libio_to_fcntl_flags( uint32_t flags ) +int rtems_libio_to_fcntl_flags( unsigned int flags ) { int fcntl_flags = 0; diff --git a/cpukit/libcsupport/src/lseek.c b/cpukit/libcsupport/src/lseek.c index 16271eba09..00307e3e0d 100644 --- a/cpukit/libcsupport/src/lseek.c +++ b/cpukit/libcsupport/src/lseek.c @@ -20,10 +20,13 @@ off_t lseek( int fd, off_t offset, int whence ) { rtems_libio_t *iop; + off_t rv; LIBIO_GET_IOP( fd, iop ); - return (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence ); + rv = (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence ); + rtems_libio_iop_drop( iop ); + return rv; } /* diff --git a/cpukit/libcsupport/src/open.c b/cpukit/libcsupport/src/open.c index 22773454ba..8558e207d3 100644 --- a/cpukit/libcsupport/src/open.c +++ b/cpukit/libcsupport/src/open.c @@ -99,7 +99,11 @@ static int do_open( rtems_filesystem_eval_path_extract_currentloc( &ctx, &iop->pathinfo ); rtems_filesystem_eval_path_cleanup( &ctx ); - iop->flags = rtems_libio_fcntl_flags( oflag ); + _Atomic_Store_uint( + &iop->flags, + rtems_libio_fcntl_flags( oflag ), + ATOMIC_ORDER_RELAXED + ); rv = (*iop->pathinfo.handlers->open_h)( iop, path, oflag, mode ); diff --git a/cpukit/libcsupport/src/read.c b/cpukit/libcsupport/src/read.c index d55ff180ae..03c39120bb 100644 --- a/cpukit/libcsupport/src/read.c +++ b/cpukit/libcsupport/src/read.c @@ -31,6 +31,7 @@ ssize_t read( ) { rtems_libio_t *iop; + ssize_t n; rtems_libio_check_buffer( buffer ); rtems_libio_check_count( count ); @@ -40,7 +41,9 @@ ssize_t read( /* * Now process the read(). */ - return (*iop->pathinfo.handlers->read_h)( iop, buffer, count ); + n = (*iop->pathinfo.handlers->read_h)( iop, buffer, count ); + rtems_libio_iop_drop( iop ); + return n; } #if defined(RTEMS_NEWLIB) && !defined(HAVE__READ_R) diff --git a/cpukit/libcsupport/src/write.c b/cpukit/libcsupport/src/write.c index f44962afd8..a90b291ed8 100644 --- a/cpukit/libcsupport/src/write.c +++ b/cpukit/libcsupport/src/write.c @@ -34,6 +34,7 @@ ssize_t write( ) { rtems_libio_t *iop; + ssize_t n; rtems_libio_check_buffer( buffer ); rtems_libio_check_count( count ); @@ -43,5 +44,7 @@ ssize_t write( /* * Now process the write() request. */ - return (*iop->pathinfo.handlers->write_h)( iop, buffer, count ); + n = (*iop->pathinfo.handlers->write_h)( iop, buffer, count ); + rtems_libio_iop_drop( iop ); + return n; } |