DUP function understanding

Source: Internet
Author: User

DUP Function
: Copy file descriptor
Related header files: # include <unistd. h>
Function expression: int DUP (INT filedes );
Parameter description: The DUP function parameter filedes indicates the file descriptor of the file to be copied.
Return Value Description: if a file is successfully copied and a new file descriptor is returned,-1 is returned.
Function Description: The DUP function always finds the first available file descriptor in the process file table.
To specify the file descriptor
After copying to this descriptor
, Returns this descriptor.
Function instructions:
The DUP function always copies the retest file descriptor to the location of the first available file descriptor in the process.
So we can use this feature to know the minimum available file descriptors in the process.
.
The file copied by the DUP function must be an open and valid file.
. The DUP function parameter cannot be a random integer to avoid system confusion.

 

Using the DUP function, we can copy a descriptor. Pass it to the function an existing Descriptor and it will return a new descriptor,
This new descriptor is a copy of the descriptor passed to it. This means that the two descriptors share the same data structure. For example,
If we perform the lseek operation on a file descriptor, the location of the first file is the same as that of the second one.

Note that we can create a descriptor before calling fork, which is the same as calling DUP to create a descriptor,
The sub-process will also receive a copied descriptor.

The dup2 function is similar to the DUP function, but the dup2 function allows the caller to specify the ID of a valid Descriptor and a target descriptor. When the dup2 function returns a successful result, the target Descriptor (the second parameter of the dup2 function) is changed to a replica of the source Descriptor (the first parameter of the dup2 function). In other words,
The two file descriptors now point to the same file and are the files pointed to by the first parameter of the function. Below we use a piece of code to explain :?
Int oldfd;
Oldfd = open ("app_log", (o_rdwr | o_create), 0644 );
Dup2 (oldfd, 1 );
Close (oldfd );
Note:

DUP () or dup2 () mainly redirects the output of a specific file description!
They are sure to copy the description of the file to the minimum description that is not opened currently!
The standard output corresponds to 1,
Close (1 );
DUP (FD );
Close (FD );
If the standard output is disabled, the description will be idle. Once DUP is redirected, the two of them share the same open file table item, then, you can output the standard stream to the specified location, that is, the file!
We recommend that you use dup2 ().
Dup2 (FD, stdout_fileno );
So it looks much better, right?
In this example, we open a new file called "app_log" and receive a file descriptor named fd1. We call the dup2 function,
The parameters are oldfd and 1, which causes the file descriptor represented by 1 to be replaced with the newly opened file descriptor (that is, stdout, because the ID of the standard output file is 1 ).
Everything written to stdout is now written into the file named "app_log.

It should be noted that after the dup2 function copies the oldfd, it will immediately close it, but will not turn off the newly opened file descriptor, because file descriptor 1 now points to it.

Next we will introduce a more in-depth sample code:

1: # include <stdio. h>
2: # include <stdlib. h>
3: # include <unistd. h>
4:
5: int main ()

6 :{
7: int PFDS [2];
8:
9: If (pipe (PFDS) = 0)... {// create a pipeline
10:

11: If (Fork () = 0)... {// sub-process
12:
13: Close (1); // close the stdout Descriptor
14: dup2 (PFDS [1], 1); // redirects stdout to the MPs Queue (PFDS [1])
15: Close (PFDS [0]); // close the input of the Pipeline
16: execlp ("ls", "ls", "-1", null); // Replace the image of the sub-process with the process image of the command LS-1
17:
18:} else... {// parent process
19:
20: Close (0); // close the stdin Descriptor
21: dup2 (PFDS [0], 0); // Changes stdin to the output end of the MPs queue.
22: Close (PFDS [1]); // close the stdout end of the MPs Queue (PFDS [1])
23: execlp ("WC", "WC", "-l", null); // Replace the image of the parent process with the process image of command WC-1
24:
25 :}
26:
27 :}
28:
29: Return 0;
30 :}

We use the standard output of the LS-1 command as the standard input and connect it to the WC-l command.

