0723------The DUP, dup2, and FCNTL functions of the Linux base----------file IO

Source: Internet
Author: User

1. DUP function

The 1.1 DUP function is used to copy a file descriptor , and the copied file descriptor can be used normally (see Example 1). The DUP function returns one of the smallest available file descriptors in the current File descriptor table (the rules for assigning file descriptors under Linux are: Finding the smallest available), which is done by the system. After the DUP function executes successfully, the two file descriptors fd_1 and Fd_2 point to the same file table entry because they share the offset (the file data structure is shown in the UNIX environment Advanced programming) and the data structure in the kernel is represented as: a process table entry, 1 File Table entries (here two file descriptors point to the same file table entry), 1 v nodes. One property in a file table entry is a reference count, and after calling DUP, two file descriptors point to the same file table entry, so the reference count in the table entry is 2,close one FD when the reference count is minus 1, and the file table entry is destroyed only if the reference count is 0 o'clock.

Example 1. The file descriptor after the DUP copy can be used normally.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h>/* * DUP copy file descriptor * */#define ERR_EXIT (m) do     {         perror (m);        Exit (exit_failure);    } while (0) int main (int argc, const char *argv[]) {    int fd_1 = open ("Test.txt", o_rdonly);    if (fd_1 = =-1) {        err_exit ("open");    }    int fd_2 = DUP (fd_1);    printf ("fd_1 =%d\t fd_2 =%d\n", fd_1, fd_2);    Char buf[1024] = {0}; This must be initialized to 0    read (fd_2, buf, 1024x768);    printf ("buf:%s\n", buf);    Close (fd_1);    Close (fd_2);    return 0;}

Example 2. The two descriptor share offset after the DUP is copied, so the file contents are contiguous when they are read alternately.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h>/* * dup  copy after two file descriptor points to the same file table entry * Thus sharing file offset */#define ERR_EXIT (m) do     {         Perror (m);        Exit (exit_failure);    } while (0) int main (int argc, const char *argv[]) {    int fd_1 = open ("Test.txt", o_rdonly);    if (fd_1 = =-1) {        err_exit ("open");    }    int fd_2 = DUP (fd_1);    printf ("fd_1 =%d\t fd_2 =%d\n", fd_1, fd_2);    Char buf[1024] = {0}; Read files alternately from two file descriptor tables read    (Fd_1, buf, 3);    printf ("Fd_1  buf:%s\n", buf);    memset (buf, 0, sizeof (BUF));    Read (Fd_2, buf, 3);    printf ("Fd_2  buf:%s\n", buf);    Close (fd_1); Close one after another can also read    memset (buf, 0, sizeof (BUF));    Read (Fd_2, buf, 3);    printf ("Fd_2  buf:%s\n", buf);    Close (fd_2);    return 0;}

2. dup2

  The 2.1 dup2 and the DUP function are the same, copying file descriptors, but the difference is that the DUP is assigned by the system FD, and DUP2 is manually specified. If the file descriptor specified by Dup2 is already occupied, the FD is closed first, and if they are equal, the FD is still returned.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h>/* *  dup2 for replication You can manually specify which FD is copied  if the FD is already occupied, then close/#define ERR_EXIT (M) Do     {         perror (m);        Exit (exit_failure);    } while (0) int main (int argc, const char *argv[]) {    int fd_1 = open ("Test.txt", o_rdonly);    if (fd_1 = =-1) {        err_exit ("open");    }    int fd_2 = 5;    Dup2 (Fd_1, fd_2);    Char buf[1024] = {0};    Read (Fd_2, buf,);    printf ("Fd_2  buf:%s\n", buf);    Close (fd_1);    Close (fd_2);    return 0;}

2.2 Two points to note

A) Two common commands od-c filename displays the contents of the file in ASCII code; du-h filename Displays the large size of the file in the disk , where OD can specify multiple formats, such as binary hexadecimal floating-point numbers, and so on.

b) If the array is not initialized to 0, it is stored in a random value. Therefore, the definition must be initialized to 0.

3. REDIRECT standard input and output

3.1 implementation of standard stream redirection is achieved by replicating FD. There are three ways to replicate FD:

A) DUP

b) dup2

c) Fcntl, set the option to F_DUPFD

3.2 Redirect standard input with DUP

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h> #include <unistd.h>/* * REDIRECT Standard input */#define ERR_EXIT (m) do     {         perror (m);        Exit (exit_failure);    } while (0) int main (int argc, const char *argv[]) {    int fd_1 = open ("Test.txt", o_rdonly);    if (fd_1 = =-1) {        err_exit ("open");    }    Close (Stdin_fileno);    int fd_2 = DUP (fd_1);     At this point 0 and 3 point to the same file table entry    //printf ("fd_1 =%d\t fd_2 =%d\n", fd_1, fd_2);//fd_1 = 3 Fd_2 = 0    char buf[1024] = {0};< C13/>fgets (buf, 1024x768, stdin);    Fputs (buf, stdout);    Close (fd_1);    return 0;}

