.. _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; }