FILE (File IO)

This section introduces the functions related to file operations. File operations are generally based on the file descriptor fd, as shown in the following figure:

The specific file system functions have been implemented in the virtual file system . You can click here to jump

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct timeval *timeout);copymistakeCopy Success

【Parameter description】

  • nfds : select the number of file handles to monitor, generally set to the maximum file descriptor value of each file to be monitored plus 1.

  • readfds : The file descriptor set monitors whether there is data to read in any file in the file set. When the select function returns, readfds will clear the unreadable file descriptors and leave only the readable file descriptors.

  • writefds : The file descriptor set monitors whether any file in the file set has data to write. When the select function returns, writefds will clear the non-writable file descriptors and leave only the writable file descriptors.

  • exceptfds : The file set will monitor any file in the file set for errors, and can be used for other purposes, such as monitoring out-of-band data OOB, which is sent to the socket using the MSG_OOB flag. When the select function returns, exceptfds will clear the other file descriptors in it, leaving only the file descriptors marked with OOB data.

  • The timeout parameter is a pointer to a struct timeval type, which allows select() to return if no file descriptor is ready after waiting for the timeout period. The timeval structure is used to specify the number of seconds and microseconds for this period. It can put select in three states:

(1) If NULL is passed as a parameter, that is, no time structure is passed, select is placed in a blocking state and waits until a file descriptor in the monitored file descriptor set changes. (2) If the time value is set to 0 seconds and 0 milliseconds, it becomes a pure non-blocking function. Regardless of whether the file descriptor changes, it returns immediately and continues to execute. If there is no change in the file, it returns 0, and if there is a change, it returns a positive value. (3) The value of timeout is greater than 0, which is the waiting timeout. In other words, select is blocked within the timeout time. If an event arrives within the timeout time, it returns. Otherwise, it will return after the timeout. The return value is the same as above.

timeval structure definition

struct timeval
{
    int tv_sec;      /* 秒 */
    int tv_usec;     /* 微妙 */
};copymistakeCopy Success

【Return value】

  • int : Returns the number of ready descriptors if any, 0 if timeout occurs, -1 if an error occurs

The following operations are used to set, clear, and determine file descriptor sets.

FD_ZERO(fd_set *set);           // 清除一个文件描述符集。
FD_SET(int fd,fd_set *set);     // 将一个文件描述符加入文件描述符集中。
FD_CLR(int fd,fd_set *set);     // 将一个文件描述符从文件描述符集中清除。
FD_ISSET(int fd,fd_set *set);   // 判断文件描述符是否被置位copymistakeCopy Success

fd_set can be understood as a set, which stores file descriptors, i.e. file handles. The three parameters in the middle specify the set of file descriptors that we want the kernel to test for read, write, and exception conditions. If you are not interested in a condition, you can set it to a null pointer.

The select() mechanism provides a data structure of fd_set , which is actually an array of long type. Each array element can establish a connection with an open file handle (whether it is a Socket handle, other file or named pipe or device handle). The work of establishing the connection is done by the programmer. When select() is called, the kernel modifies the content of fd_set according to the IO status, thereby notifying the process that executes select() which Socket or file is readable.

int poll(struct pollfd *fds, nfds_t nfds, int timeout);copymistakeCopy Success

【Parameter description】

  • fds : fds is an array of struct pollfd type, which is used to store socket descriptors whose status needs to be detected, and the fds array will not be cleared after the poll function is called; a pollfd structure represents a monitored file descriptor, and poll() is instructed to monitor multiple file descriptors by passing fds.

The prototype of struct pollfd is as follows:

typedef struct pollfd {
        int fd;                 // 需要被检测或选择的文件描述符
        short events;           // 对文件描述符fd上感兴趣的事件
        short revents;          // 文件描述符fd上当前实际发生的事件
} pollfd_t;copymistakeCopy Success

Among them, the events field of the structure is the event mask for monitoring the file descriptor, which is set by the user, and the revents field of the structure is the event mask of the operation result of the file descriptor, which is set by the kernel when the call returns.

  • nfds : records the total number of descriptors in the array fds.

  • timeout : specifies the number of milliseconds to wait. Regardless of whether the I/O is ready, poll() will return, which is similar to the select function.

【Return value】

  • int : The function returns the number of ready read, write, or error descriptors in the fds set. Returning 0 indicates a timeout, and returning -1 indicates an error.

Poll changes the way file descriptor sets are described, using the pollfd structure instead of select's fd_set structure, making the file descriptor set limit supported by poll much larger than select's 1024. This is also different from select.

If you need to read and write standard input and output (standard I/O interface), call the following function/function, please open the RT_USING_POSIX_FSand RT_USING_POSIX_STDIOmacros. If you read and write files in the file system, you only need to open it RT_USING_POSIX_FS, no need to open it RT_USING_POSIX_STDIO.

/* 标准输出 */
write(STDOUT_FILENO 或 STDERR_FILENO);
printf(...); /* 该函数仅需在gcc下使能上述两个宏,在其他编译器下,可以直接使用 */
fprintf(stdout 或 stderr);
fwrite(stdout 或 stderr);
fputs(stdout 或 stderr);
fputc(stdout 或 stderr);
puts();

/* 标准输入 */
getchar();
read(STDIN_FILENO);
fread(stdin);
fgetc(stdin);
fgets(stdin);copymistakeCopy Success

Note: If the FinSH function is enabled, you can use finsh_getchar instead of getchar in the FinSH thread to get the characters typed from the terminal.

Last updated

Assoc. Prof. Wiroon Sriborrirux, Founder of Advance Innovation Center (AIC) and Bangsaen Design House (BDH), Electrical Engineering Department, Faculty of Engineering, Burapha University