Здравствуйте, 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. А что же ей еще делать-то ? :-)
Здравствуйте, 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;
}
Здравствуйте, 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?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, 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?
да я уже понял, что тупанул. Удалил сообщение, а оно не удаляется
Здравствуйте, 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>>