C Programming

C: IOCTL Function Usage

The simple files of a Linux-based system can easily be read or written using simple input and output operations. However, there are some other complex types of files too that cannot be accessed with the help of simple input and output functions. We use the “IOCTL” function of the C programming language for all such files. It stands for “Input/ Output Control.”

In this article, we will try to understand the purpose of the “IOCTL” function of the C programming language in-depth by looking at its syntax. Then, we will talk a little about the file type for which this function is used, and we will also share with you the location where such files usually reside. Then, we will demonstrate an example that uses the “IOCTL” function of the C programming language. Finally, we will discuss some errors associated with this particular function.

The Purpose of the IOCTL Function in C:

Apart from the regular files of a system, there are some special purpose files, such as the device files. The device files are the ones that are used to interact with the different device drivers of a system. However, you cannot access these device files with the help of regular system calls. This is where the “IOCTL” function comes into play. This function helps in accessing these files very conveniently. The “IOCTL” function of the C programming language resides inside the “ioctl.h” header file.

The general syntax of this function is appended below:

#define “Name of IOCTL” _IO(num1, num2, argument type)

Here, “Name of IOCTL” can be replaced by any meaningful name that you want for your particular function. Then, “_IO” can be left as it is for an “IOCTL” function with no parameters; however, you can also replace it with “_IOW,” “_IOR,” and “_IOWR” for an “IOCTL” function having writing, reading, and writing and reading both capabilities. “num1” refers to the unique number assigned to our “IOCTL” call, “num2” represents the unique number assigned to the “IOCTL” function, whereas the “argument type” refers to the data that this particular “IOCTL” function is capable of dealing with.

Where do the Device Files Reside on a Linux System?

The device files usually reside within a Linux-based system’s “/dev” directory. Therefore, for accessing all such files with the help of the “IOCTL” function, you must navigate to the “/dev” directory of your system.

Usage of the IOCTL Function in C:

To explain to you in detail the usage of the IOCTL function in the C programming language, we have made use of a simple C program shown in the images below. We intend to open a specific device file from our system and write a random value to it in this program. After doing this, we also want to read a value from the very same file. You need to look at the code for this example to understand it more clearly.

First, we have included a long list of libraries or header files whose functions will be used in this C program. Then, we have defined the “read” and “write” functions by using the “define” keyword for reading and writing the device files of our system. After that, within our “main()” function, we have defined an integer variable named “fileDescriptor.” This file descriptor will be used to check whether our device file has been opened effectively or not. Then, we have defined two other variables of int32_t type named “val” and “num.” These variables will take input from the user at the runtime and display the corresponding output.

After that, we have printed a message to convey that our program is attempting to open the device file. Then, using the “open” function, we have attempted to open the desired device file by providing its correct path, i.e., the “/dev” directory followed by the name of the desired device file. After that, we wanted to check whether the file was opened successfully or not. For doing that, we need to validate the value of the “fileDescriptor” variable. Suppose this value will be less than “0”. In that case, an error message will be printed on the terminal indicating that the specified device file could not be opened due to some error, and the program will terminate immediately.

Otherwise, if the device file is opened successfully, a message will be printed on the terminal asking the user to enter the value he wants to write to the specified device file. Then, the given user input will be saved in the “num” variable. After that, a message will be printed on the terminal to convey that the passed number has been written to the specified device file, followed by the “IOCTL” function that will perform this action. Then, we want to read the value from the same file for which we have printed a message on the terminal and then again use the “IOCTL” function to read the value from that file into the “val” variable.

After that, we have printed the value of the “val” variable on the terminal, which is the value read from the specified device file. Then, we published a message on the terminal to convey closing the device file. This message is followed by the “close” function used to modify the value of the “fileDescriptor” variable so that the device file under discussion can be safely closed. Finally, we have used the “return 0” statement as the last statement of our C program.

Now, it is time to compile this C program to see any errors. For that, we have used the affixed command:

$ gcc ioctl.c –o ioctl

For running this compiled C code, we have used the command shown below:

$ ./ioctl

Once we executed this C script, we were asked to enter the value we wanted to send to the device file. We have entered the number “3” as shown in the following image:

As soon as we provided this value at the terminal, it was immediately written onto our device file. A new value was read from that file and displayed on the terminal, as shown in the image below. You can also look at the successive messages printed on the terminal as the output of this C program.

Common Errors Allied with the IOCTL Function in C:

The three most common errors associated with the “IOCTL” function are as follows:

  • EBADF: The file descriptor is invalid.
  • EFAULT: Denied access to invalid memory.
  • EINVAL: Request is invalid.

Conclusion:

This article revolved around discussing the “IOCTL” function of the C programming language. We stated the detailed purpose of this function and the file type that this function generally deals with. Then, we shared a thorough example to demonstrate the usage of this function, followed by some errors associated with this function. Hopefully, after going through this guide, you will understand the working of the “IOCTL” function of the C programming language well.

About the author

Aqsa Yasin

I am a self-motivated information technology professional with a passion for writing. I am a technical writer and love to write for all Linux flavors and Windows.