Какова цель 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_* не справляются. Это приведет к сбою процесса или неопределенному поведению.

Другие вопросы по тегам