mkdir и last error
От: slavo  
Дата: 13.09.07 07:55
Оценка:
День добрый,

функция mkdir согласно MSDN выставляет ошибку в переменную errno. Но на практике выясняется, то она выставляет ошибку еще и в last error. Как это объяснить? В MSDN про это не сказано и если я обнуляю last error где-то до вызова mkdir, а потом ее вызываю, то оказывается, что last error уже не 0, а по документации — ноль.
Re: mkdir и last error
От: Pavel Dvorkin Россия  
Дата: 13.09.07 08:32
Оценка: 4 (1)
Здравствуйте, slavo, Вы писали:

S>День добрый,


S>функция mkdir согласно MSDN выставляет ошибку в переменную errno. Но на практике выясняется, то она выставляет ошибку еще и в last error. Как это объяснить? В MSDN про это не сказано и если я обнуляю last error где-то до вызова mkdir, а потом ее вызываю, то оказывается, что last error уже не 0, а по документации — ноль.


Все правильно


int __cdecl _tmkdir (
        const _TSCHAR *path
        )
{
        ULONG dosretval;

        /* ask OS to create directory */

        if (!CreateDirectory((LPTSTR)path, (LPSECURITY_ATTRIBUTES)NULL))
            dosretval = GetLastError();
        else
            dosretval = 0;

        if (dosretval) {
            /* error occured -- map error code and return */
            _dosmaperr(dosretval);
            return -1;
        }

        return 0;
}


Вот CreateDirectory тебе и устроила SetLastError. А что же ей еще делать-то ? :-)
With best regards
Pavel Dvorkin
Re[2]: mkdir и last error
От: slavo  
Дата: 13.09.07 09:37
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, slavo, Вы писали:


S>>День добрый,


S>>функция mkdir согласно MSDN выставляет ошибку в переменную errno. Но на практике выясняется, то она выставляет ошибку еще и в last error. Как это объяснить? В MSDN про это не сказано и если я обнуляю last error где-то до вызова mkdir, а потом ее вызываю, то оказывается, что last error уже не 0, а по документации — ноль.


PD>Все правильно



PD>
PD>int __cdecl _tmkdir (
PD>        const _TSCHAR *path
PD>        )
PD>{
PD>        ULONG dosretval;

PD>        /* ask OS to create directory */

PD>        if (!CreateDirectory((LPTSTR)path, (LPSECURITY_ATTRIBUTES)NULL))
PD>            dosretval = GetLastError();
PD>        else
PD>            dosretval = 0;

PD>        if (dosretval) {
PD>            /* error occured -- map error code and return */
PD>            _dosmaperr(dosretval);
PD>            return -1;
PD>        }

PD>        return 0;
PD>}


PD>Вот CreateDirectory тебе и устроила SetLastError. А что же ей еще делать-то ? :-)
PD>


А это откуда? У меня в mkdir.c вот что написано:
int __cdecl _mkdir (
        const char *path
        )
{
        /* ask OS to create directory */
        HParamBlockRec hparamBlock;
        char st[256];
        OSErr osErr;

        if (!*path)
        {
            errno = ENOENT;
            return -1;
        }
        strcpy(st, path);
        hparamBlock.fileParam.ioNamePtr = _c2pstr(st);
        hparamBlock.fileParam.ioVRefNum = 0;
        hparamBlock.fileParam.ioDirID = 0;
        osErr = PBDirCreateSync(&hparamBlock);
        if (osErr) {
            /* error occured -- map error code and return */
            _dosmaperr(osErr);
            return -1;
        }

        return 0;
}
Re[3]: mkdir и last error
От: Erop Россия  
Дата: 13.09.07 09:58
Оценка:
Здравствуйте, slavo, Вы писали:

S>>>функция mkdir согласно MSDN выставляет ошибку в переменную errno.


S>А это откуда? У меня в mkdir.c вот что написано:

S>
S>int __cdecl _mkdir (
S>        const char *path
S>        )
S>{
S>        /* ask OS to create directory */
S>        HParamBlockRec hparamBlock;
S>        char st[256];
S>        OSErr osErr;

S>        if (!*path)
S>        {
S>            errno = ENOENT;
S>            return -1;
S>        }
S>        strcpy(st, path);
S>        hparamBlock.fileParam.ioNamePtr = _c2pstr(st);
S>        hparamBlock.fileParam.ioVRefNum = 0;
S>        hparamBlock.fileParam.ioDirID = 0;
S>        osErr = PBDirCreateSync(&hparamBlock);
S>        if (osErr) {
S>            /* error occured -- map error code and return */
S>            _dosmaperr(osErr);
S>            return -1;
S>        }

S>        return 0;
S>}
S>


А какая связь между MSDN и MAC OS?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: mkdir и last error
От: slavo  
Дата: 13.09.07 10:04
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, slavo, Вы писали:


S>>>>функция mkdir согласно MSDN выставляет ошибку в переменную errno.


S>>А это откуда? У меня в mkdir.c вот что написано:

S>>
S>>int __cdecl _mkdir (
S>>        const char *path
S>>        )
S>>{
S>>        /* ask OS to create directory */
S>>        HParamBlockRec hparamBlock;
S>>        char st[256];
S>>        OSErr osErr;

S>>        if (!*path)
S>>        {
S>>            errno = ENOENT;
S>>            return -1;
S>>        }
S>>        strcpy(st, path);
S>>        hparamBlock.fileParam.ioNamePtr = _c2pstr(st);
S>>        hparamBlock.fileParam.ioVRefNum = 0;
S>>        hparamBlock.fileParam.ioDirID = 0;
S>>        osErr = PBDirCreateSync(&hparamBlock);
S>>        if (osErr) {
S>>            /* error occured -- map error code and return */
S>>            _dosmaperr(osErr);
S>>            return -1;
S>>        }

S>>        return 0;
S>>}
S>>


E>А какая связь между MSDN и MAC OS?


да я уже понял, что тупанул. Удалил сообщение, а оно не удаляется
Re: mkdir и last error
От: Кодт Россия  
Дата: 13.09.07 11:14
Оценка: 2 (1)
Здравствуйте, slavo, Вы писали:

S>функция mkdir согласно MSDN выставляет ошибку в переменную errno. Но на практике выясняется, то она выставляет ошибку еще и в last error. Как это объяснить? В MSDN про это не сказано и если я обнуляю last error где-то до вызова mkdir, а потом ее вызываю, то оказывается, что last error уже не 0, а по документации — ноль.


Глобальные переменные с кодами ошибок — что сишная errno, что виндовая LastError — это очень плохой способ единственной диагностики.
Во всяком случае, проверять коды нужно немедленно после той функции, в документации по которой сказано, что она их устанавливает.
В промежутке между установкой и проверкой могут быть функции, в документации по которым сказано, что они их не трогают — или, по крайней мере, об этом говорит здравый смысл.

А то, что mkdir, обращаясь к ОС, будет прикладывать усилия по неизменению ОСовской переменной... а зачем?

И кстати: зачем смешивать диагностику по errno и по LastError?

Ну а если уж совсем припёрло, то
class KeepLastError
{
    DWORD code;
public:
    KeepLastError() : code(GetLastError()) {}
    ~KeepLastError() { SetLastError(code); }
};

.....
void foo()
{    // восстановит по выходу из блока
    KeepLastError guard;
    .....
    int ok = mkdir("c:\\foo");
    .....
}

void bar()
{
    .....
    int ok = KeepLastError(), mkdir("c:\\bar"); // восстановит по выходу из выражения
    .....
}
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.