[PATCH v1] pxcdevctl: Adjust for standard
Ryan Long
ryan.long at oarcorp.com
Mon Sep 13 17:16:25 UTC 2021
psxdevctl is supposed to return the value in errno. Before, it was
returning -1 and setting errno. Changed the tests to reflect these
changes. Added code from RRADE's posix_devctl.c.
Closes #4506
---
cpukit/libcsupport/src/posix_devctl.c | 80 ++++++++++++++++++++++++++++++----
testsuites/psxtests/psxdevctl01/test.c | 69 +++++++++++++++++++----------
2 files changed, 118 insertions(+), 31 deletions(-)
diff --git a/cpukit/libcsupport/src/posix_devctl.c b/cpukit/libcsupport/src/posix_devctl.c
index 3ff9dd9..fd19074 100644
--- a/cpukit/libcsupport/src/posix_devctl.c
+++ b/cpukit/libcsupport/src/posix_devctl.c
@@ -35,6 +35,7 @@
#include <rtems/seterr.h>
#include <unistd.h>
+#include <fcntl.h>
int posix_devctl(
int fd,
@@ -44,6 +45,15 @@ int posix_devctl(
int *__restrict dev_info_ptr
)
{
+ int rv = 0;
+
+ /*
+ * posix_devctl() is supposed to return an errno. errno needs to be
+ * preserved in spite of calling methods (e.g., close, fcntl, and ioctl)
+ * that set it.
+ */
+ int errno_copy = errno;
+
/*
* The POSIX 1003.26 standard allows for library implementations
* that implement posix_devctl() using ioctl(). In this case,
@@ -72,15 +82,69 @@ int posix_devctl(
}
/*
- * The FACE Technical Standard Edition 3.0 and newer requires the SOCKCLOSE
- * ioctl command. This is because the Security Profile does not include
- * close() and applications need a way to close sockets. Closing sockets is
- * a minimum requirement so using close() in the implementation meets that
- * requirement but also lets the application close other file types.
+ *
*/
- if (dcmd == SOCKCLOSE ) {
- return close(fd);
+ switch (dcmd) {
+
+ /*
+ * The FACE Technical Standard Edition 3.0 and newer requires the SOCKCLOSE
+ * ioctl command. This is because the Security Profile does not include
+ * close() and applications need a way to close sockets. Closing sockets is
+ * a minimum requirement so using close() in the implementation meets that
+ * requirement but also lets the application close other file types.
+ */
+ case SOCKCLOSE:
+ if (close(fd) != 0) {
+ rv = errno;
+ errno = errno_copy;
+
+ return rv;
+ }
+ break;
+
+ /*
+ * The FACE Technical Standard Edition 3.0 and newer requires the
+ * posix_devctl command to support the FIONBIO subcommand.
+ */
+ case FIONBIO: {
+ int tmp_flag;
+ int flag;
+
+ if (nbyte != sizeof(int)) {
+ return EINVAL;
+ }
+
+ tmp_flag = fcntl(fd, F_GETFL, 0);
+ if (tmp_flag == -1) {
+ rv = errno;
+ errno = errno_copy;
+
+ return rv;
+ }
+
+ flag = *(int *)dev_data_ptr;
+
+ if (flag != 0) {
+ tmp_flag |= O_NONBLOCK;
+ } else {
+ tmp_flag &= ~O_NONBLOCK;
+ }
+
+ (void) fcntl(fd, F_SETFL, tmp_flag);
+ break;
+ }
+
+ default:
+ if (ioctl(fd, dcmd, dev_data_ptr) != 0) {
+ rv = errno;
+ errno = errno_copy;
+
+ return rv;
+ }
+ break;
}
- return ioctl(fd, dcmd, dev_data_ptr);
+ errno = errno_copy;
+
+ return rv;
}
diff --git a/testsuites/psxtests/psxdevctl01/test.c b/testsuites/psxtests/psxdevctl01/test.c
index b45725c..2fe7df1 100644
--- a/testsuites/psxtests/psxdevctl01/test.c
+++ b/testsuites/psxtests/psxdevctl01/test.c
@@ -53,37 +53,16 @@ int main(
int dev_data;
void *dev_data_ptr;
size_t nbyte;
- int dev_info;
TEST_BEGIN();
- puts( "posix_devctl() FIONBIO on stdin return dev_info -- EBADF" );
- fd = 0;
- dcmd = FIONBIO;
- dev_data_ptr = &dev_data;
- nbyte = sizeof(dev_data);
- status = posix_devctl( fd, dcmd, dev_data_ptr, nbyte, &dev_info );
- rtems_test_assert( status == -1 );
- rtems_test_assert( errno == EBADF );
- rtems_test_assert( dev_info == 0 );
-
- puts( "posix_devctl() FIONBIO on stdin NULL dev_info -- EBADF" );
- fd = 0;
- dcmd = FIONBIO;
- dev_data_ptr = NULL;
- nbyte = 0;
- status = posix_devctl( fd, dcmd, dev_data_ptr, nbyte, NULL );
- rtems_test_assert( status == -1 );
- rtems_test_assert( errno == EBADF );
-
puts( "posix_devctl() SOCKCLOSE on invalid file descriptor -- EBADF" );
- fd = 21;
+ fd = -1;
dcmd = SOCKCLOSE;
dev_data_ptr = NULL;
nbyte = 0;
status = posix_devctl( fd, dcmd, dev_data_ptr, nbyte, NULL );
- rtems_test_assert( status == -1 );
- rtems_test_assert( errno == EBADF );
+ rtems_test_assert( status == EBADF );
/*
* Create a file, open it, and close it via posix_devctl().
@@ -102,6 +81,50 @@ int main(
status = close( fd );
rtems_test_assert( status == -1 );
rtems_test_assert( errno == EBADF );
+
+ puts( "posix_devctl() FIONBIO with invalid nbyte -- EINVAL" );
+ fd = 0;
+ dcmd = FIONBIO;
+ dev_data_ptr = NULL;
+ nbyte = 0;
+ status = posix_devctl( fd, dcmd, dev_data_ptr, nbyte, NULL );
+ rtems_test_assert( status == EINVAL );
+
+ puts( "posix_devctl() FIONBIO with invalid file descriptor -- EBADF" );
+ fd = -1;
+ dcmd = FIONBIO;
+ dev_data_ptr = NULL;
+ nbyte = sizeof(int);
+ status = posix_devctl( fd, dcmd, dev_data_ptr, nbyte, NULL );
+ rtems_test_assert( status == EBADF );
+
+ puts( "posix_devctl() FIONBIO flag not zero -- 0" );
+ fd = 0;
+ dcmd = FIONBIO;
+ dev_data = 1;
+ dev_data_ptr = &dev_data;
+ nbyte = sizeof(int);
+ status = posix_devctl( fd, dcmd, dev_data_ptr, nbyte, NULL );
+ rtems_test_assert( status == 0 );
+
+ puts( "posix_devctl() FIONBIO flag is zero -- 0" );
+ fd = 0;
+ dcmd = FIONBIO;
+ dev_data = 0;
+ dev_data_ptr = &dev_data;
+ nbyte = sizeof(int);
+ status = posix_devctl( fd, dcmd, dev_data_ptr, nbyte, NULL );
+ rtems_test_assert( status == 0 );
+
+ puts( "posix_devctl() dcmd not valid value -- EBADF" );
+ fd = 0;
+ dcmd = 1;
+ dev_data = 0;
+ dev_data_ptr = &dev_data;
+ nbyte = sizeof(int);
+ status = posix_devctl( fd, dcmd, dev_data_ptr, nbyte, NULL );
+ rtems_test_assert( status == EBADF );
+
TEST_END();
exit(0);
}
--
1.8.3.1
More information about the devel
mailing list