char * __cdecl strerror ( int errnum ) { #ifdef _MT _ptiddata ptd = _getptd(); char *errmsg; static char errmsg_backup[_SYS_MSGMAX+2]; #else static char errmsg[_ERRMSGLEN_]; /* Longest errmsg + \0 */ #endif #ifdef _MT if ( (ptd->_errmsg == NULL) && ((ptd->_errmsg = _malloc_crt(_ERRMSGLEN_)) == NULL) ) errmsg = errmsg_backup; /* error: use backup */ else errmsg = ptd->_errmsg; #endif strcpy(errmsg, _sys_err_msg(errnum)); return(errmsg); }
static void _callthreadstart(void) { _ptiddata ptd; /* pointer to thread's _tiddata struct */ /* must always exist at this point */ ptd = _getptd(); /* * Guard call to user code with a _try - _except statement to * implement runtime errors and signal support */ __try { ( (void(__CLRCALL_OR_CDECL *)(void *))(((_ptiddata)ptd)->_initaddr) ) ( ((_ptiddata)ptd)->_initarg ); _endthread(); } __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) ) { /* * Should never reach here */ _exit( GetExceptionCode() ); } /* end of _try - _except */ }
void __cdecl _endthread ( void ) { _ptiddata ptd; /* pointer to thread's _tiddata struct */ /* * Call fp termination, if necessary */ if ( _FPmtterm != NULL ) (*_FPmtterm)(); if ( (ptd = _getptd()) == NULL ) _amsg_exit(_RT_THREAD); /* * Close the thread handle (if there was one) */ if ( ptd->_thandle != (unsigned long)(-1L) ) (void) CloseHandle( (HANDLE)(ptd->_thandle) ); /* * Free up the _tiddata structure & its subordinate buffers * _freeptd() will also clear the value for this thread * of the TLS variable __tlsindex. */ _freeptd(ptd); /* * Terminate the thread */ ExitThread(0); }
int __cdecl rand ( void ) { _ptiddata ptd = _getptd(); return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) & 0x7fff ); }
void __cdecl srand ( unsigned int seed ) { #ifdef _MT _getptd()->_holdrand = (unsigned long)seed; #else holdrand = (long)seed; #endif }
void _xceendthreadex (unsigned retcode) { _ptiddata ptd; if((ptd = _getptd()) == NULL) xceabort(); _freeptd(ptd); ExitThread(retcode); }
void _xceendthread (void) { _ptiddata ptd; if((ptd = _getptd()) == NULL ) xceabort(); if(ptd->_thandle != (unsigned long)(-1L)) CloseHandle((HANDLE)(ptd->_thandle)); _freeptd(ptd); ExitThread(0); }
int __cdecl rand ( void ) { #ifdef _MT _ptiddata ptd = _getptd(); return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) & 0x7fff ); #else return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff); #endif }
struct lconv * __cdecl localeconv ( void ) { /* * Note that we don't need _LocaleUpdate in this function. * The main reason being, that this is a leaf function in * locale usage terms. */ _ptiddata ptd = _getptd(); pthreadlocinfo ptloci = ptd->ptlocinfo; __UPDATE_LOCALE(ptd, ptloci); return(__lconv); }
char * __cdecl _strerror ( REG1 const char *message ) { #ifdef _MT _ptiddata ptd = _getptd(); char *bldmsg; #else /* _MT */ static char bldmsg[_ERRMSGLEN_]; #endif /* _MT */ #ifdef _MT /* Use per thread buffer area (malloc space, if necessary) */ /* [NOTE: This buffer is shared between _strerror and streror.] */ if ( (ptd->_errmsg == NULL) && ((ptd->_errmsg = _malloc_crt(_ERRMSGLEN_)) == NULL) ) return(NULL); bldmsg = ptd->_errmsg; #endif /* _MT */ /* Build the error message */ bldmsg[0] = '\0'; if (message && *message) { strcat( bldmsg, message ); strcat( bldmsg, ": " ); } strcat( bldmsg, _sys_err_msg( errno ) ); return( strcat( bldmsg, "\n" ) ); }
_MCRTIMP uintptr_t __cdecl _beginthread ( void (__CLRCALL_OR_CDECL * initialcode) (void *), unsigned stacksize, void * argument ) { _ptiddata ptd; /* pointer to per-thread data */ uintptr_t thdl; /* thread handle */ unsigned long err = 0L; /* Return from GetLastError() */ /* validation section */ _VALIDATE_RETURN(initialcode != NULL, EINVAL, -1); /* Initialize FlsGetValue function pointer */ __set_flsgetvalue(); /* * Allocate and initialize a per-thread data structure for the to- * be-created thread. */ if ( (ptd = (_ptiddata)_calloc_crt(1, sizeof(struct _tiddata))) == NULL ) { goto error_return; } /* * Initialize the per-thread data */ _initptd(ptd, _getptd()->ptlocinfo); ptd->_initaddr = (void *) initialcode; ptd->_initarg = argument; #if defined (_M_CEE) || defined (MRTDLL) if(!_getdomain(&(ptd->__initDomain))) { goto error_return; } #endif /* defined (_M_CEE) || defined (MRTDLL) */ /* * Create the new thread. Bring it up in a suspended state so that * the _thandle and _tid fields are filled in before execution * starts. */ if ( (ptd->_thandle = thdl = (uintptr_t) CreateThread( NULL, stacksize, _threadstart, (LPVOID)ptd, CREATE_SUSPENDED, (LPDWORD)&(ptd->_tid) )) == (uintptr_t)0 ) { err = GetLastError(); goto error_return; } /* * Start the new thread executing */ if ( ResumeThread( (HANDLE)thdl ) == (DWORD)(-1) ) { err = GetLastError(); goto error_return; } /* * Good return */ return(thdl); /* * Error return */ error_return: /* * Either ptd is NULL, or it points to the no-longer-necessary block * calloc-ed for the _tiddata struct which should now be freed up. */ _free_crt(ptd); /* * Map the error, if necessary. */ if ( err != 0L ) _dosmaperr(err); return( (uintptr_t)(-1) ); }
int __cdecl raise ( int signum ) { _PHNDLR sigact; _PHNDLR *psigact; PEXCEPTION_POINTERS oldpxcptinfoptrs; int oldfpecode; int indx; #ifdef _MT int siglock = 0; _ptiddata ptd; #endif /* _MT */ switch (signum) { case SIGINT: sigact = *(psigact = &ctrlc_action); #ifdef _MT siglock++; #endif /* _MT */ break; case SIGBREAK: sigact = *(psigact = &ctrlbreak_action); #ifdef _MT siglock++; #endif /* _MT */ break; case SIGABRT: sigact = *(psigact = &abort_action); #ifdef _MT siglock++; #endif /* _MT */ break; case SIGTERM: sigact = *(psigact = &term_action); #ifdef _MT siglock++; #endif /* _MT */ break; case SIGFPE: case SIGILL: case SIGSEGV: #ifdef _MT ptd = _getptd(); sigact = *(psigact = &(siglookup( signum, ptd->_pxcptacttab )->XcptAction)); #else /* _MT */ sigact = *(psigact = &(siglookup( signum )-> XcptAction)); #endif /* _MT */ break; default: /* * unsupported signal, return an error */ return (-1); } #ifdef _MT /* * if signum is one of the 'process-wide' signals (i.e., SIGINT, * SIGBREAK, SIGABRT or SIGTERM), assert _SIGNAL_LOCK. */ if ( siglock ) _mlock(_SIGNAL_LOCK); #endif /* _MT */ /* * If the current action is SIG_IGN, just return */ if ( sigact == SIG_IGN ) { #ifdef _MT if ( siglock ) _munlock(_SIGNAL_LOCK); #endif /* _MT */ return(0); } /* * If the current action is SIG_DFL, take the default action */ if ( sigact == SIG_DFL ) { #ifdef _MT if ( siglock ) _munlock(_SIGNAL_LOCK); #endif /* _MT */ /* * The current default action for all of the supported * signals is to terminate with an exit code of 3. * */ _exit(3); } /* * From here on, sigact is assumed to be a pointer to a user-supplied * handler. */ /* * For signals which correspond to exceptions, set the pointer * to the EXCEPTION_POINTERS structure to NULL */ if ( (signum == SIGFPE) || (signum == SIGSEGV) || (signum == SIGILL) ) { #ifdef _MT oldpxcptinfoptrs = ptd->_tpxcptinfoptrs; ptd->_tpxcptinfoptrs = NULL; #else /* _MT */ oldpxcptinfoptrs = _pxcptinfoptrs; _pxcptinfoptrs = NULL; #endif /* _MT */ /* * If signum is SIGFPE, also set _fpecode to * _FPE_EXPLICITGEN */ if ( signum == SIGFPE ) { #ifdef _MT oldfpecode = ptd->_tfpecode; ptd->_tfpecode = _FPE_EXPLICITGEN; #else /* _MT */ oldfpecode = _fpecode; _fpecode = _FPE_EXPLICITGEN; #endif /* _MT */ } } /* * Reset the action to SIG_DFL and call the user specified handler * routine. */ if ( signum == SIGFPE ) /* * for SIGFPE, must reset the action for all of the floating * point exceptions */ for ( indx = _First_FPE_Indx ; indx < _First_FPE_Indx + _Num_FPE ; indx++ ) { #ifdef _MT ( (struct _XCPT_ACTION *)(ptd->_pxcptacttab) + indx )->XcptAction = SIG_DFL; #else /* _MT */ _XcptActTab[indx].XcptAction = SIG_DFL; #endif /* _MT */ } else *psigact = SIG_DFL; #ifdef _MT if ( siglock ) _munlock(_SIGNAL_LOCK); #endif /* _MT */ if ( signum == SIGFPE ) /* * Special code to support old SIGFPE handlers which * expect the value of _fpecode as the second argument. */ #ifdef _MT (*(void (__cdecl *)(int,int))sigact)(SIGFPE, ptd->_tfpecode); #else /* _MT */ (*(void (__cdecl *)(int,int))sigact)(SIGFPE, _fpecode); #endif /* _MT */ else
_PHNDLR __cdecl signal( int signum, _PHNDLR sigact ) { struct _XCPT_ACTION *pxcptact; _PHNDLR oldsigact; #ifdef _MT _ptiddata ptd; #endif /* _MT */ /* * Check for values of sigact supported on other platforms but not * on this one. Also, make sure sigact is not SIG_DIE */ if ( (sigact == SIG_ACK) || (sigact == SIG_SGE) ) goto sigreterror; /* * Take care of all signals which do not correspond to exceptions * in the host OS. Those are: * * SIGINT * SIGBREAK * SIGABRT * SIGTERM * */ if ( (signum == SIGINT) || (signum == SIGBREAK) || (signum == SIGABRT) || (signum == SIGTERM) ) { _mlock(_SIGNAL_LOCK); /* * if SIGINT or SIGBREAK, make sure the handler is installed * to capture ^C and ^Break events. */ if ( ((signum == SIGINT) || (signum == SIGBREAK)) && !ConsoleCtrlHandler_Installed ) if ( SetConsoleCtrlHandler(ctrlevent_capture, TRUE) == TRUE ) ConsoleCtrlHandler_Installed = TRUE; else { _doserrno = GetLastError(); _munlock(_SIGNAL_LOCK); goto sigreterror; } switch (signum) { case SIGINT: oldsigact = ctrlc_action; ctrlc_action = sigact; break; case SIGBREAK: oldsigact = ctrlbreak_action; ctrlbreak_action = sigact; break; case SIGABRT: oldsigact = abort_action; abort_action = sigact; break; case SIGTERM: oldsigact = term_action; term_action = sigact; break; } _munlock(_SIGNAL_LOCK); goto sigretok; } /* * If we reach here, signum is supposed to be one the signals which * correspond to exceptions in the host OS. Those are: * * SIGFPE * SIGILL * SIGSEGV */ /* * Make sure signum is one of the remaining supported signals. */ if ( (signum != SIGFPE) && (signum != SIGILL) && (signum != SIGSEGV) ) goto sigreterror; #ifdef _MT /* * Fetch the tid data table entry for this thread */ ptd = _getptd(); /* * Check that there a per-thread instance of the exception-action * table for this thread. if there isn't, create one. */ if ( ptd->_pxcptacttab == _XcptActTab ) /* * allocate space for an exception-action table */ if ( (ptd->_pxcptacttab = _malloc_crt(_XcptActTabSize)) != NULL ) /* * initialize the table by copying over the contents * of _XcptActTab[] */ (void) memcpy(ptd->_pxcptacttab, _XcptActTab, _XcptActTabSize); else /* * cannot create exception-action table, return * error to caller */ goto sigreterror; #endif /* _MT */ /* * look up the proper entry in the exception-action table. note that * if several exceptions are mapped to the same signal, this returns * the pointer to first such entry in the exception action table. it * is assumed that the other entries immediately follow this one. */ #ifdef _MT if ( (pxcptact = siglookup(signum, ptd->_pxcptacttab)) == NULL ) #else /* _MT */ if ( (pxcptact = siglookup(signum)) == NULL ) #endif /* _MT */ goto sigreterror; /* * SIGSEGV, SIGILL and SIGFPE all have more than one exception mapped * to them. the code below depends on the exceptions corresponding to * the same signal being grouped together in the exception-action * table. */ /* * store old signal action code for return value */ oldsigact = pxcptact->XcptAction; /* * loop through all entries corresponding to the * given signal and update the SigAction and XcptAction * fields as appropriate */ while ( pxcptact->SigNum == signum ) { /* * take care of the SIG_IGN and SIG_DFL action * codes */ pxcptact->XcptAction = sigact; /* * make sure we don't run off the end of the table */ #ifdef _MT if ( ++pxcptact >= ((struct _XCPT_ACTION *)(ptd->_pxcptacttab) + _XcptActTabCount) ) #else /* _MT */ if ( ++pxcptact >= (_XcptActTab + _XcptActTabCount) ) #endif /* _MT */ break; } sigretok: return(oldsigact); sigreterror: errno = EINVAL; return(SIG_ERR); }
unsigned long * __cdecl __doserrno( void ) { return ( &(_getptd()->_tdoserrno) ); }
int * __cdecl _errno( void ) { return ( &(_getptd()->_terrno) ); }
struct tm * __cdecl gmtime ( const time_t *timp ) { long caltim = *timp; /* calendar time to convert */ int islpyr = 0; /* is-current-year-a-leap-year flag */ REG1 int tmptim; REG3 int *mdays; /* pointer to days or lpdays */ #ifdef _MT REG2 struct tm *ptb; /* will point to gmtime buffer */ _ptiddata ptd = _getptd(); #else /* _MT */ REG2 struct tm *ptb = &tb; #endif /* _MT */ if ( caltim < 0L ) return(NULL); #ifdef _MT /* Use per thread buffer area (malloc space, if necessary) */ if ( (ptd->_gmtimebuf != NULL) || ((ptd->_gmtimebuf = _malloc_crt(sizeof(struct tm))) != NULL) ) ptb = ptd->_gmtimebuf; else ptb = &tb; /* malloc error: use static buffer */ #endif /* _MT */ /* * Determine years since 1970. First, identify the four-year interval * since this makes handling leap-years easy (note that 2000 IS a * leap year and 2100 is out-of-range). */ tmptim = (int)(caltim / _FOUR_YEAR_SEC); caltim -= ((long)tmptim * _FOUR_YEAR_SEC); /* * Determine which year of the interval */ tmptim = (tmptim * 4) + 70; /* 1970, 1974, 1978,...,etc. */ if ( caltim >= _YEAR_SEC ) { tmptim++; /* 1971, 1975, 1979,...,etc. */ caltim -= _YEAR_SEC; if ( caltim >= _YEAR_SEC ) { tmptim++; /* 1972, 1976, 1980,...,etc. */ caltim -= _YEAR_SEC; /* * Note, it takes 366 days-worth of seconds to get past a leap * year. */ if ( caltim >= (_YEAR_SEC + _DAY_SEC) ) { tmptim++; /* 1973, 1977, 1981,...,etc. */ caltim -= (_YEAR_SEC + _DAY_SEC); } else { /* * In a leap year after all, set the flag. */ islpyr++; } } } /* * tmptim now holds the value for tm_year. caltim now holds the * number of elapsed seconds since the beginning of that year. */ ptb->tm_year = tmptim; /* * Determine days since January 1 (0 - 365). This is the tm_yday value. * Leave caltim with number of elapsed seconds in that day. */ ptb->tm_yday = (int)(caltim / _DAY_SEC); caltim -= (long)(ptb->tm_yday) * _DAY_SEC; /* * Determine months since January (0 - 11) and day of month (1 - 31) */ if ( islpyr ) mdays = _lpdays; else mdays = _days; for ( tmptim = 1 ; mdays[tmptim] < ptb->tm_yday ; tmptim++ ) ; ptb->tm_mon = --tmptim; ptb->tm_mday = ptb->tm_yday - mdays[tmptim]; /* * Determine days since Sunday (0 - 6) */ ptb->tm_wday = ((int)(*timp / _DAY_SEC) + _BASE_DOW) % 7; /* * Determine hours since midnight (0 - 23), minutes after the hour * (0 - 59), and seconds after the minute (0 - 59). */ ptb->tm_hour = (int)(caltim / 3600); caltim -= (long)ptb->tm_hour * 3600L; ptb->tm_min = (int)(caltim / 60); ptb->tm_sec = (int)(caltim - (ptb->tm_min) * 60); ptb->tm_isdst = 0; return( (struct tm *)ptb ); }
char * __cdecl strtok ( char * string, const char * control ) { unsigned char *str; const unsigned char *ctrl = control; unsigned char map[32]; int count; #ifdef _MT _ptiddata ptd = _getptd(); #else static char *nextoken; #endif /* Clear control map */ for (count = 0; count < 32; count++) map[count] = 0; /* Set bits in delimiter table */ do { map[*ctrl >> 3] |= (1 << (*ctrl & 7)); } while (*ctrl++); /* Initialize str. If string is NULL, set str to the saved * pointer (i.e., continue breaking tokens out of the string * from the last strtok call) */ if (string) str = string; else #ifdef _MT str = ptd->_token; #else str = nextoken; #endif /* Find beginning of token (skip over leading delimiters). Note that * there is no token iff this loop sets str to point to the terminal * null (*str == '\0') */ while ( (map[*str >> 3] & (1 << (*str & 7))) && *str ) str++; string = str; /* Find the end of the token. If it is not the end of the string, * put a null there. */ for ( ; *str ; str++ ) if ( map[*str >> 3] & (1 << (*str & 7)) ) { *str++ = '\0'; break; } /* Update nextoken (or the corresponding field in the per-thread data * structure */ #ifdef _MT ptd->_token = str; #else nextoken = str; #endif /* Determine if a token has been found. */ if ( string == str ) return NULL; else return string; }
void __cdecl srand( unsigned int seed ) { _getptd()->_holdrand = (unsigned long)seed; }
/* now define version that doesn't lock/unlock, validate fh */ int __cdecl _write_nolock ( int fh, const void *buf, unsigned cnt ) { int lfcount; /* count of line feeds */ int charcount; /* count of chars written so far */ int written; /* count of chars written on this write */ ULONG dosretval; /* o.s. return value */ char tmode ; /* textmode - ANSI or UTF-16 */ BOOL toConsole = 0; /* true when writing to console */ BOOL isCLocale = 0; /* true when locale handle is C locale */ lfcount = charcount = 0; /* nothing written yet */ if (cnt == 0) return 0; /* nothing to do */ _VALIDATE_CLEAR_OSSERR_RETURN( (buf != NULL), EINVAL, -1 ); tmode = _textmode(fh); if(tmode == __IOINFO_TM_UTF16LE || tmode == __IOINFO_TM_UTF8) { /* For a UTF-16 file, the count must always be an even number */ _VALIDATE_CLEAR_OSSERR_RETURN(((cnt & 1) == 0), EINVAL, -1); } if (_osfile(fh) & FAPPEND) { /* appending - seek to end of file; ignore error, because maybe file doesn't allow seeking */ #if _INTEGRAL_MAX_BITS >= 64 (void)_lseeki64_nolock(fh, 0, FILE_END); #else /* _INTEGRAL_MAX_BITS >= 64 */ (void)_lseek_nolock(fh, 0, FILE_END); #endif /* _INTEGRAL_MAX_BITS >= 64 */ } /* check for text mode with LF's in the buffer */ /* * Note that in case the handle belongs to Console, write file will * generate garbage output. For user to print these characters * correctly, we will need to print ANSI. * * Also note that in case of printing to Console, we still have to * convert the characters to console codepage. */ if (_isatty(fh) && (_osfile(fh) & FTEXT)) { DWORD dwMode; _ptiddata ptd = _getptd(); isCLocale = (ptd->ptlocinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE); toConsole = GetConsoleMode((HANDLE)_osfhnd(fh), &dwMode); } /* don't need double conversion if it's ANSI mode C locale */ if (toConsole && !(isCLocale && (tmode == __IOINFO_TM_ANSI))) { UINT consoleCP = GetConsoleCP(); char mboutbuf[MB_LEN_MAX]; wchar_t tmpchar; int size = 0; int written = 0; char *pch; for (pch = (char *)buf; (unsigned)(pch - (char *)buf) < cnt; ) { BOOL bCR; if (tmode == __IOINFO_TM_ANSI) { bCR = *pch == LF; /* * Here we need to do double convert. i.e. convert from * multibyte to unicode and then from unicode to multibyte in * Console codepage. */ if (!isleadbyte(*pch)) { if (mbtowc(&tmpchar, pch, 1) == -1) { break; } } else if ((cnt - (pch - (char*)buf)) > 1) { if (mbtowc(&tmpchar, pch, 2) == -1) { break; } /* * Increment pch to accomodate DBCS character. */ ++pch; } else { break; } ++pch; } else if (tmode == __IOINFO_TM_UTF8 || tmode == __IOINFO_TM_UTF16LE) { /* * Note that bCR set above is not valid in case of UNICODE * stream. We need to set it using unicode character. */ tmpchar = *(wchar_t *)pch; bCR = tmpchar == LF; pch += 2; } if (tmode == __IOINFO_TM_ANSI) { if( (size = WideCharToMultiByte(consoleCP, 0, &tmpchar, 1, mboutbuf, sizeof(mboutbuf), NULL, NULL)) == 0) { break; } else { if ( WriteFile( (HANDLE)_osfhnd(fh), mboutbuf, size, (LPDWORD)&written, NULL) ) { charcount += written; if (written < size) break; } else { dosretval = GetLastError(); break; } } if (bCR) { size = 1; mboutbuf[0] = CR; if (WriteFile((HANDLE)_osfhnd(fh), mboutbuf, size, (LPDWORD)&written, NULL) ) { if (written < size) break; lfcount ++; charcount++; } else { dosretval = GetLastError(); break; } } } else if ( tmode == __IOINFO_TM_UTF8 || tmode == __IOINFO_TM_UTF16LE) { if ( _putwch_nolock(tmpchar) == tmpchar ) { charcount++; } else { dosretval = GetLastError(); break; } if (bCR) /* emit carriage return */ { size = 1; tmpchar = CR; if ( _putwch_nolock(tmpchar) == tmpchar ) { charcount++; lfcount++; } else { dosretval = GetLastError(); break; } } } } } else if ( _osfile(fh) & FTEXT ) { /* text mode, translate LF's to CR/LF's on output */ dosretval = 0; /* no OS error yet */ if(tmode == __IOINFO_TM_ANSI) { char ch; /* current character */ char *p = NULL, *q = NULL; /* pointers into buf and lfbuf resp. */ char lfbuf[BUF_SIZE]; p = (char *)buf; /* start at beginning of buffer */ while ( (unsigned)(p - (char *)buf) < cnt ) { q = lfbuf; /* start at beginning of lfbuf */ /* fill the lf buf, except maybe last char */ while ( q - lfbuf < sizeof(lfbuf) - 1 && (unsigned)(p - (char *)buf) < cnt ) { ch = *p++; if ( ch == LF ) { ++lfcount; *q++ = CR; } *q++ = ch; } /* write the lf buf and update total */ if ( WriteFile( (HANDLE)_osfhnd(fh), lfbuf, (int)(q - lfbuf), (LPDWORD)&written, NULL) ) { charcount += written; if (written < q - lfbuf) break; } else { dosretval = GetLastError(); break; } } } else if ( tmode == __IOINFO_TM_UTF16LE ){ char lfbuf[BUF_SIZE]; wchar_t wch; /* current wide char */ wchar_t *pu = (wchar_t *)buf; wchar_t *qu = NULL; while ( (unsigned)((char *)pu - (char *)buf) < cnt ) { qu = (wchar_t *)lfbuf; /* start at beginning of lfbuf */ /* fill the lf buf, except maybe last wchar_t */ while ( (((char *)qu - lfbuf) < (sizeof(lfbuf) - 2)) && ((unsigned)((char *)pu - (char *)buf) < cnt )) { wch = *pu++; if ( wch == LF ) { lfcount+=2; *qu++ = CR; } *qu++ = wch; } /* write the lf buf and update total */ if ( WriteFile( (HANDLE)_osfhnd(fh), lfbuf, (int)((char*)qu - lfbuf), (LPDWORD)&written, NULL) ) { charcount += written; if (written < ((char *)qu - lfbuf)) break; } else { dosretval = GetLastError(); break; } } } else { /* * Let's divide the lfbuf in 1:2 wher 1 is for storing * widecharacters and 2 if for converting it to UTF8. This takes * into account the worst case scenario where all the UTF8 * characters are 4 byte long. */ char utf8_buf[(BUF_SIZE*2)/3]; wchar_t utf16_buf[BUF_SIZE/6]; wchar_t wch; /* current wide char */ wchar_t *pu = (wchar_t *)buf; wchar_t *qu = NULL; pu = (wchar_t *)buf; while ((unsigned)((char *)pu - (char *)buf) < cnt) { int bytes_converted = 0; qu = utf16_buf; /* start at beginning of lfbuf */ while ( (((char *)qu - (char *)utf16_buf) < (sizeof(utf16_buf) - 2)) && ((unsigned)((char *)pu - (char *)buf) < cnt )) { wch = *pu++; if ( wch == LF ) { /* no need to count the linefeeds here: we calculate the written chars in another way */ *qu++ = CR; } *qu++ = wch; } bytes_converted = WideCharToMultiByte( CP_UTF8, 0, utf16_buf, ((int)((char *)qu - (char *)utf16_buf))/2, utf8_buf, sizeof(utf8_buf), NULL, NULL); if (bytes_converted == 0) { dosretval = GetLastError(); break; } else { /* * Here we need to make every attempt to write all the * converted characters. The resaon behind this is, * incase half the bytes of a UTF8 character is * written, it may currupt whole of the stream or file. * * The loop below will make sure we exit only if all * the bytes converted are written (which makes sure no * partial MBCS is written) or there was some error in * the stream. */ int bytes_written = 0; do { if (WriteFile( (HANDLE)_osfhnd(fh), utf8_buf + bytes_written, bytes_converted - bytes_written, &written, NULL)) { bytes_written += written; } else { dosretval = GetLastError(); break; } } while ( bytes_converted > bytes_written); /* * Only way the condition below could be true is if * there was en error. In case of error we need to * break this loop as well. */ if (bytes_converted > bytes_written) { break; } /* if this chunk has been committed successfully, update charcount */ charcount = (int)((char *)pu - (char *)buf); } } } } else { /* binary mode, no translation */ if ( WriteFile( (HANDLE)_osfhnd(fh), (LPVOID)buf, cnt, (LPDWORD)&written, NULL) ) { dosretval = 0; charcount = written; } else dosretval = GetLastError(); } if (charcount == 0) { /* If nothing was written, first check if an o.s. error, otherwise we return -1 and set errno to ENOSPC, unless a device and first char was CTRL-Z */ if (dosretval != 0) { /* o.s. error happened, map error */ if (dosretval == ERROR_ACCESS_DENIED) { /* wrong read/write mode should return EBADF, not EACCES */ errno = EBADF; _doserrno = dosretval; } else _dosmaperr(dosretval); return -1; } else if ((_osfile(fh) & FDEV) && *(char *)buf == CTRLZ) return 0; else { errno = ENOSPC; _doserrno = 0; /* no o.s. error */ return -1; } } else /* return adjusted bytes written */ return charcount - lfcount; }
{ LPVOID v2; // eax@1 LPVOID v3; // esi@1 int v4; // eax@1 void (__cdecl *v5)(_DWORD); // edx@2 LONG result; // eax@4 int v7; // edi@7 int v8; // ebx@8 int v9; // ecx@9 int v10; // ebx@11 int v11; // eax@11 v2 = _getptd(); v3 = v2; v4 = xcptlookup(a1, *((_DWORD *)v2 + 20)); if ( v4 && (v5 = *(void (__cdecl **)(_DWORD))(v4 + 8)) != 0 ) { if ( v5 == (void (__cdecl *)(_DWORD))5 ) { *(_DWORD *)(v4 + 8) = 0; result = 1; } else { if ( v5 == (void (__cdecl *)(_DWORD))1 ) { result = -1; } else { v7 = *((_DWORD *)v3 + 21);
wchar_t * __cdecl wcstok ( wchar_t * string, const wchar_t * control ) { wchar_t *token; const wchar_t *ctl; #ifdef _MT _ptiddata ptd = _getptd(); #else /* _MT */ static wchar_t *nextoken; #endif /* _MT */ /* If string==NULL, continue with previous string */ if (!string) #ifdef _MT string = ptd->_wtoken; #else /* _MT */ string = nextoken; #endif /* _MT */ /* Find beginning of token (skip over leading delimiters). Note that * there is no token iff this loop sets string to point to the terminal * null (*string == '\0') */ while (*string) { for (ctl=control; *ctl && *ctl != *string; ctl++) ; if (!*ctl) break; string++; } token = string; /* Find the end of the token. If it is not the end of the string, * put a null there. */ for ( ; *string ; string++ ) { for (ctl=control; *ctl && *ctl != *string; ctl++) ; if (*ctl) { *string++ = '\0'; break; } } /* Update nextoken (or the corresponding field in the per-thread data * structure */ #ifdef _MT ptd->_wtoken = string; #else /* _MT */ nextoken = string; #endif /* _MT */ /* Determine if a token has been found. */ if ( token == string ) return NULL; else return token; }