First, create an MPS queue in the 9th line of code, and then divide the application into two processes: A child process and a parent process.

In the sub-process, first disable the stdout Descriptor (13th rows), and then provide the LS-1 command function,
However, it is not written to stdout (row 13th), but to the input end of the pipeline we created, which is redirected through the DUP function.

In row 3, use the dup2 function to redirect stdout to the pipeline (PFDS [1]). Then, immediately turn off the input of the pipeline. Then, use the execlp function to replace the image of the sub-process with the process image of the command LS-1. Once the command is executed, any output of the sub-process will be sent to the input end of the pipeline.

Now let's look at the receiver of the pipeline.
. From the code, we can see that the receiver of the pipeline is undertaken by the parent process.
.

First, disable the stdin Descriptor (line 1) because we will not receive data input from standard device files such as the keyboard of the machine, but from the output of other programs. Then, the dup2 function (21st rows) is used again to change stdin to the output end of the pipeline, which is achieved by making the file descriptor 0 (that is, the conventional stdin) equal to PFDS [0. Close the stdout end of the MPs Queue (PFDS [1]),
Because it is not used here. Finally, use the execlp function to replace the image of the parent process with the process image of the WC-1 command. The command WC-1 uses the content of the pipeline as its input (line 1 ).

In this program, we need to pay special attention to the input of the pipeline in which our sub-process redirects its output.
Then, the parent process redirects its input to the output of the pipeline.

This is a very useful technology in actual application development.

1. Data Structure of file descriptors in the kernel
Before specifying DUP/dup2, I think it is necessary to first understand the form of file descriptors in the kernel.
When a process exists, some files are opened, and some file descriptors are returned,

Run a process from shell,
By default, three file descriptors exist (0, 1, 2)
,

0 is associated with the standard input of the process,
1. Associated with standard output of processes,

2. It is associated with the standard error output of the process,

Which file descriptors can be viewed by a process in the/proc/process ID/FD directory?
. You can clearly explain the problem:

Progress table item

----------------
FD mark file pointer
_____________________
FD 0: | ________ | ____________ | ------------> file table
FD 1: | ________ | ____________ |

FD 2: | ________ | ____________ |

FD 3: | ________ | ____________ |

| ...... |

| _____________________ |

Figure 1

The file table contains: File status mark, current file offset, and V node pointer, which are not discussed in this article.
Focus, we only need to know:

Each opened file descriptor (FD mark) has its own file table items in the progress table, pointed by the file pointer
.

2. DUP/dup2 Functions
The apue and man documents use a simple sentence to express the functions of these two functions: copying an existing file descriptor.
# Include <unistd. h>
Int DUP (INT oldfd );
Int dup2 (INT oldfd, int newfd );

This process is analyzed from figure 1. When the DUP function is called, the kernel creates a new file descriptor in the process.
The descriptor is the minimum value of the currently available file descriptor. This file descriptor points to the file table items owned by oldfd.
Progress table item

----------------

FD mark file pointer

_____________________

FD 0: | ________ | ____________ | ______

FD 1: | ________ | ____________ | ---------------- >||

FD 2: | ________ | ____________ | file table |

FD 3: | ________ | ____________ | ---------------- >|______ |

| ...... |

| _____________________ |

Figure 2:
2. If the value of oldfd is 1 and the minimum value of the current file descriptor is 3, the new descriptor 3 points
File Table items owned by descriptor 1.

The difference between dup2 and DUP is that the newfd parameter can be used to specify the value of the new descriptor,

If newfd is enabled, disable it first.

If newfd is equal to oldfd, dup2 returns newfd without disabling it. The new value returned by the dup2 Function
The file descriptor shares the same file table item with the oldfd parameter.
Apue illustrates this problem using another method:
In fact, DUP (oldfd) is called );
Equivalent
? Fcntl (oldfd, f_dupfd, 0)
Call dup2 (oldfd, newfd );
Equivalent
Close (oldfd );
Fcntl (oldfd, f_dupfd, newfd );

 

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.