Introduction to up and dup2 functions ---- reprint
Dup and dup2 are two very useful calls. They are used to copy the descriptor of a file. They are often used to redirect stdin, stdout, and stderr of processes. The original form of these two functions is as follows:
# Include <unistd. h>
Int dup (int oldfd );
Int dup2 (int oldfd, int targetfd)
Using the dup function, we can copy a descriptor. If you pass it to the function an existing descriptor, it will return a new descriptor, which is a copy of the descriptor sent 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 file. The following code snippet describes how to use the dup function:
Int fd1, fd2;
...
Fd2 = dup (fd1 );
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. The following code is used to describe:
Int oldfd;
Oldfd = open ("app_log", (O_RDWR | O_CREATE), 0644 );
Dup2 (oldfd, 1 );
Close (oldfd );
In this example, we open a new file called "app_log" and receive a file descriptor named fd1. We call the dup2 function with the oldfd and 1 parameters. This will cause 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. Recall the command line pipeline mentioned earlier in this article, where we connect the standard output of the LS-1 command to the WC-l command as the standard input. Next, we will use a C program to illustrate the implementation of this process. Sample Code 3 is shown in the following code.
In Example code 3, first create an MPS queue in the code of line 3, and then divide the application into two processes: one sub-process (line 13-16) and a parent process (LINE 20-23 ). Next, in the sub-process, first disable the stdout Descriptor (13th rows), and then provide the LS-1 command function, but it is not written to stdout (13th rows ), instead, it is written to the input end of the pipeline we created. This is done 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 sub-process image with the command ls
-1 process image. Once the command is executed, any output will be sent to the input end of the pipeline.
Now let's look at the receiver of the pipeline. It can be seen from the code that the receiving end 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, and run the WC command.
-1 uses the content of the MPs queue as its input (23rd rows ).
Example code 3: Use C to implement code for command line operations
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 )...{
10:
11: If (Fork () = 0 )...{
12:
13: Close (1 );
14: Dup2 (PFDS [1], 1 );
15: Close (PFDS [0]);
16: Execlp ("ls", "ls", "-1", NULL );
17:
18: } Else ...{
19:
20: Close (0 );
21: Dup2 (PFDS [0], 0 );
22: Close (PFDS [1]);
23: Execlp ("wc", "wc", "-l", NULL );
24:
25: