Hi, glibc 2.3.current CVS is throwing a huge stone in our direction, it no longer allows overload of __errno_location. To visualize this problem I have added this testcase. I will try to find a way to make our errno handling work again :/ linux only. Ciao, Marcus Changelog: Added testcase for multithread safe errno. Index: dlls/kernel/tests/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/kernel/tests/Makefile.in,v retrieving revision 1.6 diff -u -r1.6 Makefile.in --- dlls/kernel/tests/Makefile.in 4 Oct 2002 17:42:27 -0000 1.6 +++ dlls/kernel/tests/Makefile.in 22 Jan 2003 09:34:15 -0000 @@ -12,6 +12,7 @@ directory.c \ drive.c \ environ.c \ + errno.c \ file.c \ format_msg.c \ generated.c \
/* * Errno testing. * * Copyright 2003 Marcus Meissner * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <wine/test.h> #include <windef.h> #include <winbase.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> /* * This test is just to check that errno is thread safe. * We cannot use config.h, so *BSD and other platforms will want * to add other ifdefs. */ #if defined(linux) #include <sched.h> void WINAPI errnotest1(void *x) { struct stat stbuf; int cnt = 100; while (cnt--) { if (-1!=lstat("/not/existant/file",&stbuf)) return; sched_yield(); /* will not change errno */ if (errno != ENOENT) { ok(errno==ENOENT,"errno did not stay at ENOENT for non existing file, changed to %d\n", errno); return; } } ok(1==1,"Errno stayed the same over the whole run.\n"); } void WINAPI errnotest2(void *x) { int cnt = 100; close(333); while (cnt--) { close(333); sched_yield(); /* will not change errno */ if (errno != EBADF) { ok(errno==EBADF,"errno did not stay at EBADF for close of bad fd, changed to %d\n", errno); return; } } ok(1==1,"Errno stayed the same over the whole run.\n"); } START_TEST(errno) { DWORD threadId; HANDLE ht[2]; ht[0]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)errnotest1,NULL,0,&threadId); ht[1]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)errnotest2,NULL,0,&threadId); WaitForMultipleObjects(2,ht,TRUE,INFINITE); } #else START_TEST(errno) { /* nothing */ } #endif