Bug 2761

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
Надо разобраться, если возможно отличить, что открытие файла не удалось
из-за превышения лимита на количество дескрипторов, то нужно выводить
специальное сообщение.
Comment 1 Константин Кондратюк 2008-10-29 12:19:23 MSK
В случае возникновения ошибки открытия сравнивать количество открытых дескрипторов с максимальным?
Comment 2 Vitaly Lipatov 2008-10-29 13:19:44 MSK
Для начала надо проанализировать код ошибки.
Comment 3 Anton Rudnev 2009-03-05 14:56:28 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
Comment 4 Anton Rudnev 2009-03-05 15:01:35 MSK
- printf("Normal f[%u] = %x\n", i, f);
+ printf("Normal f[%u] = %x\n", i, f[i]);

конено же :)
Comment 5 Vitaly Lipatov 2009-03-05 16:17:49 MSK
А дальше нужно разобраться, какой код ошибки будет в Wine для CreateFile,
и в каком месте вставить проверку.

А главное, ведь надо ещё суметь программу с сообщением об ошибке запустить - то есть предварительно закрыть некоторые файлы.
Сложности есть, пока откладываю.
Comment 6 Anton Rudnev 2009-03-05 17:51:12 MSK
по идее должно возникнуть:

ERROR_TOO_MANY_OPEN_FILES
4
0x4

( http://msdn.microsoft.com/en-us/library/ms681382(VS.85).aspx )

сейчас я проверяю действительно ли это работает у нас.
Comment 7 Anton Rudnev 2009-03-05 18:40:31 MSK
 
> сейчас я проверяю действительно ли это
> работает у нас.
>

всё работает:

...
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
...
Comment 8 Anton Rudnev 2009-03-05 18:41:48 MSK
код:

#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;
}
Comment 9 Vitaly Lipatov 2009-09-07 18:42:13 MSD
Программа по баге 4260 практически дописана, можно браться за её вызов в нужном месте.

Comment 10 Александр Морозов 2009-09-29 18:07:02 MSD
Реализовал вывод сообщений с помощью eterx11msg. Одновременно выводится не более одного сообщения.

Кроме сообщения о превышении лимита на количество дескрипторов для процесса, должны выводиться сообщения о запуске нескольких копий wineserver при отсутствии терминальной лицензии, об использовании неподходящего модуля ядра для cifs, о превышении числа одновременно работающих с файлом процессов.
Comment 11 Александр Морозов 2009-10-01 12:12:27 MSD
Вывод сообщения о запуске второго wineserver надо было вставить в сам wineserver, так как он в этом случае завершается и до обращения к etersoft_sharing_open дело не доходит.

Патч: server: Show error message if a license do not allow to run second wineserver (eterbug #2761).
Comment 12 Денис Баранов 2009-10-03 16:00:35 MSD
WINE@Etersoft 1.0.11 eter8.5\eter5
Вывод предупреждения при не терминальной лицензии работает.
Comment 13 Денис Баранов 2010-04-15 09:33:47 MSD
-