[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