Подтвердить что ты не робот

Dup2/dup - зачем мне дублировать файловый дескриптор?

Я пытаюсь понять использование dup2 и dup.

На странице man:

DESCRIPTION

dup and dup2 create a copy of the file descriptor oldfd.
After successful return of dup or dup2, the old and new descriptors may
be used interchangeably. They share locks, file position pointers and
flags; for example, if the file position is modified by using lseek on
one of the descriptors, the position is also changed for the other.

The two descriptors do not share the close-on-exec flag, however.

dup uses the lowest-numbered unused descriptor for the new descriptor.

dup2 makes newfd be the copy of oldfd, closing newfd first if necessary.  

RETURN VALUE

dup and dup2 return the new descriptor, or -1 if an error occurred 
(in which case, errno is set appropriately).  

Зачем мне этот системный вызов? в чем заключается дублирование файлового дескриптора?

Если у меня есть файловый дескриптор, зачем мне его копировать?

Буду признателен, если бы вы могли объяснить и дать мне пример, где требуется dup2/dup.

Спасибо

4b9b3361

Ответ 1

Системный вызов dup дублирует существующий файловый дескриптор, возвращая новый, который относится к одному и тому же базовому объекту ввода-вывода.

Dup позволяет оболочкам реализовать такие команды:

ls existing-file non-existing-file > tmp1  2>&1

2 > & 1 сообщает оболочке предоставить команду файловому дескриптору 2, который является дубликатом дескриптора 1. (то есть stderr и stdout указывают на тот же fd).
Теперь сообщение об ошибке для вызова ls на несуществующий файл и правильный вывод ls в существующем файле отображаются в файле tmp1.

Следующий пример кода запускает программу wc со стандартным подключением к считываемому концу трубы.

int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = 0;
pipe(p);
if(fork() == 0) {
    close(STDIN); //CHILD CLOSING stdin
    dup(p[STDIN]); // copies the fd of read end of pipe into its fd i.e 0 (STDIN)
    close(p[STDIN]);
    close(p[STDOUT]);
    exec("/bin/wc", argv);
} else {
    write(p[STDOUT], "hello world\n", 12);
    close(p[STDIN]);
    close(p[STDOUT]);
}

Ребенок дублирует конец чтения на дескриптор файла 0, закрывает файл de скрипты в p и execs wc. Когда wc читает со своего стандартного ввода, он считывает из трубы.
Это то, как трубы реализованы с использованием dup, так что, используя дуп, вы используете канал для сборки чего-то еще, что красота системных вызовов вы строите одну вещь за другой, используя уже существующие инструменты, этот инструмент был построен с использованием что-то еще. В конце системные вызовы - это самые основные инструменты, которые вы получаете в ядре

Приветствия:)

Ответ 2

Другой причиной дублирования файлового дескриптора является использование fdopen. fclose закрывает дескриптор файла, который был передан в fdopen, поэтому, если вы не хотите, чтобы исходный дескриптор файла был закрыт, вы должны сначала его дублировать с помощью dup.

Ответ 3

Некоторые моменты, связанные с dup/dup2, можно отметить, пожалуйста,

dup/dup2. Технически цель состоит в том, чтобы разделить одну таблицу файлов с записью внутри одного процесса разными дескрипторами. (Если мы разыскиваем дескриптор, по умолчанию дублируем в дочернем процессе, и запись в таблице файлов также разделяется).

Это означает, что у нас может быть более одного дескриптора файла, имеющего, возможно, разные атрибуты для одной отдельной записи таблицы открытых файлов с использованием функции dup/dup2.

(Хотя в настоящий момент только флаг FD_CLOEXEC является единственным атрибутом для дескриптора файла).

http://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html

dup(fd) is equivalent to fcntl(fd, F_DUPFD, 0);

dup2(fildes, fildes2); is equivalent to 

   close(fildes2);
   fcntl(fildes, F_DUPFD, fildes2);

Различия (для последнего) - Помимо некоторого значения errno, начиная с dup2 и fcntl close, за которым следует fcntl, может повысить условия гонки, так как задействованы два вызова функций.

Подробности можно проверить из http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html

Пример использования -

Один интересный пример при реализации управления заданиями в оболочке, где можно увидеть использование dup/dup2.. в ссылке ниже

http://www.gnu.org/software/libc/manual/html_node/Launching-Jobs.html#Launching-Jobs

Ответ 4

dup используется для перенаправления вывода из процесса.

Например, если вы хотите сохранить вывод из процесса, вы дублируете вывод (fd = 1), вы перенаправляете дублированный fd в файл, затем выполняете вилку и выполняете этот процесс, а когда процесс завершается, вы снова перенаправить сохраненный fd на вывод.