Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:15

0001 /*
0002  * Copyright (c) 2016, 2020 Joel Sherrill <joel@rtems.org>.
0003  * All rights reserved.
0004  *
0005  * Redistribution and use in source and binary forms, with or without
0006  * modification, are permitted provided that the following conditions
0007  * are met:
0008  * 1. Redistributions of source code must retain the above copyright
0009  *    notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *    notice, this list of conditions and the following disclaimer in the
0012  *    documentation and/or other materials provided with the distribution.
0013  *
0014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0015  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0016  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0017  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0018  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0019  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0020  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0021  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0022  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0023  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0024  * SUCH DAMAGE.
0025  */
0026 
0027 #ifdef HAVE_CONFIG_H
0028 #include "config.h"
0029 #endif
0030 
0031 #define _POSIX_26_C_SOURCE
0032 
0033 #include <devctl.h>
0034 #include <sys/ioctl.h>
0035 #include <rtems/seterr.h>
0036 
0037 #include  <unistd.h>
0038 #include  <fcntl.h>
0039 
0040 int posix_devctl(
0041   int              fd,
0042   int              dcmd,
0043   void *__restrict dev_data_ptr,
0044   size_t           nbyte,
0045   int *__restrict  dev_info_ptr
0046 )
0047 {
0048   int rv = 0;
0049 
0050   /*
0051    * posix_devctl() is supposed to return an errno. errno needs to be
0052    * preserved in spite of calling methods (e.g., close, fcntl, and ioctl)
0053    * that set it.
0054    */
0055   int errno_copy = errno;
0056 
0057   /*
0058    * The POSIX 1003.26 standard allows for library implementations
0059    * that implement posix_devctl() using ioctl(). In this case,
0060    * the extra parameters are largely ignored.
0061    *
0062    * The FACE Technical Standard requires only that FIONBIO
0063    * be supported for sockets.
0064    *
0065    * This method appears to be rarely implemented and there are
0066    * no known required use cases for this method beyond those
0067    * from the FACE Technical Standard.
0068    */
0069 
0070   /*
0071    * POSIX 1003.26 mentions that nbyte must be non-negative but this
0072    * doesn't make sense because size_t is guaranteed to be unsigned.
0073    */
0074 
0075   /*
0076    * Since this is implemented on top of ioctl(), the device information
0077    * is not going to be passed down. Fill it in with zero so the behavior
0078    * is defined.
0079    */
0080   if (dev_info_ptr != NULL) {
0081     *dev_info_ptr = 0;
0082   }
0083 
0084   /*
0085    *
0086    */
0087   switch (dcmd) {
0088 
0089     /*
0090      * The FACE Technical Standard Edition 3.0 and newer requires the SOCKCLOSE
0091      * ioctl command. This is because the Security Profile does not include
0092      * close() and applications need a way to close sockets. Closing sockets is
0093      * a minimum requirement so using close() in the implementation meets that
0094      * requirement but also lets the application close other file types.
0095      */
0096     case SOCKCLOSE:
0097       if (close(fd) != 0) {
0098         rv    = errno;
0099         errno = errno_copy;
0100 
0101         return rv;
0102       }
0103       break;
0104 
0105     /*
0106      * The FACE Technical Standard Edition 3.0 and newer requires the
0107      * posix_devctl command to support the FIONBIO subcommand.
0108      */
0109     case FIONBIO: {
0110       int tmp_flag;
0111       int flag;
0112 
0113       if (nbyte != sizeof(int)) {
0114         return EINVAL;
0115       }
0116 
0117       tmp_flag = fcntl(fd, F_GETFL, 0);
0118       if (tmp_flag == -1) {
0119         rv = errno;
0120         errno = errno_copy;
0121 
0122         return rv;
0123       }
0124 
0125       flag = *(int *)dev_data_ptr;
0126 
0127       if (flag != 0) {
0128         tmp_flag |= O_NONBLOCK;
0129       } else {
0130         tmp_flag &= ~O_NONBLOCK;
0131       }
0132 
0133       (void) fcntl(fd, F_SETFL, tmp_flag);
0134       break;
0135     }
0136 
0137     default:
0138       if (ioctl(fd, dcmd, dev_data_ptr) != 0) {
0139         rv = errno;
0140         errno = errno_copy;
0141 
0142         return rv;
0143       }
0144       break;
0145   }
0146 
0147   errno = errno_copy;
0148 
0149   return rv;
0150 }