какова цель fcntl с параметром F_DUPFD - PullRequest
2 голосов
/ 12 апреля 2010

Я проследил процесс оракула и обнаружил, что сначала он открывает файл /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 ]

5 голосов
/ 07 января 2011

В некоторых системах, таких как Solaris, стандартный ввод-вывод с FILE работает только с файловыми дескрипторами 0-255, потому что его реализация структуры FILE использует 8-битное целое число вместо int. Если в программе используется много файловых дескрипторов, полезно зарезервировать файловые дескрипторы 3-255 с помощью fnctl (fd, F_DUPFD, 256). В противном случае такие функции, как fopen (), freopen () и fdopen () не будут работать, если у вас открыто 256 файлов.

5 голосов
/ 12 апреля 2010

Кроме того, это файл дескрипторы , а не файл дескрипторы . Последние являются функцией C, используемой с fopen и его братьями, тогда как дескрипторы более UNIXy, для использования с open и др.

Интересно. Единственная причина, которая приходит на ум, заключается в том, что какой-то другой фрагмент кода имеет конкретную потребность в том, чтобы дескриптор файла был 256. Я подозреваю, что только Oracle узнает причину этого странного. В любом случае, вы не гарантированно получите 256, вы получите файл с первым доступным дескриптором файла, большим или равным этому числу.


Из небольшого исследования (я не знаю каждую небольшую вещь о внутренностях UNIX на моей голове), есть атрибуты, которые принадлежат группе дублированных дескрипторов, таких как файл положение и режим доступа. Существуют и другие атрибуты, принадлежащие файловому дескриптору single , даже при дублировании, например, флаг 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 и и так далее).

2 голосов
/ 14 февраля 2014

Вот еще один пример, когда требуется метод резервирования файловых дескрипторов с низким номером.

Предположим, что процесс открывает большое количество файловых дескрипторов, например, он принимает более 1024 одновременных соединений сокетов. В то же время процесс также использует стороннюю библиотеку, которая открывает соединения с сокетами и использует select(), чтобы увидеть, готовы ли сокеты для чтения или записи. Кроме того, сторонняя библиотека была скомпилирована с __FD_SETSIZE, установленным на 1024 (значение по умолчанию).

Если библиотека открывает сокет, когда используются все файловые дескрипторы ниже 1024, то она получит дескриптор, с которым select() и связанные макросы FD_ * не могут справиться. Это приведет к сбою процесса или неопределенному поведению.

...