dup and dup2 functions

Both of the following functions can be used to copy an existing file descriptor:

1
2
3
4
#include<unistd.h>
int  dup( int  filedes);
int  dup2( int  filedes, int  filedes2);
                                                                                                  两函数的返回值:若成功则返回新的文件描述符,若出错则返回-1

The new file descriptor returned by dup must be the smallest of the currently available file descriptors. With dup2, the value of the new descriptor can be specified with the filedes2 parameter. If filedes2 is already open, close it now. If filedes is equal to filedes2, dup2 returns filedes2 without closing it.

The new file descriptors returned by these functions share the same file table entry as the parameter filedes . As shown, we assume that we execute:

  newfd = dup (1);  

When this function starts executing, it is assumed that the next available descriptor is 3 (which is very possible since 0, 1 and 2 are opened by the shell). Because both descriptors point to the same file table entry, they share the same file status flags (read, write, append, etc.) and the same current file offset.

Each file descriptor has its own set of file descriptor flags.

 

Another way to duplicate a descriptor is to use the fcntl function, which, in effect, can be called:

dup(filedes);

equal to

fcntl(filedes,F_DUPFD,0);

while calling

dup2(filedes,filedes2);

equal to

close(filedes2);

fcntl(filedes,F_DUPFD,filedes2);

In the latter case, dup2 is not exactly equivalent to close plus fcntl. The difference between them is:

1) dup2 is an atomic operation, while close and fcntl include two function calls. It is possible to insert and execute a signal capture function between close and fcntl, which may modify the file descriptor.

2) dup2 and fcntl have some different errno.

 

Focus on explaining two places:

  • The third picture, to be executed dup2(fd, 1);, the file descriptor 1 originally pointed to tty, and now it points to a new file somefile, the original one is closed, but ttythis file originally has two reference counts, and the file descriptor save_fdalso points to it, so just Decrementing the reference count by 1 doesn't really close the file.

  • The fifth picture, to be executed dup2(save_fd, 1);, the file descriptor 1 originally pointed to somefile, and now it points to a new file tty, the original one is closed. somefileOriginally there was only one reference count, so this time it is reduced to 0, which is really closed.

1. The format of dup() and dup2() functions is as follows:

#include<unistd.h>
   int dup(int oldfd);
   int dup2(int oldfd, int newfd);

    dup() uses the lowest-numbered unused descriptor for the new descriptor.dup2
    () makes newfd be the copy of oldfd, closing newfd first ifnecessary, but note the following:
   *If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed.
        *If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd.

   1) These two functions we can use to copy file descriptors.
   2) where oldfd and newfd are the file descriptors before and after copying, respectively.
   3) The calls of these two functions will copy the file descriptor oldfd, and their return value is the new file descriptor.
    4) The difference is: the return value of dup() is the smallest unused file descriptor; the return value of dup2() is the pre-established file descriptor newfd.
    5) For dup2(), if the file descriptor newfd is in use, close newfd first; if newfd is the same as oldfd, return normally without closing the file.
    PS: This is my own classification of the words in the book.


2. If you want to understand it first, you must also understand the file descriptor clearly:
       relationship: process --- (own) ---> (several) file descriptors () --- (corresponding) ---> file
                            |--->file second prime (0)
                            |--->file descriptor (1)--->file (1)
         a process (n)---|--->file descriptor (2)
                            |--->FileDescriptor(3)--->File(3)
                            |.
                            |.
                            |.
                            |--->FileDescriptor(1023)--->File(...)
      PS1: by once The file opened by the open() function can have many descriptors connected to it;
      PS2: Each process in Linux can have 1024 file descriptors;
      PS3: The first three 0, 1, and 2 of the file descriptor correspond to:
            STDIN_FILENO 0 Standard input file
            STDOUT_FILENO 1 Standard output file
            STDERR_FILENO 2 Standard error output file
  So you can A good start to understand how the dup(int oldfd) and dup2(int oldfd, int newfd) functions work:
      dup() is good to understand:
        the system allocates a new, unused file descriptor with the smallest value Point to the file pointed to by the parameter oldfd in the dup() function, and return the value.
      dup2() is more difficult to understand:
        1) dup2() first checks whether oldfd is a valid file descriptor, if not, the call fails, and the newfd file descriptor is not closed;
        2) If oldfd is a valid file descriptor , then check whether newfd is in use, if it is in use, close it, point newfd to the file pointed to by oldfd, and return newfd;
        3) If newfd is the same as oldfd, it will return normally without closing the file.
