dup

DUP(2)          Ð ÑководÑÑво пÑогÑаммиÑÑа Linux          DUP(2)



ÐÐЯ
       dup, dup2, dup3 - ÑоздаÑÑ Ð´ÑÐ±Ð»Ð¸ÐºÐ°Ñ Ñайлового
       деÑкÑипÑоÑа

ÐÐÐÐÐ
       #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);

ÐÐÐСÐÐÐÐ
       СиÑÑемнÑй вÑзов dup() ÑоздаÑÑ ÐºÐ¾Ð¿Ð¸Ñ Ñайлового
       деÑкÑипÑоÑа oldfd, иÑполÑзÑÑ Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾
       деÑкÑипÑоÑа ÑамÑй маленÑкий ÑвободнÑй
       Ð½Ð¾Ð¼ÐµÑ Ñайлового деÑкÑипÑоÑа.

       ÐоÑле ÑÑпеÑного вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑÑаÑÑй и новÑй
       ÑайловÑе деÑкÑипÑоÑÑ ÑвлÑÑÑÑÑ
       взаимозаменÑемÑми. Ðни ÑказÑваÑÑ Ð½Ð° одно и
       Ñо же оÑкÑÑÑое Ñайловое опиÑание (ÑмоÑÑиÑе
       open(2)) и поÑÑÐ¾Ð¼Ñ Ð¸Ð¼ÐµÑÑ Ð¾Ð±Ñее Ñайловое
       ÑмеÑение и Ñлаги ÑоÑÑоÑÐ½Ð¸Ñ Ñайла; напÑимеÑ,
       еÑли Ñайловое ÑмеÑение измениÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ
       lseek(2) ÑеÑез один из ÑайловÑÑ Ð´ÐµÑкÑипÑоÑов, Ñо
       ÑмеÑение измениÑÑÑ Ð¸ Ð´Ð»Ñ Ð´ÑÑгого.

       ÐÑи два ÑайловÑÑ Ð´ÐµÑкÑипÑоÑа имеÑÑ ÑазлиÑнÑе
       Ñлаги деÑкÑипÑоÑа Ñайла (Ñлаг close-on-exec).
       Флаг close-on-exec (FD_CLOEXEC; Ñм. fcntl(2)) Ñ ÐºÐ¾Ð¿Ð¸Ð¸
       деÑкÑипÑоÑа ÑбÑаÑÑваеÑÑÑ.

   dup2()
       СиÑÑемнÑй вÑзов dup2() вÑполнÑÐµÑ ÑÑ Ð¶Ðµ задаÑÑ,
       ÑÑо и dup(), но вмеÑÑо иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñамого
       маленÑкого неиÑполÑзÑемого номеÑа
       Ñайлового деÑкÑипÑоÑа, он иÑполÑзÑÐµÑ Ð½Ð¾Ð¼ÐµÑ
       Ñайлового деÑкÑипÑоÑа, Ñказанного в newfd.
       ÐÑли ÑайловÑй деÑкÑипÑÐ¾Ñ newfd Ñже оÑкÑÑÑ, Ñо он
       закÑÑваеÑÑÑ Ð¿ÐµÑед повÑоÑнÑм иÑполÑзованием.

       Шаги по закÑÑÑÐ¸Ñ Ð¸ повÑоÑÐ½Ð¾Ð¼Ñ Ð¸ÑполÑзованиÑ
       Ñайлового деÑкÑипÑоÑа 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.

ÐÐÐÐÐ ÐЩÐÐÐÐÐ ÐÐÐЧÐÐÐÐ
       Ð ÑлÑÑае ÑÑпеÑа даннÑе ÑиÑÑемнÑе вÑзовÑ
       возвÑаÑаÑÑ Ð½Ð¾Ð²Ñй ÑайловÑй деÑкÑипÑÐ¾Ñ Ð¸Ð»Ð¸ -1,
       еÑли пÑоизоÑла оÑибка (в ÑÑом ÑлÑÑае errno
       ÑÑÑанавливаеÑÑÑ Ð´Ð¾Ð»Ð¶Ð½Ñм обÑазом).

ÐШÐÐÐÐ
       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)).

ÐÐРСÐÐ
       ÐÑзов dup3() бÑл добавлен в Linux веÑÑии 2.6.27;
       поддеÑжка в glibc доÑÑÑпна Ñ Ð²ÐµÑÑии 2.9.

СÐÐТÐÐТСТÐÐРСТÐÐÐÐРТÐÐ
       dup(), dup2(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

       dup3() еÑÑÑ ÑолÑко в Linux.

ÐÐÐÐЧÐÐÐЯ
       ÐÑибка, коÑоÑÑÑ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ dup2(), оÑлиÑаеÑÑÑ Ð¾Ñ
       Ñой, ÑÑо возвÑаÑÐ°ÐµÑ fcntl(â¦, F_DUPFD, â¦), когда newfd
       наÑодиÑÑÑ Ð²Ð½Ðµ допÑÑÑимÑÑ Ð¿Ñеделов. Ðа
       некоÑоÑÑÑ ÑиÑÑÐµÐ¼Ð°Ñ dup2() Ñакже иногда
       возвÑаÑÐ°ÐµÑ EINVAL â как F_DUPFD.

       ÐÑли бÑл оÑкÑÑÑ newfd, Ñо лÑбÑе оÑибки, о коÑоÑÑÑ
       бÑло Ð±Ñ ÑообÑено close(2), ÑеÑÑÑÑÑÑ. ÐÑли ÑÑо важно,
       Ñо (еÑли пÑогÑамма однониÑÐµÐ²Ð°Ñ Ð¸ не
       вÑделÑÐµÑ ÑайловÑе деÑкÑипÑоÑÑ Ð² обÑабоÑÑикаÑ
       Ñигналов) пÑавилÑней бÑÐ´ÐµÑ Ð½Ðµ закÑÑваÑÑ newfd
       пеÑед вÑзовом dup2(), из-за ÑоÑÑÑзаÑелÑноÑÑи,
       опиÑанной вÑÑе. ÐмеÑÑо ÑÑого можно
       иÑполÑзоваÑÑ, напÑимеÑ, Ñакой код:

           /* ÐолÑÑиÑÑ ÐºÐ¾Ð¿Ð¸Ñ Â«newfd», коÑоÑÑÑ Ð·Ð°Ñем можно
              иÑполÑзоваÑÑ Ð´Ð»Ñ Ð¿ÑовеÑки оÑибок close(); оÑибка EBADF
              ознаÑаеÑ, ÑÑо «newfd» не оÑкÑÑÑ. */

           tmpfd = dup(newfd);
           if (tmpfd == -1 && errno != EBADF) {
               /* обÑабоÑка неожидаемой оÑибки dup() */
           }

           /* аÑомаÑное копиÑование «oldfd» в «newfd» */

           if (dup2(oldfd, newfd) == -1) {
               /* обÑабоÑка оÑибки dup2() */
           }

           /* ÑепеÑÑ Ð¿ÑовеÑим оÑибки close() Ñ Ñайла, на коÑоÑÑй изнаÑалÑно
              ÑÑÑлалÑÑ Â«newfd» */

           if (tmpfd != -1) {
               if (close(tmpfd) == -1) {
                   /* обÑабоÑка оÑибок закÑÑÑÐ¸Ñ */
               }
           }

СÐÐТРÐТРТÐÐÐÐ
       close(2), fcntl(2), open(2)



Linux                             2016-03-15                            DUP(2)