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

Практические примеры используют dup или dup2

Я знаю, что делает dup или dup2, но я понятия не имею, когда он будет использоваться. Какие-нибудь практические примеры? Спасибо.

4b9b3361

Ответ 1

Одним из примеров использования будет перенаправление ввода-вывода. Для этого вы создаете дочерний процесс и закрываете дескрипторы файла stdin или stdout (0 и 1), а затем вы делаете dup() в другом выбранном вами filedescriptor, который теперь будет сопоставлен с самым низким доступным файловым дескриптором, который находится в этом случай 0 или 1.

Используя это, вы можете теперь выполнить любой дочерний процесс, который, возможно, не знает о вашем приложении и всякий раз, когда ребенок записывает на stdout (или читает из stdin, независимо от того, что вы настроили), данные записываются на предоставленный filedescriptor.

Оболочки используют это для реализации коммандос с трубами, например. /bin/ls | more, соединяя stdout одного процесса с stdin другого.

Ответ 2

Лучший сценарий для понимания dup и dup2 - перенаправление.
Первое, что нам нужно знать, это то, что система имеет 3 идентификатора файлов по умолчанию (или переменные, указывающие выходные или входные источники), которые имеют дело с вводом и выводом. Они stdin, stdout, stderr, в целых числах они 0, 1, 2. Большинство функций, таких как fprintf или cout, напрямую выводятся на stdout.
Если мы хотим перенаправить вывод, один из способов даст, например, fprintf функцию дополнительных аргументов, указывающих in и out.
Однако есть более элегантный способ: мы можем перезаписать идентификаторы файлов по умолчанию, чтобы они указывали на файл, который мы хотим получить. dup и dup2 работают именно в этой ситуации.
Начнем с простого примера: предположим, что мы хотим перенаправить вывод fprintf в txt файл с именем "chinaisbetter.txt" . Прежде всего, нам нужно открыть этот файл

int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);

Затем мы хотим, чтобы stdout указывал на "chinaisbetter.txt" с помощью функции dup:

dup2(fw,1);

Теперь stdout (1) указывает на дескриптор "chinaisbetter.txt" , хотя он все еще 1, но выход перенаправляется прямо сейчас.
Затем вы можете использовать printf как обычно, но результаты будут в файле txt вместо прямого показа на экране:

printf("Are you kidding me? \n");

PS

  • Это просто дает интуитивное объяснение, вам может потребоваться проверить man-страницу или подробную информацию. На самом деле мы говорим "копировать" здесь, они не копируют все.

  • Идентификатор файла здесь относится к обработчику файла. Описанный выше файловый дескриптор представляет собой структуру данных файлов записей.

Ответ 3

Когда вам интересно о функциях POSIX, особенно тех, которые, похоже, дублируют себя, обычно хорошо проверить сам стандарт. Внизу вы обычно увидите примеры, а также рассуждения о реализации (и существовании) обоих.

В этом случае:

Следующие разделы являются информативными.

Примеры

Перенаправление стандартного вывода в файл

Следующий пример закрывает стандартный вывод для текущих процессов, повторно назначает стандартный вывод для перехода к файлу, на который ссылается pfd, и закрывает исходный дескриптор файла для очистки.

#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...

Перенаправление сообщений об ошибках

Следующий пример перенаправляет сообщения от stderr до stdout.

#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...

Использование приложения

Отсутствует.

Обоснование

Функции dup() и dup2() являются избыточными. Их службы также предоставляются функцией fcntl(). Они включены в этот объем IEEE Std 1003.1-2001 в основном по историческим причинам, поскольку многие существующие приложения используют их.

В то время как показанный короткий сегмент кода очень похож в поведении на dup2(), соответствующая реализация, основанная на других функциях, определенных в этом томе IEEE Std 1003.1-2001, значительно сложнее. Наименее очевидным является возможный эффект функции улавливания сигнала, которая может быть вызвана между этапами, и выделять или освобождать файловые дескрипторы. Этого можно избежать, заблокировав сигналы.

Функция dup2() не является устаревшей, поскольку она представляет собой безопасную версию функциональности, предоставляемую в небезопасной версии типа fcntl(). Он используется в привязке POSIX Ada.

Функция dup2() не предназначена для использования в критических областях в качестве механизма синхронизации.

В описании [EBADF] случай, когда fildes выходит за пределы диапазона, покрывается данным случаем, когда fildes недействительны. Описания для fildes и fildes2 различны, потому что единственный вид недействительности, который имеет значение для fildes2, - это вне диапазона; то есть, не имеет значения, относится ли fildes2 к открытому файлу при вызове dup2().

Будущие направления

Отсутствует.

См. также

close(), fcntl(), open(), том базовых определений IEEE Std 1003.1-2001, <unistd.h>

История изменений

Первый выпущен в выпуске 1. Выведен из номера 1 из SVID.

Ответ 4

Один практический пример - перенаправление выходных сообщений на другой поток, например, на некоторый файл журнала. Вот пример кода для перенаправления ввода-вывода.
Пожалуйста, обратитесь к оригинальному сообщению здесь

#include <stdio.h>

main()
{
    int    fd;
    fpos_t pos;

    printf("stdout, ");

    fflush(stdout);
    fgetpos(stdout, &pos);
    fd = dup(fileno(stdout));
    freopen("stdout.out", "w", stdout);

    f();

    fflush(stdout);
    dup2(fd, fileno(stdout));
    close(fd);
    clearerr(stdout);
    fsetpos(stdout, &pos);        /* for C9X */

    printf("stdout again\n");
}

f()
{
printf("stdout in f()");
}