From 3951d4da6fc4885dd450e5257d7273ab6a392492 Mon Sep 17 00:00:00 2001 From: Ryan Long Date: Mon, 23 Aug 2021 12:43:23 -0400 Subject: pxcdevctl: Adjust for standard 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 +++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 8 deletions(-) (limited to 'cpukit/libcsupport') diff --git a/cpukit/libcsupport/src/posix_devctl.c b/cpukit/libcsupport/src/posix_devctl.c index 3ff9dd929f..fd190744e9 100644 --- a/cpukit/libcsupport/src/posix_devctl.c +++ b/cpukit/libcsupport/src/posix_devctl.c @@ -35,6 +35,7 @@ #include #include +#include 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; } -- cgit v1.2.3