Может ли кто-нибудь объяснить, что делает dup() в C?
Я знаю, что dup, dup2, dup3 "создаст копию файлового дескриптора oldfd" (из man-страниц). Однако я не могу его переварить.
Как я знаю, файловые дескрипторы - это просто numbers, чтобы отслеживать местоположение файлов и их направление (ввод/вывод). Было бы проще просто
fd=fd2;
Всякий раз, когда мы хотим дублировать файловый дескриптор?
И еще что-то..
dup() использует неиспользуемый дескриптор с наименьшим номером для нового дескриптора.
Означает ли это, что он может также принимать значения stdin, stdout или stderr, если мы предположим, что у нас есть close() - один из них?
Ответы
Ответ 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);