Provided by: manpages-ru-dev_4.27.0-1_all bug

НАИМЕНОВАНИЕ

       dup, dup2, dup3 - создать дубликат файлового дескриптора

БИБЛИОТЕКА

       Стандартная библиотека языка C (libc, -lc)

ОБЗОР

       #include <unistd.h>

       int dup(int oldfd);
       int dup2(int oldfd, int newfd);

       #define _GNU_SOURCE             /* См. feature_test_macros(7) */
       #include <fcntl.h>              /* Определение констант O_* */
       #include <unistd.h>

       int dup3(int oldfd, int newfd, int flags);

ОПИСАНИЕ

       The  dup()   system call allocates a new file descriptor that refers to the same open file description as
       the descriptor oldfd.  (For an explanation of  open  file  descriptions,  see  open(2).)   The  new  file
       descriptor  number is guaranteed to be the lowest-numbered file descriptor that was unused in the calling
       process.

       After a successful return, the old and new file descriptors may be used interchangeably.  Since  the  two
       file  descriptors  refer to the same open file description, they share file offset and file status flags;
       for example, if the file offset is modified by using lseek(2)  on one of the file descriptors, the offset
       is also changed for the other file descriptor.

       Эти два  файловых  дескриптора  имеют  различные  флаги  дескриптора  файла  (флаг  close-on-exec).  Флаг
       close-on-exec (FD_CLOEXEC; см. fcntl(2)) у копии дескриптора сбрасывается.

   dup2()
       The  dup2()  system call performs the same task as dup(), but instead of using the lowest-numbered unused
       file descriptor, it uses the file descriptor number  specified  in  newfd.   In  other  words,  the  file
       descriptor newfd is adjusted so that it now refers to the same open file description as oldfd.

       If  the  file  descriptor  newfd  was  previously  open,  it  is closed before being reused; the close is
       performed silently (i.e., any errors during the close are not reported by dup2()).

       Шаги по закрытию и повторному использованию файлового дескриптора newfd выполняются атомарно. Это  важно,
       так  как  попытка  реализовать  подобное с помощью close(2) и dup() привело бы к состязательности, в силу
       чего newfd мог быть задействован повторно между этими двумя шагами. Такое повторное  использование  может
       произойти,   из-за  прерывания  основной  программы  обработчиком  сигналов,  который  выделяет  файловый
       дескриптор, или из-за параллельной нити, выделяющей файловый дескриптор.

       Также заметим следующее:

       •  Если oldfd является некорректным файловым дескриптором, то вызов завершается с  ошибкой,  а  newfd  не
          закрывается.

       •  Если  oldfd  является  корректным файловым дескриптором, а номер newfd совпадает с oldfd, то dup2() не
          делает ничего и возвращает значение newfd.

   dup3()
       dup3() похож на dup2(). Отличия заключаются в следующем:

       •  Вызывающий может принудительно установить флаг close-on-exec  flag  у  нового  файлового  дескриптора,
          указав O_CLOEXEC в flags. Зачем это может быть нужно смотрите в open(2).

       •  Если oldfd равно newfd, то dup3() выдает ошибку EINVAL.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       On  success,  these  system calls return the new file descriptor.  On error, -1 is returned, and errno is
       set to indicate the error.

ОШИБКИ

       EBADF  Значение oldfd не является открытым файловым дескриптором.

       EBADF  Значение newfd находится  вне  допустимого  диапазона  файловых  дескрипторов  (смотрите  описание
              RLIMIT_NOFILE в getrlimit(2)).

       EBUSY  (только  в  Linux)  Может случиться в dup2() или dup3() при возникновении состязательности вызовов
              open(2) и dup().

       EINTR  Вызов dup2() или dup3() был прерван каким-либо сигналом. Смотрите signal(7).

       EINVAL (dup3()) flags содержит некорректное значение.

       EINVAL (dup3()) oldfd было равно newfd.

       EMFILE Было достигнуто ограничение по количеству открытых  файловых  дескрипторов  на  процесс  (смотрите
              описание RLIMIT_NOFILE в getrlimit(2)).

СТАНДАРТЫ

       dup()
       dup2() POSIX.1-2008.

       dup3() Linux.

ИСТОРИЯ

       dup()
       dup2() POSIX.1-2001, SVr4, 4.3BSD.

       dup3() Linux 2.6.27, glibc 2.9.

ПРИМЕЧАНИЯ

       Ошибка,  которую  возвращает  dup2(), отличается от той, что возвращает fcntl(…, F_DUPFD, …), когда newfd
       находится вне допустимых пределов. На некоторых системах dup2() также  иногда  возвращает  EINVAL  —  как
       F_DUPFD.

       If  newfd  was  open, any errors that would have been reported at close(2)  time are lost.  If this is of
       concern, then—unless the program is single-threaded and does not  allocate  file  descriptors  in  signal
       handlers—the  correct approach is not to close newfd before calling dup2(), because of the race condition
       described above.  Instead, code something like the following could be used:

           /* Obtain a duplicate of 'newfd' that can subsequently
              be used to check for close() errors; an EBADF error
              means that 'newfd' was not open. */

           tmpfd = dup(newfd);
           if (tmpfd == -1 && errno != EBADF) {
               /* Handle unexpected dup() error. */
           }

           /* Atomically duplicate 'oldfd' on 'newfd'. */

           if (dup2(oldfd, newfd) == -1) {
               /* Handle dup2() error. */
           }

           /* Now check for close() errors on the file originally
              referred to by 'newfd'. */

           if (tmpfd != -1) {
               if (close(tmpfd) == -1) {
                   /* Handle errors from close. */
               }
           }

СМОТРИТЕ ТАКЖЕ

       close(2), fcntl(2), open(2), pidfd_getfd(2)

ПЕРЕВОД

       Русский перевод этой страницы руководства разработал(и) Yuri  Kozlov  <yuray@komyakino.ru>,  Иван  Павлов
       <pavia00@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот  перевод является свободной программной документацией; он распространяется на условиях общедоступной
       лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html  версии  3  или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если  вы  обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом
       разработчику(ам)  по  его(их)  адресу(ам)  электронной  почты  или  по   адресу   списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                   2 мая 2024 г.                                           dup(2)