Какова цель fcntl с параметром F_DUPFD
Я проследил процесс оракула, и найти его сначала открыть файл /etc/netconfig
как дескриптор файла 11
, а затем продублируйте 256
позвонив fcntl
с параметром F_DUPFD
, а потом close
оригинальный дескриптор файла 11
, Позже он прочитал с помощью дескриптора файла 256
, Так какой смысл дублировать дескриптор файла? Почему бы просто не поработать с оригинальным дескриптором файла?
12931: 0.0006 open("/etc/netconfig", O_RDONLY|O_LARGEFILE) = 11
12931: 0.0002 fcntl(11, F_DUPFD, 0x00000100) = 256
12931: 0.0001 close(11) = 0
12931: 0.0002 read(256, " # p r a g m a i d e n".., 1024) = 1024
12931: 0.0003 read(256, " t s t p i _ c".., 1024) = 215
12931: 0.0002 read(256, 0x106957054, 1024) = 0
12931: 0.0001 lseek(256, 0, SEEK_SET) = 0
12931: 0.0002 read(256, " # p r a g m a i d e n".., 1024) = 1024
12931: 0.0003 read(256, " t s t p i _ c".., 1024) = 215
12931: 0.0003 read(256, 0x106957054, 1024) = 0
12931: 0.0001 close(256) = 0
3 ответа
Кроме того, они являются файловыми дескрипторами, а не файловыми дескрипторами. Последние являются функцией C, используемой с fopen
и его братьев, в то время как дескрипторы более UNIXy, для использования с open
и другие.
Интересно. Единственная причина, которая приходит на ум, заключается в том, что какой-то другой фрагмент кода имеет конкретную потребность в том, чтобы дескриптор файла был 256. Я подозреваю, что только Oracle будет знать причину для этого причудливого. В любом случае вы не гарантированно получите 256, вы получите файл с первым доступным дескриптором файла, большим или равным этому числу.
После небольшого исследования (я не знаю всех мелочей о внутренностях UNIX в верхней части моей головы), есть атрибуты, которые принадлежат группе дублированных дескрипторов, такие как положение файла и режим доступа. Существуют и другие атрибуты, которые принадлежат одному дескриптору файла, даже при дублировании, например, флаг close-on-exec в GNULib.
Делать дубликат (либо с dup
, dup2
или ваш fcntl
) может быть способом создания двух дескрипторов, один с разными атрибутами дескриптора файла, но я не вижу, что дело в вашем вопросе, так как первый дескриптор все равно закрыт. Как вы говорите, почему бы просто не использовать низкий дескриптор?
Интересно, что если вы Google для netconfig f_dupfd
вы увидите похожие следы, где fcntl
не удается, и он продолжает читать этот файл с низким дескриптором, поэтому я думаю, что это попытка сохранить как можно меньше файловых дескрипторов. Например:
4327: open("/etc/netconfig", O_RDONLY|O_LARGEFILE) = 4
4327: fcntl(4, F_DUPFD, 0x00000100) Err#22 EINVAL
4327: read(4, " # p r a g m a i d e n".., 1024) = 1024
4327: read(4, " t s t p i _ c".., 1024) = 215
4327: read(4, 0x00296B80, 1024) = 0
4327: lseek(4, 0, SEEK_SET) = 0
4327: read(4, " # p r a g m a i d e n".., 1024) = 1024
4327: read(4, " t s t p i _ c".., 1024) = 215
4327: read(4, 0x00296B80, 1024) = 0
4327: close(4) = 0
Возможно, программное обеспечение имеет байтовый массив файловых дескрипторов где-то ограниченным, поэтому оно пытается переместить другие файлы выше 255-предела.
Но на самом деле, это всего лишь догадки с моей стороны (хотя я хотел бы думать, что это довольно умные догадки). Также имейте в виду, что это может делать не сам Oracle. Материал netconfig используется во многих местах, поэтому это может быть какая-то базовая библиотека, особенно в свете того факта, что большинство вышеупомянутых веб-хитов не были специфичны для Oracle (ftp
, remsh
и так далее).
В некоторых системах, таких как Solaris, стандартный ввод-вывод с FILE работает только с файловыми дескрипторами 0-255, потому что его реализация структуры FILE использует 8-битное целое число вместо int. Если в программе используется много файловых дескрипторов, полезно зарезервировать файловые дескрипторы 3-255 с помощью fnctl(fd, F_DUPFD, 256). В противном случае такие функции, как fopen(), freopen() и fdopen() не будут работать, если у вас открыто 256 файлов.
Вот еще один пример, когда необходима техника резервирования файловых дескрипторов с низким номером.
Предположим, что процесс открывает большое количество файловых дескрипторов, например, он принимает более 1024 одновременных соединений сокетов. В то же время процесс также использует стороннюю библиотеку, которая открывает сокетные соединения и использует select()
чтобы увидеть, готовы ли сокеты для чтения или записи. Кроме того, сторонняя библиотека была скомпилирована с __FD_SETSIZE
установите на 1024 (значение по умолчанию).
Если библиотека открывает сокет, когда используются все файловые дескрипторы ниже 1024, она получит дескриптор, который select()
и связанные макросы FD_* не справляются. Это приведет к сбою процесса или неопределенному поведению.