Я наткнулся на следующий код в одной из наших собственных библиотек и пытаюсь понять поведение, которое он демонстрирует:
long GetFD(long* fd, const char* fileName, const char* mode)
{
string fileMode;
if (strlen(mode) == 0 || tolower(mode[0]) == 'w' || tolower(mode[0]) == 'o')
fileMode = string("w");
else if (tolower(mode[0]) == 'a')
fileMode = string("a");
else if (tolower(mode[0]) == 'r')
fileMode = string("r");
else
return -1;
FILE* ofp;
ofp = fopen(fileName, fileMode.c_str());
if (! ofp)
return -1;
*fd = (long)_fileno(ofp);
if (*fd < 0)
return -1;
return 0;
}
long CloseFD(long fd)
{
close((int)fd);
return 0;
}
После повторного вызова GetFD с соответствующим CloseFD весь dll больше не сможет выполнять какой-либо файловый ввод-вывод. Я написал программу-тестер и обнаружил, что могу получить GetFD 509 раз, но 510-й раз приведет к ошибке.
При использовании Process Explorer количество дескрипторов не увеличивалось.
Таким образом, похоже, что DLL достигает предела для количества открытых файлов; установка _setmaxstdio(2048)
увеличивает количество раз, которое мы можем вызвать GetFD. Очевидно, что close () работает совершенно правильно.
После небольшого поиска я заменил вызов fopen()
на:
long GetFD(long* fd, const char* fileName, const char* mode)
{
*fd = (long)open(fileName, 2);
if (*fd < 0)
return -1;
return 0;
}
Теперь повторный вызов GetFD / CloseFD работает.
Что здесь происходит?