Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
int fcntl(int fd, int cmd, struct flock *lock);Другими словами, функция принимает по крайней мере два аргумента; в зависимости от второго аргумента, она может принимать и третий аргумент.
Последняя форма, в которой третий аргумент является указателем на
struct flock9.4.3.1. Флаг close-on-exec
После вызова
fork()exec()Организационно такое поведение может представлять проблему. Часть вашей программы, порождающая новый процесс, не должна особенно нуждаться в других частях программы, манипулирующей открытыми файлами. И цикл наподобие следующего неприятный, поскольку может не быть открытых файлов:
int j;for (j = getdtablesize(); j >= 3; j--) /* закрыть все, кроме 0, 1, 2 */ (void)close(j);Решением является флаг close-on-exec (закрытие при исполнении exec). Он является атрибутом самого дескриптора файла, а не лежащего в его основе открытого файла. Когда этот флаг установлен, система автоматически закрывает файл, когда процесс осуществляет
execАргумент
cmdF_GETFDПолучает флаги дескриптора файла. Возвращаемое значение является значением всех установленных флагов дескриптора или -1 при ошибке.
F_SETFDУстанавливает флаги дескриптора файла в содержащееся в
argВ настоящий момент определен лишь один «флаг дескриптора файла»:
FD_CLOEXECif (fcntl(fd, F_SETFD, 1) < 0) ... /* установить close-on-exec, обработать ошибки */if (fcntl(fd, F_GETFD) == 1) ... /* бит close-on-exec уже установлен */Однако, определение POSIX допускает дальнейшее расширение, поэтому правильный способ написания такого кода больше соответствует этим строкам:
int fd;long fd_flags;if ((fd_flags = fcntl(fd, F_GETFD)) < 0) /* Получить флаги */ /* обработать ошибки */fd_flags |= FD_CLOEXEC; /* Add close-on-exec flag */if (fcntl(fd, F_SETFD, fd_flags) < 0) /* Установить флаги */ /* обработать ошибки */ЗАМЕЧАНИЕ. Флаг close-on-exec является собственностью дескриптора, а не лежащего в его основе файла. Поэтому новый дескриптор, возвращенный функциями
dup()dup2()fcntl()F_DUPDdup()gawkВ языке awk операторы ввода/вывода используют обозначение перенаправления, сходное с обозначением для оболочки. Это включает односторонние каналы к и от подпроцесса:
print "something brilliant" > "/some/file" /* Вывод в файл */getline my_record < "/some/other/file" /* Ввод из файла */print "more words of wisdom" | "a_reader process" /* Вывод в подпроцесс */"a_write_process" | getline some_input /* Ввод из подпроцесса */У интерпретатора
awkawkforkexecТеперь на современных системах часть стартового кода библиотеки С времени исполнения (который запускается до вызова
main()execОднажды один пользователь сообщил, что когда в программе было максимальное количество открытых файлов, ни один процесс, для которого она пыталась использовать для конвейера
forkexecВы, возможно, можете догадаться, что произошло. Порожденная оболочка унаследовала дескрипторы открытых файлов, которые
gawkgawk9.4.3.2. Дублирование дескриптора файла
Когда аргумент
cmdfcntl()F_DUPFDdup2()arg