Embedded Linux: fcntl() and ioctl() Functions

Embedded Linux: fcntl() and ioctl() Functions

Click the blue text above to follow us

fcntl() and ioctl() are two system calls used to control file descriptors, each serving different purposes and functionalities in various situations.

1

fcntl() Function

The fcntl() function provides the capability to perform various control operations on an open file descriptor, such as duplicating a file descriptor (similar to dup, dup2), getting/setting file descriptor flags, and getting/setting file status flags. It is a multifunctional tool for managing file descriptors. You can view the prototype of the fcntl() function by using the command “man 2 fcntl”.

#include
int fcntl(int fd, int cmd, ... /* arg */);

The parameters and return values of the fcntl() function are as follows:

  • fd: File descriptor.

  • cmd: Operation command. This specifies the type of operation to be performed on the file descriptor fd. These commands typically start with F_XXX, such as F_DUPFD, F_GETFD, F_SETFD, etc. The specific functions of these commands can be understood by consulting the manual page (man 2 fcntl). Common functionalities include:

    • Duplicating a file descriptor (F_DUPFD or F_DUPFD_CLOEXEC);

    • Getting/setting file descriptor flags (F_GETFD or F_SETFD);

    • Getting/setting file status flags (F_GETFL or F_SETFL);

    • Getting/setting asynchronous IO ownership (F_GETOWN or F_SETOWN);

    • Getting/setting record locks (F_GETLK or F_SETLK).

  • …: The fcntl() function is a variable argument function, and the third parameter must be passed according to the specific cmd.

  • Return value: If the execution fails, it returns -1 and sets errno; if successful, the return value depends on cmd (the operation command). For example, F_DUPFD (duplicate file descriptor) will return a new file descriptor, F_GETFD (get file descriptor flags) will return the file descriptor flags, and F_GETFL (get file status flags) will return the file status flags, etc.

Example usage:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }
    // Get file descriptor flags
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) {
        perror("fcntl");
        close(fd);
        return 1;
    }
    // Set file descriptor flags, adding non-blocking flag
    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
        perror("fcntl");
        close(fd);
        return 1;
    }
    // Other operations...
    close(fd);
    return 0;
}

2

ioctl() Function

The ioctl() function can be seen as a multifunctional toolbox for file IO operations, capable of handling various miscellaneous and non-unified tasks, typically used for interacting with special files or hardware peripherals.

This blog post only introduces this system call; specific usage will be discussed in advanced articles, such as using ioctl() to obtain LCD-related information. The prototype of the ioctl() function is as follows (you can view it using the command “man 2 ioctl”):

#include
int ioctl(int fd, unsigned long request, ...);

The parameters and return values of the ioctl() function are as follows:

  • fd: File descriptor.

  • request: Used to specify the operation to be performed; the specific value depends on the object of the operation, which will be detailed later.

  • …: Variable argument list, specific parameters are determined based on the request parameter, used for operations related to the request.

  • Return value: Returns 0 on success, -1 on failure.

Example usage:

#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fs.h>
int main() {
    int fd = open("/dev/sda", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }
    // Query device block size
    long block_size;
    if (ioctl(fd, BLKSSZGET, &block_size) == -1) {
        perror("ioctl");
        close(fd);
        return 1;
    }
    printf("Block size: %ld bytes\n", block_size);
    // Other operations...
    close(fd);
    return 0;
}

Embedded Linux: fcntl() and ioctl() FunctionsEmbedded Linux: fcntl() and ioctl() FunctionsClick Read the original text for more exciting content~

Leave a Comment