dup2 System Call in C

29/12/2020
Chưa phân loại
The dup2() system function is used to create a copy of an existing file descriptor. In Linux, there are 3 standard file descriptors. They are:

stdin: This is the standard input file descriptor. It is used to take input from the terminal by default. scanf(), getc() etc functions uses stdin file descriptor to take user inputs. The stdin file descriptor is also represented by the number 0.

stdout: This is the standard output file descriptor. It is used to print something to the console/terminal by default. The widely used printf() function uses stdout to print your desired output to the console/terminal. The stdout file descriptor is also represented by the number 1.

stderr: This is the standard error file descriptor. It does the same thing as the stdout file descriptor. The stderr file descriptor is used to print error messages on the console/terminal. The only difference is if you use stderr file descriptor to print the error messages, and stdout file descriptor to print normal outputs, then you can later separate them. For example, you can redirect the error messages to a file and normal outputs to the console or another file. The stderr file descriptor is also represented by the number 2.

Other than these 3 file descriptors, you can create additional file descriptors in C. To create a new file descriptor, you can use the open() function in C. The open() function opens a new file, creates a file descriptor for that file and attaches a number other than 0, 1, 2 to the file descriptor.

Once you open a file using open() function, you can use the read() and write() function to read and write to the newly created file descriptor.

Now, imagine a situation where you want to read from a specific file using scanf() or getc() function and write to another file using printf() function. This is not the default behavior of the scanf(), getc() and printf() functions as I explained earlier. By default, scanf() and getc() function uses stdin and printf() uses stdout and there is no way to tell these functions to use other file descriptors. So, to alter this default behavior, you have to replace the stdin and stdout file descriptors with your desired file descriptors. This is what the dup2() system function does. The dup2() function copies a file descriptor to another file descriptor.

dup2() Syntax and Return Value:

The syntax of dup2() function is:

int dup2(int old_file_descriptor, int new_file_descriptor);

dup2() function copies the old_file_descriptor into the new_file_descriptor. If the new_file_descriptor already exists, then it’s automatically closed and then the old_file_descriptor is copied to it.

On success, the dup2() function returns the new file descriptor. If an error occurs, dup2() returns -1.

The dup2() function is defined in the header file unistd.h.

You must include the header unistd.h in your C source file in order to use the dup2() function as follows:

#include <unistd.h>

For more information, check the man page of dup2() with the following command:

$ man dup2

Example 1:

Create a new C source file 01_dup2.c and type in the following lines of codes in the file.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
 
int main(void) {
  int number1, number2, sum;
 
  int input_fds = open("./input.txt", O_RDONLY);
 
  if(dup2(input_fds, STDIN_FILENO) < 0) {
    printf("Unable to duplicate file descriptor.");
    exit(EXIT_FAILURE);
  }
 
  scanf("%d %d", &number1, &number2);
 
  sum = number1 + number2;
 
  printf("%d + %d = %dn", number1, number2, sum);
 
  return EXIT_SUCCESS;
}

Now, create a new file input.txt in the same directory and type in the following line in it.

15 41

The main objective of this program is to read 2 integer numbers from the input.txt file using scanf() function, add them and print the sum.

First, I included the required header files with the following lines of codes.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

In the main() function, I defined the required variables.

int number1, number2, sum;

Then, I opened the file input.txt in read only mode (O_RDONLY) using the open() function and stored the file descriptor in the variable input_fds.

int input_fds = open("./input.txt", O_RDONLY);

Once I have the file descriptor of the input.txt file, I copied the file descriptor into the standard input file descriptor STDIN_FILENO (0) using dup2() function. The file descriptor of input.txt is now the default stdin file descriptor.

dup2(input_fds, STDIN_FILENO)

I could also write the dup2() function as follows. The result would be the same. STDIN_FILENO holds the value 0, which is the value of the stdin file descriptor.

dup2(input_fds, 0)

I also checked for dup2() errors with the following lines. If an error do occur, the program is set to print an error message and exit.

