#define _CRTIMP #include #include #include "internal.h" /*** * Copy of MS functions _lock_file, _unlock_file which are missing from * msvcrt.dll and msvcr80.dll. They are needed to atomic/lock stdio * functions (printf, fprintf, vprintf, vfprintf). We need exactly the same * lock that MS uses in msvcrt.dll because we can mix mingw-w64 code with * original MS functions (puts, fputs for example). ***/ _CRTIMP void __cdecl _lock(int locknum); _CRTIMP void __cdecl _unlock(int locknum); #define _STREAM_LOCKS 16 #define _IOLOCKED 0x8000 /*** * _lock_file - Lock a FILE * *Purpose: * Assert the lock for a stdio-level file * *Entry: * pf = __piob[] entry (pointer to a FILE or _FILEX) * *Exit: * *Exceptions: * *******************************************************************************/ void __cdecl _lock_file( FILE *pf ) { /* * The way the FILE (pointed to by pf) is locked depends on whether * it is part of _iob[] or not */ if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) ) { /* * FILE lies in _iob[] so the lock lies in _locktable[]. */ _lock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) ); /* We set _IOLOCKED to indicate we locked the stream */ pf->_flag |= _IOLOCKED; } else /* * Not part of _iob[]. Therefore, *pf is a _FILEX and the * lock field of the struct is an initialized critical * section. */ EnterCriticalSection( &(((_FILEX *)pf)->lock) ); } void *__MINGW_IMP_SYMBOL(_lock_file) = _lock_file; /*** * _unlock_file - Unlock a FILE * *Purpose: * Release the lock for a stdio-level file * *Entry: * pf = __piob[] entry (pointer to a FILE or _FILEX) * *Exit: * *Exceptions: * *******************************************************************************/ void __cdecl _unlock_file( FILE *pf ) { /* * The way the FILE (pointed to by pf) is unlocked depends on whether * it is part of _iob[] or not */ if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) ) { /* * FILE lies in _iob[] so the lock lies in _locktable[]. * We reset _IOLOCKED to indicate we unlock the stream. */ pf->_flag &= ~_IOLOCKED; _unlock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) ); } else /* * Not part of _iob[]. Therefore, *pf is a _FILEX and the * lock field of the struct is an initialized critical * section. */ LeaveCriticalSection( &(((_FILEX *)pf)->lock) ); } void *__MINGW_IMP_SYMBOL(_unlock_file) = _unlock_file;