Почему не работает флаг O_CLOEXEC / FD_CLOEXEC?

#c #linux #pipe #fork #fcntl

#c #linux #канал #форк #fcntl

Вопрос:

У меня есть родительский процесс, имеющий несколько дочерних процессов, которым не нужен дескриптор FIFO, открытый родителем перед разветвлением. Я попытался использовать следующие подходы, которые

  • fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); после открытия fd.
  • fd = open(/tmp/testfifo, O_RDONLY|O_CLOEXEC|O_NONBLOCK);

Чтобы проверить, правильно ли он работает, я выполняю следующие шаги, но первый не работает, поскольку он определяется как ошибка. Однако я не понимаю, что не так со вторым.

Первый подход,

 if (fcntl(fd, F_GETFD) amp; FD_CLOEXEC) {
    fprintf(stderr, "FD_CLOEXEC is setn");
}
 

Второй подход через терминал,

 lsof -n | grep /private/tmp/testfifo
 

С двумя дочерними элементами он печатает,

 program   17898 soner    3r     FIFO     0t0 5274098 /private/tmp/testfifo
program   17898 soner    4w     FIFO     0t0 5274098 /private/tmp/testfifo
program   17899 soner    3r     FIFO     0t0 5274098 /private/tmp/testfifo
program   17899 soner    4w     FIFO     0t0 5274098 /private/tmp/testfifo
program   17900 soner    3r     FIFO     0t0 5274098 /private/tmp/testfifo
program   17900 soner    4w     FIFO     0t0 5274098 /private/tmp/testfifo
 

Мой подход неверен? Или я сделал что-то не так? Или я неправильно понял обоснование флага?

Комментарии:

1. Вы вызываете exec() дочерний процесс?

2. @Barmar нет, сэр, но что, если даже я это вызову? Предположим, что я выполнил шаги перед выполнением.

3. CLOEXEC это сокращение от «закрыть на exec». Это означает, что дескриптор будет автоматически закрыт при вызове процесса exec() . Он не закрывается при разветвлении.

4. @Barmar итак, все ли дочерние элементы закрывают его, вызывая close() ? Разве нет другого способа?

5. Да, это то, что они обычно делают.