Hello and welcome!
In this video session we will discuss on dup() and dup2() System Call.
Let's begin with the program of dup() system call.
Here.
We have few programs to explain.
Dup() system call.
Let's open a program for dup() system call.
Before explaining what is DUP system call?
Let's open the manual page of DUP system call.
In order to open the manual page of dup system call, we have to enter man, followed by two, followed
by dup.
Here.
Man is the manual and dup is the system call.
Two refers to the set of system calls.
So all system calls are present in a reference 2 of manual pages.
In order to use dup system call, we have to include Unistd.h.
dup() nothing, but it creates a duplicate of file descriptor specified in 'oldfd' parameter.
So in the dup() system call, it creates a duplicate of the file descriptor provided here in the argument
and returns new file descriptor.
This new file descriptor is lower value of the file descriptor available in the file descriptor table
of the process.
Let's see what this means.
So before we had discussed that file descriptor table is per process and zero, one and two or default
file descriptors available in every process.
Now if we want to duplicate a file descriptor, let's say we want to duplicate file descriptor number
two which is nothing but standard error.
If we pass 'fd' equal to two here.
In this case we have oldfd equal to two, dup system call returns a new file descriptor and the new
file descriptor will be lowest number unused in the file descriptor table.
So here in this case we have 0 1 2 file descriptors and duplicating.
fd equal to two we get the next lowest number available which is three.
Now let's say that there is already a file descriptor by value three and it refers to some file.
Now, if we duplicate the file descriptor two, we get the next lowest unused file descriptor.
In this case we have 0 1 2 3.
So we will get the next lowest unused FD using dup system call as four
In this case.
Now let's see the example of dup system call.
As we have explained, the DUP system call is used to duplicate the file descriptor.
Whatever we provide in this argument of dup system call.
It provides a duplicate of this and returns a new file descriptor.
Here, the old file descriptor is duplicated to the next available number from the file descriptor table.
Let's see how this works here.
Let's open the program file.
In this program we have included all the required header files.
Now let's say we are going to open a new file called newFile.log
And if the file is not present we are going to create the file in the specified mode.
0767.
That means user can read, write and execute.
And if the open system call fails, it returns -1.
And we can print the error.
Else the open system call is successful.
Now let's see how to use this dup system call.
So the open system call returns the file descriptor of newFile.log file.
This is being passed as argument to dup system call.
So we need to duplicate this file descriptor to get the new file descriptor.
This will be returned in 'newfd'.
'newfd' is also type integer.
Here we are printing the new file descriptor.
Now, what we have in the process level file descriptor table is, we have a new file descriptor let's
say three which points to this file.
'newFile.log'.
So fd was pointing to the newFile, now we have duplicated it.
So probably if the next available number may be four.
Let's run this and see the output.
Let's compile the code using gcc.
space
dup_1a.c -o .
Space dup_1a
Let's create object file named dup_1a.
Let's compile this file.
We have successfully compiled this code.
Now let's run the program.
By running ./dup_1a.
Here, the open system was executed successfully.
This means we were able to create the new file called 'newFile.log' and new file value after dup
is 4.
Let's see what is the initial value of FD?
The initial value of fd is three and this refers to the file 'newFile.log'
DUP system call creates a.
Duplicate of file descriptor.
So in this case we have got the next lowest number available which is four in our case.
So one more thing here is we can say that when we refer to this fd or this fd, which is 'newfd', both refers
to the same file.
So this is the meaning of duplicating the file descriptor.
Let's add string to file using newfd and let's recompile this file using gcc.
Now let's run the program again.
Now let's open the file and see whether specified string has been written to the file or not.
Let's open the file named 'newFile.log'
So here we can see that both 'newfd' and 'fd' have written to the same file.
That is 'newFile.log'
So let's see some use cases of dup system call.
One of the application of dup system call is to redirect the output to the file instead of the screen,
and the contents of the file can be used to analyze the program at a later point of time.
Let's see how to achieve this using dup() system call.
Here we have opened a file called 'newFile.log' in order to capture all the output of the program.
If open system call returns -1
Then open system call has failed and we exit the program.
Else the open system call is success.
Now let's close the file descriptor one.
When we say file descriptor equal to one, it refers to the standard output which is nothing but the
screen.
When we close this file descriptor one.
Now the file descriptor table has zero, two and three.
fd =3 points to the file newFile.log and we have closed.
fd=1, we have closed standard output here.
Now let's duplicate the file descriptor pointing to the file 'newFile.log'
When we duplicate this file, we get the next lowest number available in the file descriptor table.
As we know, the file descriptor table now contains zero, two, and three.
The lowest number is one because one is available as we have closed the fd=1.
So calling dup() of three here it duplicates and returns new fd=1
So we get the new FD equal to one.
What it means here is fd =1 now refers to file newFile.log and not standard output.
So now, when we perform any printf function the printf is going to write to the default standard output.
That is fd = 1 one.
But when it writes to.
fd = 1, it does not write to standard output.
But in turn it writes all the output to the file.
Because fd = 1 and fd = 3.
both points to the same file here.
Let's compile this and see whether we have achieved this or not.
The compilation is successful.
Before running, let's clear all old files.
Let's remove the file.
newFile.log.
Now let's run the program.
We have executed the program and we are getting open system call executed successfully.
If we observe the printf output is not present on the screen.
Rather, it would be redirected to a file called newFile.log
Let's open this file and check its content.
Whatever was in the printf did not come to the screen.
Rather, it is now returned to the file.
newFile.log.
Now let's see the working of Dup2 system call.
In this example, let's discuss the dup2 system call.
dup2() system call is similar to dup() system call, but there are few differences between dup2() and
dup() system call.
Before starting Dup2 system call.
Let's see the manual page of dup2() System call.
Let's open manual page of dup2() system call.
In order to use dup2, we have to include Unistd.h, and in dup2 we have two parameters.
The first one is the oldfd and the second one is the newfd.
When we call dup2() system call, the newfd will be closed and the duplicate of oldfd will be given
to the newfd value.
Let's see an example to understand this.
In this example, we are going to open a new file called newfile2.log.
And if it is not present, we are going to create in the required mode.
If the open system call fails, we are going to print the failure message and exit the program.
If open system call is successful, the program proceeds further.
The Dup2 system call takes two parameters.
First will be the oldfd.
Second will be newfd.
In this case of dup2 system call, newfd will be closed.
That is here one is closed.
One(fd=1) refers to standard output which is nothing but screen in this case.
Then a duplicate of FD is created and in case of dup2() system call, the duplicate value will always
be value of newfd that was closed.
But in previous dup() system call.
It duplicates to the lowest number that is available, but in dup2(), we can make sure that we can
provide the value that is required by the user.
So here dup2() has more control over the dup() system call also dup2() system call performs in a atomic
manner, which means all the actions handled by dup2() system call is guaranteed to execute as a atomic
manner.
That means the complete thing will be performed without any interrupt.
Now after dup2 system call both old and new fd points to the same file.
So here in this case it points to the file newfile2.log
In this program.
Whenever the program writes output to the screen, that is, fd=1, it actually writes
to the file called newfile2.log
In this example, the printf function which writes to file that is pointed by fd = 1
Now, since fd =1, points to newfile2.log because of dup2 system call, the contents
of printf will be written to newfile2.log instead of output screen.
Let's compile this program and see the output for better understanding.
Now let's run the program.
dup2() has been successfully executed and we got open system call executed
Successful message on the screen.
So if you observe before dup2 system call, all printf message is written to screen, but after dup2
system call, the printf message are being written to newfile2.log
In this video session we have learned about dup and dup2 System Call.
Join me in next session to discuss some use case of file operations.
Thank you.