nuttx/Documentation/implementation/ioctl.rst
Tomasz 'CeDeROM' CEDRO 0cfa6f1b96 doc: Migrating the rest of documentation from cwiki.
* This completes task list in https://github.com/apache/nuttx/issues/11127.
* This preserves selected content from cwiki and moves it to new docs.
* Most pages are simple copy-paste with a simple RST formatting updates,
  with minor updates.
* Content update / reorganization will follow later on when needed.
* Files added (or updated title from cwiki -> current docs):
  * Documentation/implementation:
    * index.
    * cancellation_points.
    * Asynchronous vs. Synchronous Context Switches -> context_switches.rst.
    * ARMv7-M Hardfaults, SVCALL, and Debuggers -> hardfatuls.rst.
    * chip.h FAQ -> chip_h.rst.
    * Debug Output (SYSLOG) Issues -> syslog.rst.
    * Detaching File Descriptors -> file_descriptors.rst.
    * device_nodes.rst.
    * Dynamic Clocking -> power_management.rst.
    * ENOTTY ioctl() Return Value -> ioctl.rst.
    * memory_configurations.rst.
    * kernel_modules_vs_shared_libraries.rst.
    * NAKing USB OUT/IN Tokens -> usb.rst.
    * naming_arch_mcu_board_interfaces.rst.
    * naming_os_internals.rst.
    * nuttx_tasking.rst.
    * oneshot_timers_and_cpu_load.rst.
    * nuttx_initialization_sequence.rst.
    * short_time_delays.rst.
    * Signal Handler Tour -> signal_handlers.rst.
    * smp.rst.
    * syslog.rst.
    * Task Exit Sequence -> nuttx_tasking.rst.
    * tasks_vs_threads.rst.
    * tls.rst.
    * tickless_os.rst.
    * Why Can't Kernel Threads Have pthreads -> kernel_threads_vs_pthreads.rst.
  * Documentation/components/filesystem:
    * smartfs.rst.

Signed-off-by: Tomasz 'CeDeROM' CEDRO <tomek@cedro.info>
2026-05-28 09:34:04 +08:00

137 lines
3.5 KiB
ReStructuredText

.. _ioctl:
=====
ioctl
=====
Not a Typewriter
================
"In computing, **Not a typewriter** or ``ENOTTY`` is an error code defined
in the ``errno.h`` found on many Unix systems.
This code is now used to indicate that
an invalid ``ioctl`` (input/output control) number was specified
in an ``ioctl`` system call."
--Source: https://en.wikipedia.org/wiki/Not_a_typewriter.
NuttX
=====
In ``ioctl()`` implementations in NuttX, ``-ENOTTY`` is always returned
if the ``ioctl()`` command is not recognized. You will often see driver
``ioctl()`` implement ions with a general structure similar to the following:
.. code:: c
int driver_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
int ret;
switch (cmd)
{
...
default:
ret = -ENOTTY;
break;
}
}
return ret;
}
Note that ``-ENOTTY`` is returned internally in NuttX.
This will subsequently be used to set the errno value to ``ENOTTY``
and to ``return -1`` to indicate the error condition.
ERRORS
------
These are the return values from a Linux ``ioctl()`` call:
* ``EBADF`` fd is not a valid file descriptor.
* ``EFAULT`` argp references an inaccessible memory area.
* ``EINVAL`` request or argp is not valid.
* ``ENOTTY`` fd is not associated with a character special device.
* ``ENOTTY`` The specified request does not apply to the kind of object
that the file descriptor fd references.
Reference: https://www.man7.org/linux/man-pages/man2/ioctl.2.html.
Linux Explanation
=================
On Jun 27 Linus Torvalds wrote:
"The correct error code for "I don't understand this ioctl" is ENOTTY.
The naming may be odd, but you should think of that error value as a
"unrecognized ioctl number, you're feeding me random numbers that I
don't understand and I assume for historical reasons that you tried to
do some tty operation on me".
...
The EINVAL thing goes way back, and is a disaster. It predates Linux
itself, as far as I can tell. You'll find lots of man-pages that have
this line in it:
EINVAL Request or argp is not valid.
and it shows up in POSIX etc. And sadly, it generally shows up
_before_ the line that says
ENOTTY The specified request does not apply to the kind of object
that the descriptor d references.
so a lot of people get to the EINVAL, and never even notice the ENOTTY.
(..)
At least glibc (and hopefully other C libraries) use a _string_ that
makes much more sense: strerror(ENOTTY) is "Inappropriate ioctl for
device"."
--Source: https://lore.kernel.org/patchwork/patch/258361.
How is this useful?
Knowing that no error occurred but the ``ioctl()`` command was not recognized
is a useful piece of information.
Suppose, for example, I have nfds open character drivers in an array ``fd[]``.
Then I could do something like this:
.. code:: c
int do_command(FAR int *fd, int nfds, int cmd)
{
int ret;
int i;
/* Try all file descriptors */
for (i = 0; i < nfds; i++)
{
ret = ioctl(fd[i], cmd, 0ul); /* No argument in this example */
if (ret < 0)
{
int errcode = errno;
/* Try the next file descriptor if this one return ENOTTY */
if (errcode != ENOTTY)
{
/* Other errors, including EINVAL, are fatal */
return -errcode
}
}
else if (ret >= 0)
{
return OK; /* Success! */
}
}
return -ENOENT;
}