У него будет 2 fd [1] после dup (fd [1];,
Нет. Значение fd[1]
никогда не меняется. Если оно было 4 до вызована dup
, это 4 после вызова dup
.
, почему система закрыла второй fd [1] (4. [write]) в результате? не первый fd [1] (2. [Запись])?
Если fd[1]
равно 4, то close(fd[1]);
закроет дескриптор 4. Это не повлияет на другие дескрипторы, которые ссылаются на одну и ту же конечную точку.
Перед вызовом pipe
ваш процесс уже имеет дескрипторы файлов 0, 1 и 2 в качестве стандартного ввода, стандартного вывода и стандартной ошибки. Затем вы создаете два новых дескриптора для канала.
Вот как это выглядит, когда вы звоните fork
, более или менее:
... 0 ... | .... 1 .... | .....2 .... | .... fd [0] .... | ..... fd [1] .....
stdin, stdout, stderr, конец трубы, другой конец трубы
Затем в родительском элементе вы закрываете fd[0]
, поэтому у вас есть:
... 0 ... | .... 1 ..... | ..... 2 ... | .... FD [0] ................ | ...... fd [1] .....
stdin, stdout, stderr, закрытый конец трубы, открытый конец трубы
Тогда вызакрыть стандартный вывод:
... 0 .... | ... 1 .... | ..... 2 ..... | ... fd [0].. | ...... fd [1] .....
stdin, закрыто, stderr, закрыто, открытый конец трубы
Затем вы дублируете открытый конец трубы:
... 0 .... | .................. 1 ............. |..... 2 ..... | ..fd [0] .. | ....... fd [1] .....
stdin, дублирование открытого конца трубы, stderr, закрытое, открытый конец трубы
Затем закройте fd [1]:
... 0 .... | .................... 1 ............ | ..... 2 ... | ... FD [0] .. | ..fd [1].....
stdin, дублирование открытого конца трубы, stderr, закрыто, закрыто
Или, проще:
... 0 ...| ................... 1 ............... | .... 2 ....
stdin, dup открытого конца канала, stderr
Так что, когда вы вызываете execl
, новый процесс унаследует стандартный ввод и стандартную ошибку родителя, но унаследует копию одного конца своего канала какстандартвыход.