dup/dup2 function Learning

Source: Internet
Author: User

The DUP/DUP2 function is used to implement a copy between file descriptors. For this, let's look at the declaration of the function:

#include <unistd.h>int dup (int  OLDFD); int dup2 (intint newfd);

DUP function

The DUP function passes in a file descriptor, OLDFD must be an open file descriptor, or the DUP function call fails. The return value is the smallest file descriptor available for the current system. The test procedure is as follows:

#include <stdio.h>#include<string.h>#include<unistd.h>#include<fcntl.h>intMain () {intFD = open ("./data.txt", O_RDWR |o_creat); intNEWFD =0; /*Test OLDFD argv*/    //Close (FD);NEWFD=DUP (FD); if(NEWFD <0) {printf ("DUP error\n"); return-1; }    CharBuff[] ="Hello World"; Write (NEWFD, buff,sizeof(Buff));}

The result of the program is that the file data.txt is correctly written to "Hello World". However, if close (FD) is executed before the DUP, the DUP function call fails. The DUP function implements a function similar to the fork function after a parent-child process shares a file descriptor. Available (stolen diagrams) to understand:

The old and new descriptors share the offset (location), flags, and locks of the file, but do not share the CLOSE-ON-EXEC flag. Therefore, you can manipulate the files through them. Explanation of the CLOSE-ON-EXEC flag: If the file descriptor flag is set, the Exec family function is called in the child process produced by the fork function, and the file descriptor is automatically closed. This can be used to protect the file descriptor resource from disclosure.

dup2 function

The DUP2 function plays the same role as the DUP function. The difference is that DUP2 uses NEWFD instead of the "currently smallest available file descriptor." So, like the DUP, OLDFD must be a file descriptor that has already been opened, otherwise an error occurs. Notes on NEWFD:

    1. NEWFD can be just an integer, not the currently open file descriptor, in which case the DUP2 function is similar to the DUP function, using only NEWFD as the returned file descriptor, rather than the currently available minimum file descriptor.

    2. NEWFD is a file descriptor that is currently open, in order to reuse this file descriptor, the DUP2 function will close the file first. Equivalent to executing the close ()-->dup () procedure. However, it is important to note that this process must be an atomic operation.

Note

    1. If OLDFD is not the correct file descriptor, then the DUP2 call fails, and NEWFD will not be close.

    2. If OLDFD is a correct file descriptor, and NEWFD has the same value as OLDFD, then the DUP2 function does nothing but returns NEWFD.

Use of dup/dup2

Using the DUP2 function in a single process can play a role in redirection. For example, redirect the standard output to the specified file. The sample code is as follows:

#include <stdio.h>#include<string.h>#include<unistd.h>#include<fcntl.h>#include<errno.h>intMain () {intFD = open ("./data.txt", O_RDWR |o_creat); if(FD <0) {printf ("Open error\n"); printf ("error is%s\n", Strerror (errno)); return-1; }    intNEWFD =0; NEWFD=dup2 (FD, Stdout_fileno); if(NEWFD <0) {printf ("DUP error\n"); return-1; } printf ("Hello world\n");}

The result is that you can print Hello World directly to a file by calling the printf function. The DUP2 function can be seen to implement the redirection function. In order to restore the previous file descriptor after redirection, the following technique is often used: save and restore, first save the Stdout_fileno through the DUP function, and then use the DUP2 function to recover.

#include <stdio.h>#include<string.h>#include<unistd.h>#include<fcntl.h>#include<errno.h>intMain () {CharBuff[] ="Hello world\n"; intFD = open ("./data.txt", O_RDWR |o_creat); if(FD <0) {printf ("Open error\n"); printf ("error is%s\n", Strerror (errno)); return-1; }    intNEWFD, SAVEFD; //SaveSAVEFD =DUP (Stdout_fileno); if(SAVEFD <0) {printf ("DUP to SAVEFD error\n"); return-1; } NEWFD=dup2 (FD, Stdout_fileno); if(NEWFD <0) {printf ("DUP error\n"); return-1; } write (Stdout_fileno, buff,sizeof(Buff)); //Recovery    if(Dup2 (SAVEFD, Stdout_fileno) <0) {printf ("dup2 savefd error\n"); return-1; } write (Stdout_fileno, buff,sizeof(Buff));}

One area to note is that the standard library functions are not used here, but instead the write system calls are used. If you use functions such as printf, the final result is to output two lines of "Hello world" on the screen, while the file data.txt is empty because the buffer mischief, because the final target is the screen, so the program will finally output the contents of the buffer to the screen.

The above is used in a process, and now consider that if it involves two processes, one of which redirects the standard output to a file descriptor, and the second process redirects the file descriptor to its own standard output, the effect is that the output of one process is displayed on the standard output of another process. This is a bit of remote login meaning. Try to implement the following, in order to simplify the problem, first implemented between the parent-child process, because the parent-child process can share the file descriptor.

#include <stdio.h>#include<string.h>#include<unistd.h>#include<fcntl.h>#include<errno.h>intMain () {intFD = open ("./data.txt", O_RDWR |o_creat); intpid; if(FD <0) {printf ("Open error\n"); printf ("error is%s\n", Strerror (errno)); return-1; }    intNEWFD, SAVEFD; if((SAVEFD = DUP (Stdout_fileno)) <0) {printf ("DUP savefd error\n"); return-1; } NEWFD=dup2 (FD, Stdout_fileno); if(NEWFD <0) {printf ("DUP error\n"); return-1; } printf ("Hello world\n"); if(PID = fork ()) = =0)    {        //Child Process//Chang FD to stdout        if(Dup2 (SAVEFD, Stdout_fileno) <0) {printf ("dup2 savefd error\n"); return-1; }        if(Dup2 (Stdout_fileno, FD) <0) {printf ("Child dup2 FD error\n"); return-1; } printf ("Child Hello world\n"); Sleep (2);        Close (FD); return; }    Else if(PID >0)    {        //don ' t show in child stdoutprintf"Parent Hello world\n");    Close (FD); }}

It seems that the implementation of the code is correct, but the result of the operation does not have a practical effect. The use of DUP/DUP2 functions between multiple processes remains to be studied.

dup/dup2 function Learning

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.