| Summary: | Выводить предупреждение при запрете доступа к файлу из-за превышения лимита | ||
|---|---|---|---|
| Product: | WINE@Etersoft | Reporter: | Vitaly Lipatov <lav> |
| Component: | Файловые операции | Assignee: | Александр Морозов <amorozov> |
| Status: | CLOSED FIXED | QA Contact: | Денис Баранов <baraka> |
| Severity: | minor | ||
| Priority: | P3 | CC: | kondratyuk, mibori, vitperov |
| Version: | 1.0.9 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | All | ||
| Whiteboard: | |||
| Заявки RT: | Связано с: | ||
| Дата напоминания: | |||
| Bug Depends on: | |||
| Bug Blocks: | 3932, 4260 | ||
|
Description
Vitaly Lipatov
2008-10-29 11:40:53 MSK
В случае возникновения ошибки открытия сравнивать количество открытых дескрипторов с максимальным? Для начала надо проанализировать код ошибки. #include <stdio.h>
#include <errno.h>
#define N 10000
#define name "a.txt"
#define attr "r"
main(){
unsigned int i;
FILE *f[N];
for(i = 0; i < N; i++){
f[i] = fopen(name, attr);
if(f[i] == NULL){
printf("Invalid f[%u] = NULL: code = %i\n", i, errno);
} else {
printf("Normal f[%u] = %x\n", i, f);
}
}
for(i = 0; i < N; i++){
fclose(f[i]);
}
return 0;
}
срабатывает при невозможности открыти файл так:
...
Normal f[1014] = bff2f7ec
Normal f[1015] = bff2f7ec
Normal f[1016] = bff2f7ec
Normal f[1017] = bff2f7ec
Normal f[1018] = bff2f7ec
Normal f[1019] = bff2f7ec
Invalid f[1020] = NULL: code = 24
Invalid f[1021] = NULL: code = 24
Invalid f[1022] = NULL: code = 24
Invalid f[1023] = NULL: code = 24
Invalid f[1024] = NULL: code = 24
Invalid f[1025] = NULL: code = 24
...
#define EMFILE 24 /* Too many open files */
// из errno.h
- printf("Normal f[%u] = %x\n", i, f);
+ printf("Normal f[%u] = %x\n", i, f[i]);
конено же :)
А дальше нужно разобраться, какой код ошибки будет в Wine для CreateFile, и в каком месте вставить проверку. А главное, ведь надо ещё суметь программу с сообщением об ошибке запустить - то есть предварительно закрыть некоторые файлы. Сложности есть, пока откладываю. по идее должно возникнуть: ERROR_TOO_MANY_OPEN_FILES 4 0x4 ( http://msdn.microsoft.com/en-us/library/ms681382(VS.85).aspx ) сейчас я проверяю действительно ли это работает у нас.
> сейчас я проверяю действительно ли это
> работает у нас.
>
всё работает:
...
Normal f[9914] = 9b10
Normal f[9915] = 9b14
Normal f[9916] = 9b18
Normal f[9917] = 9b1c
Normal f[9918] = 9b20
Normal f[9919] = 9b24
Normal f[9920] = 9b28
Normal f[9921] = 9b2c
Normal f[9922] = 9b30
Normal f[9923] = 9b34
Invalid f[9924] = INVALID_HANDLE_VALUE: errno = 2, GetLastError = 4
Invalid f[9925] = INVALID_HANDLE_VALUE: errno = 2, GetLastError = 4
Invalid f[9926] = INVALID_HANDLE_VALUE: errno = 2, GetLastError = 4
Invalid f[9927] = INVALID_HANDLE_VALUE: errno = 2, GetLastError = 4
Invalid f[9928] = INVALID_HANDLE_VALUE: errno = 2, GetLastError = 4
...
код:
#include <windows.h>
#include <stdio.h>
#include <errno.h>
#define N 10000
main(){
unsigned int i, handle_edge = N;
HANDLE f[N];
const char name[] = "a.txt";
for(i = 0; i < N; i++){
f[i] = CreateFile(
name,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(f[i] == INVALID_HANDLE_VALUE){
DWORD err = GetLastError();
if(handle_edge == N)
handle_edge = i + 1;
printf(
"Invalid f[%u] = INVALID_HANDLE_VALUE: "
"errno = %i, GetLastError = %x\n",
i,
errno,
err
);
} else
printf("Normal f[%u] = %x\n", i, f[i]);
}
for(i = 0; i < handle_edge; i++)
if(!CloseHandle(f[i]))
printf("Invalid close handle f[%u]\n", i);
return 0;
}
Программа по баге 4260 практически дописана, можно браться за её вызов в нужном месте. Реализовал вывод сообщений с помощью eterx11msg. Одновременно выводится не более одного сообщения. Кроме сообщения о превышении лимита на количество дескрипторов для процесса, должны выводиться сообщения о запуске нескольких копий wineserver при отсутствии терминальной лицензии, об использовании неподходящего модуля ядра для cifs, о превышении числа одновременно работающих с файлом процессов. Вывод сообщения о запуске второго wineserver надо было вставить в сам wineserver, так как он в этом случае завершается и до обращения к etersoft_sharing_open дело не доходит. Патч: server: Show error message if a license do not allow to run second wineserver (eterbug #2761). WINE@Etersoft 1.0.11 eter8.5\eter5 Вывод предупреждения при не терминальной лицензии работает. - |