As far as I know, ioctl() used to expose the "advanced" system call interface for user space applications. Instead of adding thousands of system calls that are unique to specific drivers, ioctl() used to provide extensible driver-related functions with a single system call.
This seems clear enough. However, I'm trying to compile my first application that uses the ioctl() call, and I'm starting to doubt my understanding.
In particular, I want to make an ioctl() call to "sanitize" an eMMC device. Having looked at /usr/include/linux/mmc/ioctl.h (or in the kernel source code in include/uapi/linux/mmc/ioctl.h ), I see this structure:
struct mmc_ioc_cmd {
From user space, I have no problem including this header and passing this structure to my ioctl() calls.
So this is what my last piece of sanitation looks like:
int sanitize(int fd) { struct mmc_ioc_cmd command; memset(&command, 0, sizeof(command)); command.write_flag = 1; command.opcode = MMC_SWITCH; command.arg = EXT_CSD_SANITIZE_START << 16; return ioctl(fd, MMC_IOC_CMD, &command); }
My problem is that MMC_SWITCH and EXT_CSD_SANITIZE_START defined in the kernel headers. In particular, in my kernel source code they are in include/linux/mmc/mmc.h
Everything I saw on the Internet does not tell the kernel source headers when creating user space projects. If so, how can you reasonably use MMC ioctl() ? The kernel provides a structure to go into ioctl() , but it looks like you can use this structure by filling it with "hidden" constants hidden in the kernel source.
My current solution is to copy the necessary constants from the kernel headers to my own project, but it seems dirty to me.
Have I misunderstood the use case for ioctl() ? Is it design supervision?