• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * fs/vfs/fs_ioctl.c
3  *
4  *   Copyright (C) 2007-2010, 2012-2014, 2016-2017 Gregory Nutt. All rights
5  *     reserved.
6  *   Author: Gregory Nutt <gnutt@nuttx.org>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  * 3. Neither the name NuttX nor the names of its contributors may be
19  *    used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  ****************************************************************************/
36 
37 /****************************************************************************
38  * Included Files
39  ****************************************************************************/
40 
41 #include "vfs_config.h"
42 #include "sched.h"
43 #include "assert.h"
44 #include "errno.h"
45 #include "unistd.h"
46 #include "console.h"
47 
48 #if defined(LOSCFG_NET_LWIP_SACK)
49 #include "lwip/sockets.h"
50 #endif
51 
52 #include "vnode.h"
53 
54 /****************************************************************************
55  * Public Functions
56  ****************************************************************************/
57 
58 /****************************************************************************
59  * Name: ioctl/fs_ioctl
60  *
61  * Description:
62  *   Perform device specific operations.
63  *
64  * Input Parameters:
65  *   fd       File/socket descriptor of device
66  *   req      The ioctl command
67  *   arg      The argument of the ioctl cmd
68  *
69  * Returned Value:
70  *   >=0 on success (positive non-zero values are cmd-specific)
71  *   -1 on failure with errno set properly:
72  *
73  *   EBADF
74  *     'fd' is not a valid descriptor.
75  *   EFAULT
76  *     'arg' references an inaccessible memory area.
77  *   EINVAL
78  *     'cmd' or 'arg' is not valid.
79  *   ENOTTY
80  *     'fd' is not associated with a character special device.
81  *   ENOTTY
82  *      The specified request does not apply to the kind of object that the
83  *      descriptor 'fd' references.
84  *
85  ****************************************************************************/
86 
87 #ifdef CONFIG_LIBC_IOCTL_VARIADIC
fs_ioctl(int fd,int req,...)88 int fs_ioctl(int fd, int req, ...)
89 #else
90 int ioctl(int fd, int req, ...)
91 #endif
92 {
93   int err;
94   UINTPTR arg = 0;
95   va_list ap;
96 #if CONFIG_NFILE_DESCRIPTORS > 0
97   struct file     *filep;
98   int                  ret = OK;
99 #endif
100 
101   va_start(ap, req);
102   arg = va_arg(ap, UINTPTR);
103   va_end(ap);
104 #if CONFIG_NFILE_DESCRIPTORS > 0
105 
106   /* Did we get a valid file descriptor? */
107 
108   if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
109 #endif
110     {
111       /* Perform the socket ioctl */
112 
113 #if defined(LOSCFG_NET_LWIP_SACK)
114       if ((unsigned int)fd < (unsigned int)(CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
115         {
116           return socks_ioctl(fd, (long)req, (void *)arg);
117         }
118       else
119 #endif
120         {
121           err = EBADF;
122           ret = VFS_ERROR;
123           goto errout;
124         }
125     }
126 
127 #if CONFIG_NFILE_DESCRIPTORS > 0
128 
129   if (fd >= STDIN_FILENO && fd <= STDERR_FILENO) /* fd : [0,2] */
130     {
131       fd = ConsoleUpdateFd();
132       if (fd < 0)
133         {
134           err = EBADF;
135           ret = VFS_ERROR;
136           goto errout;
137         }
138     }
139 
140   /* Get the file structure corresponding to the file descriptor. */
141 
142   ret = fs_getfilep(fd, &filep);
143   if (ret < 0)
144     {
145       /* The errno value has already been set */
146       return VFS_ERROR;
147     }
148 
149   /* Is a driver registered? Does it support the ioctl method? */
150 
151   if (filep->ops && filep->ops->ioctl)
152     {
153       /* Yes, then let it perform the ioctl */
154 
155       ret = (int) filep->ops->ioctl(filep, req, arg);
156       if (ret < 0)
157         {
158           err = -ret;
159           goto errout;
160         }
161     }
162   else
163     {
164       err = ENOSYS;
165       ret = VFS_ERROR;
166       goto errout;
167     }
168 
169   return ret;
170 #endif
171 
172 errout:
173   set_errno(err);
174   return VFS_ERROR;
175 }
176