System Administration
Showing results for 
Search instead for 
Did you mean: 

Can any one explain the exact difference between a system call and an ioctl call ?


Can any one explain the exact difference between a system call and an ioctl call ?

As per sub.

-Masthan D
Honored Contributor

Re: Can any one explain the exact difference between a system call and an ioctl call ?

All ioctl calls are ultimately system calls, but not all system calls are ioctl calls.

According to "man 2 ioctl" on Linux, the ioctl() function originally appeared in Version 7 AT&T Unix. It was -and is- used as a catch-all for operations that don't cleanly fit the Unix stream I/O model. In other words, it's a fairly deep-rooted part of Unix legacy.

The set of system calls is the fundamental interface between an application and the operating system kernel. The C library offers wrappers for most system calls to give them human-readable names, which follow the standards and conventions of the Unix world.

Ultimately, though, the system call API uses system call numbers: if you wish to use in your application a feature that's so new your C library does not have a wrapper function for it, you must know the appropriate syscall number and use either a syscall(2) function or a _syscall macro to access it. This should be a very rare situation when developing normal applications. It produces non-portable code, which must be re-implemented if your application is ever ported to another unix-like OS.

The syscall numbers are *not at all* guaranteed to be portable from one unix-like OS to another. This is one of the reasons why the syscall numbers are generally not used directly if it can be avoided.

However, you can reasonably expect that an unix-like operating system has an ioctl() syscall (among others), and it can be used to target block and character device special files (which are usually located in the /dev directory). The second argument of the ioctl() syscall is a request code, which is specific to the type of device you're targetting and tells what you really want to do.

There is no single standard that defines a complete "minimum" set of things you can do with an ioctl call, but some kinds of ioctls are more widely supported than others. For example, the set of terminal control ioctls are fairly consistent across different unix-like operating systems, but Linux's CDROM device ioctls are most likely specific to Linux only.

From the kernel viewpoint, when an application issues a regular syscall, the kernel checks the syscall number and then knows what the application wants done.
But if it's an ioctl() syscall, the kernel must pass it to the targeted device driver, which will have to check the ioctl request code (another number). So you can say that while a normal syscall has one level of indirection, the ioctl call has two (or more, depending on driver architecture of the OS).

It would be technically possible to remove the ioctl interface and implement all its functionality using regular syscalls. This would be a big loss of compatibility, as a lot of software expects to do certain things using an ioctl() call.

The advantage of the ioctl interface is that it allows new device drivers to be added without making any changes to the interface between the kernel and the C library. The ioctl interface encapsulates the driver-specific features.

When a new driver is added to the system, the application programmers can access its special functions if they have the information about its ioctl request codes available: there is no need to add new wrappers to the system's default C library, which can be allowed to stabilize and become standardized.

Did this answer your question?