3.3 Redirect standard input with dup2

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h> #include <unistd.h>/* * with dup2 redirection standard input */#define ERR_EXIT (m) do     {         Perror (m);        Exit (exit_failure);    } while (0) int main (int argc, const char *argv[]) {    int fd_1 = open ("Test.txt", o_rdonly);    if (fd_1 = =-1) {        err_exit ("open");    }    Dup2 (Fd_1, Stdin_fileno);  This closes the Stdin_fileno first,  then points the FD to fd_1    char buf[1024] = {0};    Fgets (buf, 1024x768, stdin);    Fputs (buf, stdout);    Close (fd_1);    return 0;}

3.4 Redirect standard input with Fcntl

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h> #include <unistd.h>/* * with FCNTL redirection standard input */#define ERR_EXIT (m) do     {         Perror (m);        Exit (exit_failure);    } while (0) int main (int argc, const char *argv[]) {    int fd_1 = open ("Test.txt", o_rdonly);    if (fd_1 = =-1) {        err_exit ("open");    }    Close (Stdin_fileno);    int fd_2 = Fcntl (fd_1, F_DUPFD, 0);    Char buf[1024] = {0};    Fgets (buf, 1024x768, stdin);    Fputs (buf, stdout);    Close (fd_1);    return 0;}

4. Fcntl function

4.1 Set the standard input descriptor to non-blocking. This explains the blocking and non-blocking . As an example of the Read function in this example, by default, Stdin_fileno is blocked, that is, if there is currently no data to read, the process goes to sleep, waits until the data is readable and returns. When we use FCNTL to set the descriptor to non-blocking, if no data is currently readable, the Read function returns 1 immediately and sets the corresponding errno value.

  

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include < sys/stat.h> #include <fcntl.h> #include <unistd.h>/* * Set standard input to non-blocking * */#define ERR_EXIT (m) do     {         Perror (m);        Exit (exit_failure);    } while (0) int main (int argc, const char *argv[]) {    int flag = FCNTL (Stdin_fileno, F_GETFL, 0);    Flag |= O_nonblock;    Fcntl (Stdin_fileno, F_SETFL, flag);    Char buf[1024] = {0};    int read_n = Read (Stdin_fileno, buf, 1024x768);    if (read_n = =-1) {        err_exit ("read");    }    return 0;}

The return value of the

4.2 fcntl is different depending on the second parameter, for example, if the parameter is F_DUPFD, the new file descriptor is returned if successful, and when the parameter is F_GETFL, the status flag of the file is returned, and the file status flag is O_rdonly,o_wronly,o _trunc and so on, add a sign and remove a flag in the way of flag |= File_flag; Flag &= ~file_flag;

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <         sys/stat.h> #include <fcntl.h> #include <unistd.h>/* * will set non-blocking and blocking encapsulation into functions */#define ERR_EXIT (m) do {        Perror (m);    Exit (Exit_failure); }while (0) void set_nonblock (int fd), void set_block (int fd), int main (int argc, const char *argv[]) {Set_nonblock (Stdin_fi    LENO);    Set_block (Stdin_fileno);    Char buf[1024] = {0};    int read_n = Read (Stdin_fileno, buf, 1024);    if (read_n = =-1) {err_exit ("read");    } printf ("Buf:%s", buf); return 0;}    void Set_block (int fd) {int flag = FCNTL (FD, F_GETFL, 0);    if (flag = =-1) {err_exit ("Fcntl GETFL");    } flag &= ~o_nonblock;    if (Fcntl (fd, f_setfl,flag) = =-1) {err_exit ("Fcntl SETFL");    }}void set_nonblock (int fd) {int flag = FCNTL (FD, F_GETFL, 0);    if (flag = =-1) {err_exit ("Fcntl GETFL");    } flag |= O_nonblock; if (Fcntl (FD, F_SETFL, flag) = = =-1) {        Err_exit ("Fcntl SETFL"); }}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.