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

Может ли кто-нибудь объяснить, что делает dup() в C?

Я знаю, что dup, dup2, dup3 "создаст копию файлового дескриптора oldfd" (из man-страниц). Однако я не могу его переварить.

Как я знаю, файловые дескрипторы - это просто numbers, чтобы отслеживать местоположение файлов и их направление (ввод/вывод). Было бы проще просто

fd=fd2;

Всякий раз, когда мы хотим дублировать файловый дескриптор?

И еще что-то..

dup() использует неиспользуемый дескриптор с наименьшим номером для нового дескриптора.

Означает ли это, что он может также принимать значения stdin, stdout или stderr, если мы предположим, что у нас есть close() - один из них?

4b9b3361

Ответ 1

Просто захотел ответить на второй вопрос после нескольких экспериментов.

Ответ ДА. Дескриптор файла, который вы делаете, может принимать значения 0, 1, 2, если stdin, stdout или stderr закрыты.

Пример:

close(1);     //closing stdout
newfd=dup(1); //newfd takes value of least available fd number

Если это происходит с файловыми дескрипторами:

0 stdin     .--------------.     0 stdin     .--------------.     0 stdin
1 stdout   =|   close(1)   :=>   2 stderr   =| newfd=dup(1) :=>   1 newfd
2 stderr    '--------------'                 '--------------'     2 stderr

Ответ 2

Дескриптор файла немного больше числа. Он также несет в себе различное полузакрытое состояние (независимо от того, открыт он или нет, к какому описанию файла он относится, а также некоторые флаги). dup дублирует эту информацию, так что вы можете, например, закройте оба дескриптора самостоятельно. fd=fd2 не работает.

Ответ 3

Скажем, вы пишете программу оболочки, и вы хотите перенаправить stdin и stdout в программу, которую хотите запустить. Это может выглядеть примерно так:

fdin = open(infile, O_RDONLY);
fdout = open(outfile, O_WRONLY);
// Check for errors, send messages to stdout.
...
int pid = fork(0);
if(pid == 0) {
    close(0);
    dup(fdin);
    close(fdin);
    close(1);
    dup(fdout);
    close(fdout);
    execvp(program, argv);
}
// Parent process cleans up, maybe waits for child.
...

dup2() - это немного более удобный способ сделать это. close() dup() можно заменить на:

dup2(fdin, 0);
dup2(fdout, 1);

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

Ответ 4

Самая важная вещь в dup() - это вернуть наименьшее целое число, доступное для нового дескриптора файла. Это основа перенаправления:

int fd_redirect_to = open("file", O_CREAT);
close(1); /* stdout */
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */
close(fd_redirect_to); /* we don't need this */

После этого все, что записано в дескриптор файла 1 (stdout), волшебным образом переходит в "файл".

Ответ 5

см. эту страницу, stdout может быть псевдонимом как dup(1)...

Ответ 6

Просто совет о "дублировании стандартного вывода".

В некоторых Unix-системах (но не в GNU/Linux)

fd = open("/dev/fd/1", O_WRONLY);

он эквивалентен:

fd = dup(1);