1
2
3
4
#include<unistd.h>
int  dup( int  filedes);
int  dup2( int  filedes, int  filedes2);
                                                                                                  两函数的返回值:若成功则返回新的文件描述符,若出错则返回-1

The new file descriptor returned by dup must be the smallest of the currently available file descriptors. With dup2, the value of the new descriptor can be specified with the filedes2 parameter. If filedes2 is already open, close it now. If filedes is equal to filedes2, dup2 returns filedes2 without closing it.

The new file descriptors returned by these functions share the same file table entry as the parameter filedes . As shown, we assume that we execute:

  newfd = dup (1);  

When this function starts executing, it is assumed that the next available descriptor is 3 (which is very possible since 0, 1 and 2 are opened by the shell). Because both descriptors point to the same file table entry, they share the same file status flags (read, write, append, etc.) and the same current file offset.

Each file descriptor has its own set of file descriptor flags.

 

Another way to duplicate a descriptor is to use the fcntl function, which, in effect, can be called:

dup(filedes);

equal to

fcntl(filedes,F_DUPFD,0);

while calling

dup2(filedes,filedes2);

equal to

close(filedes2);

fcntl(filedes,F_DUPFD,filedes2);

In the latter case, dup2 is not exactly equivalent to close plus fcntl. The difference between them is:

1) dup2 is an atomic operation, while close and fcntl include two function calls. It is possible to insert and execute a signal capture function between close and fcntl, which may modify the file descriptor.

2) dup2 and fcntl have some different errno.

 

Focus on explaining two places:

  • The third picture, to be executed dup2(fd, 1);, the file descriptor 1 originally pointed to tty, and now it points to a new file somefile, the original one is closed, but ttythis file originally has two reference counts, and the file descriptor save_fdalso points to it, so just Decrementing the reference count by 1 doesn't really close the file.

  • The fifth picture, to be executed dup2(save_fd, 1);, the file descriptor 1 originally pointed to somefile, and now it points to a new file tty, the original one is closed. somefileOriginally there was only one reference count, so this time it is reduced to 0, which is really closed.

1. The format of dup() and dup2() functions is as follows:

#include<unistd.h>
   int dup(int oldfd);
   int dup2(int oldfd, int newfd);

    dup() uses the lowest-numbered unused descriptor for the new descriptor.dup2
    () makes newfd be the copy of oldfd, closing newfd first ifnecessary, but note the following:
   *If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed.
        *If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd.

   1) These two functions we can use to copy file descriptors.
   2) where oldfd and newfd are the file descriptors before and after copying, respectively.
   3) The calls of these two functions will copy the file descriptor oldfd, and their return value is the new file descriptor.
    4) The difference is: the return value of dup() is the smallest unused file descriptor; the return value of dup2() is the pre-established file descriptor newfd.
    5) For dup2(), if the file descriptor newfd is in use, close newfd first; if newfd is the same as oldfd, return normally without closing the file.
    PS: This is my own classification of the words in the book.


2. If you want to understand it first, you must also understand the file descriptor clearly:
       relationship: process --- (own) ---> (several) file descriptors () --- (corresponding) ---> file
                            |--->file second prime (0)
                            |--->file descriptor (1)--->file (1)
         a process (n)---|--->file descriptor (2)
                            |--->FileDescriptor(3)--->File(3)
                            |.
                            |.
                            |.
                            |--->FileDescriptor(1023)--->File(...)
      PS1: by once The file opened by the open() function can have many descriptors connected to it;
      PS2: Each process in Linux can have 1024 file descriptors;
      PS3: The first three 0, 1, and 2 of the file descriptor correspond to:
            STDIN_FILENO 0 standard input file
            STDOUT_FILENO 1 standard output file
            STDERR_FILENO 2 standard error output file
  So you can start to understand how the dup(int oldfd) and dup2(int oldfd, int newfd) functions work:
      dup() is better to understand :
        The system allocates a new, unused file descriptor with the smallest value to point to the file pointed to by the parameter oldfd in the dup() function, and returns the value.
      dup2() is more difficult to understand:
        1) dup2() first checks whether oldfd is a valid file descriptor, if not, the call fails, and the newfd file descriptor is not closed;
        2) If oldfd is a valid file descriptor , then check whether newfd is in use, if it is in use, close it, point newfd to the file pointed to by oldfd, and return newfd;
        3) If newfd is the same as oldfd, it will return normally without closing the file.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326645671&siteId=291194637