if(dup2(input_fds, STDIN_FILENO) < 0) {
  printf("Unable to duplicate file descriptor.");
  exit(EXIT_FAILURE);
}

Then, I used scanf() to scan 2 numbers from the input.txt file.

scanf("%d %d", &number1, &number2);

Then, I added the numbers and printed the sum on the console/terminal, the default stdout.

sum = number1 + number2;
printf("%d + %d = %dn", number1, number2, sum);

As you can see, I got the expected output once I run the program.

Example 2:

Create a new C source file 02_dup2.c and type in the following lines of codes in the file.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void) {
  int number1, number2, sum;
  int input_fds = open("./input.txt", O_RDONLY);
  int output_fds = open("./output.txt", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
  dup2(input_fds, STDIN_FILENO);
  dup2(output_fds, STDOUT_FILENO);
  scanf("%d %d", &number1, &number2);
  sum = number1 + number2;
  printf("%d + %d = %dn", number1, number2, sum);
  return EXIT_SUCCESS;
}

Now, create a new file input.txt in the same directory and type in the following line in it.

15 41

In this program, I did the same thing as in Example 1. The only difference is that I created a new file output.txt and used the file descriptor of output.txt as the default stdout file descriptor using the dup2() function. Now, all the output of the printf() function will be written to the output.txt file.

I created a new file and stored the file descriptor in output_fds variable.

int output_fds = open("./output.txt", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);

I also copied the output_fds file descriptor to the stdout file descriptor. I used the predefined constant STDOUT_FILENO.

dup2(output_fds, STDOUT_FILENO);

STDOUT_FILENO contains the value 1 (the default file descriptor value of stdout). So, I could rewrite dup2() function call as follows. It would give the same results.

dup2(output_fds, 1);

The rest of the program is the same. As you can see, once I run the program, it does not print anything on the console/terminal.

But, the program created a new file output.txt file.

As you can see, the output is written to the file output.txt.

If you want to write all errors (stderr) to another file, then you can also copy a file descriptor to stderr file descriptor as follows.

dup2(error_fds, STDERR_FILENO);

So, that’s how you use the dup2() system call in C. Thanks for reading this article.

Sandclock IDC thành lập vào năm 2012, là công ty chuyên nghiệp tại Việt Nam trong lĩnh vực cung cấp dịch vụ Hosting, VPS, máy chủ vật lý, dịch vụ Firewall Anti DDoS, SSL… Với 10 năm xây dựng và phát triển, ứng dụng nhiều công nghệ hiện đại, Sandclock IDC đã giúp hàng ngàn khách hàng tin tưởng lựa chọn, mang lại sự ổn định tuyệt đối cho website của khách hàng để thúc đẩy việc kinh doanh đạt được hiệu quả và thành công.
Bài viết liên quan

Install Zorin OS Ultimate

Zorin OS is one of the most beautiful Linux distros out there that specifically targets new Linux users who had previously...
29/12/2020

A Guide to Using PPA Repositiories in Ubuntu

One of the benefits of using Ubuntu is the wide availability of a range of third party repositories. These repositories...
29/12/2020

How to Measure Distance with Raspberry Pi

You can measure distance using the HC-SR04 ultrasonic sensor with Raspberry Pi. The HC-SR04 sensor can measure distance...
29/12/2020
Bài Viết

Bài Viết Mới Cập Nhật

Hướng dẫn chuyển đổi windows server windows evaluation to standard và active windows server 2008 + 2012 + 2016 + 2019
26/10/2021

How to Update Ubuntu Linux
24/10/2021

Squid Proxy Manager cài đặt và quản lý Proxy Squid tự động trên ubuntu
20/10/2021

Hướng dẫn cài đặt Apache CloudStack 4.15.2.0
19/10/2021

Hướng dẫn ký file PDF bằng chữ ký số (chữ ký điện tử) và sửa lỗi mới nhất 2021 foxit reader
19/10/2021