void __cdecl _getbuf ( FILE *str ) { REG1 FILE *stream; _ASSERTE(str != NULL); #if !defined (CRTDLL) /* force library pre-termination procedure */ _cflush++; #endif /* !defined (CRTDLL) */ /* Init pointers */ stream = str; /* Try to get a big buffer */ #ifdef _WIN32 if (stream->_base = _malloc_crt(_INTERNAL_BUFSIZ)) #else /* _WIN32 */ #if defined (_M_MPPC) || defined (_M_M68K) if (stream->_base = _malloc_crt(BUFSIZ)) #endif /* defined (_M_MPPC) || defined (_M_M68K) */ #endif /* _WIN32 */ { /* Got a big buffer */ stream->_flag |= _IOMYBUF; #ifdef _WIN32 stream->_bufsiz = _INTERNAL_BUFSIZ; #else /* _WIN32 */ #if defined (_M_MPPC) || defined (_M_M68K) stream->_bufsiz = BUFSIZ; #endif /* defined (_M_MPPC) || defined (_M_M68K) */ #endif /* _WIN32 */ } else { /* Did NOT get a buffer - use single char buffering. */ stream->_flag |= _IONBF; stream->_base = (char *)&(stream->_charbuf); #ifdef _WIN32 stream->_bufsiz = 2; #else /* _WIN32 */ #if defined (_M_MPPC) || defined (_M_M68K) stream->_bufsiz = 1; #endif /* defined (_M_MPPC) || defined (_M_M68K) */ #endif /* _WIN32 */ } stream->_ptr = stream->_base; stream->_cnt = 0; return; }
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); }
int __cdecl __mbtow_environ ( void ) { int size; wchar_t *wenvp; char **envp = _environ; /* * For every environment variable in the multibyte environment, * convert it and add it to the wide environment. */ while (*envp) { /* find out how much space is needed */ if ((size = MultiByteToWideChar(CP_OEMCP, 0, *envp, -1, NULL, 0)) == 0) return -1; /* allocate space for variable */ if ((wenvp = (wchar_t *) _malloc_crt(size * sizeof(wchar_t))) == NULL) return -1; /* convert it */ if ((size = MultiByteToWideChar(CP_OEMCP, 0, *envp, -1, wenvp, size)) == 0) return -1; /* set it - this is not primary call, so set primary == 0 */ __crtwsetenv(wenvp, 0); envp++; } return 0; }
_TSCHAR ** __cdecl _capture_argv( #endif va_list *arglist, const _TSCHAR *firstarg, _TSCHAR **static_argv, size_t max_static_entries ) { _TSCHAR ** argv; _TSCHAR * nextarg; size_t i; size_t max_entries; nextarg = (_TSCHAR *)firstarg; argv = static_argv; max_entries = max_static_entries; i = 0; for (;;) { if (i >= max_entries) { if (argv == static_argv) argv = _malloc_crt((max_entries * 2) * sizeof(_TSCHAR *)); else argv = _realloc_crt(argv, (max_entries * 2) * sizeof(_TSCHAR *)); if (argv == NULL) break; max_entries += max_entries; } argv[ i++ ] = nextarg; if (nextarg == NULL) break; nextarg = va_arg(*arglist, _TSCHAR *); } return argv; }
int __cdecl rename( const char *oldname, const char *newname ) { /* We want to use MoveFileExW but not MoveFileExA (or MoveFile). So convert the strings to Unicode representation and call _wrename. Note that minwin does not support OEM CP for conversion via the FileAPIs APIs. So we unconditionally use the ACP for conversion */ int oldnamelen; int newnamelen; wchar_t *widenamesbuffer = NULL; wchar_t *oldnamew = NULL; wchar_t *newnamew = NULL; int retval; UINT codePage = CP_ACP; #if !(defined (_CORESYS) || defined (_CRT_APP) || defined (_KERNELX)) if (!__crtIsPackagedApp() && !AreFileApisANSI()) codePage = CP_OEMCP; #endif /* !(defined (_CORESYS) || defined (_CRT_APP) || defined (_KERNELX)) */ if ( ( (oldnamelen = MultiByteToWideChar(codePage, 0, oldname, -1, 0, 0) ) == 0 ) || ( (newnamelen = MultiByteToWideChar(codePage, 0, newname, -1, 0, 0) ) == 0 ) ) { _dosmaperr(GetLastError()); return -1; } /* allocate enough space for both */ if ( (widenamesbuffer = (wchar_t*)_malloc_crt( (oldnamelen+newnamelen) * sizeof(wchar_t) ) ) == NULL ) { /* errno is set by _malloc */ return -1; } /* now do the conversion */ oldnamew = widenamesbuffer; newnamew = widenamesbuffer + oldnamelen; if ( ( MultiByteToWideChar(codePage, 0, oldname, -1, oldnamew, oldnamelen) == 0 ) || ( MultiByteToWideChar(codePage, 0, newname, -1, newnamew, newnamelen) == 0 ) ) { _free_crt(widenamesbuffer); _dosmaperr(GetLastError()); return -1; } /* and event call the wide-character variant */ retval = _wrename(oldnamew,newnamew); _free_crt(widenamesbuffer); /* _free_crt leaves errno alone if everything completes as expected */ return retval; }
int __cdecl _stbuf ( FILE *str ) { FILE *stream; int index; _ASSERTE(str != NULL); /* Init near stream pointer */ stream = str; /* do nothing if not a tty device */ if (!_isatty(_fileno(stream))) return(0); /* Make sure stream is stdout/stderr and init _stdbuf index */ if (stream == stdout) index = 0; else if (stream == stderr) index = 1; else return(0); #ifndef CRTDLL /* force library pre-termination procedure */ _cflush++; #endif /* CRTDLL */ /* Make sure the stream is not already buffered. */ if (anybuf(stream)) return(0); /* Allocate a buffer for this stream if we haven't done so yet. */ if ( (_stdbuf[index] == NULL) && ((_stdbuf[index]=_malloc_crt(_INTERNAL_BUFSIZ)) == NULL) ) { /* Cannot allocate buffer. Use _charbuf this time */ stream->_ptr = stream->_base = (void *)&(stream->_charbuf); stream->_cnt = stream->_bufsiz = 2; } else { /* Set up the buffer */ stream->_ptr = stream->_base = _stdbuf[index]; stream->_cnt = stream->_bufsiz = _INTERNAL_BUFSIZ; } stream->_flag |= (_IOWRT | _IOYOURBUF | _IOFLRTN); return(1); }
extern "C" float _CRTIMP __cdecl _wcstof_l ( const wchar_t *nptr, wchar_t **endptr, _locale_t plocinfo ) { int len; char * str = NULL; /* get the buffer size needed for conversion */ if ( (len = WideCharToMultiByte(CP_ACP, 0 /* Use default flags */, nptr, -1, 0, 0, NULL, NULL) ) == 0 ) { _dosmaperr(GetLastError()); return 0; } /* allocate enough space for conversion */ if ( (str = (char*)_malloc_crt( len * sizeof(char) ) ) == NULL ) { /* malloc should set the errno */ return 0; } /* now do the conversion */ if ( WideCharToMultiByte(CP_ACP, 0 /* Use default flags */, nptr, -1, str, len, NULL, NULL) == 0 ) { _dosmaperr(GetLastError()); _free_crt(str); return 0; } _CRT_FLOAT ret; char *local_end_ptr = NULL; __crt_atoflt_l(&ret, str, plocinfo, &local_end_ptr); if (endptr != NULL) { if (local_end_ptr != NULL) { *endptr = (wchar_t*)(nptr + (local_end_ptr - str)); } else { *endptr = NULL; } } _free_crt(str); return ret.f; }
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" ) ); }
static int __cdecl extend_ioinfo_arrays( int fh ) { ioinfo *pio; int i; /* * Walk __pioinfo[], allocating an array of ioinfo structs for each * empty entry, until there is an ioinfo struct corresponding to fh. */ for ( i = 0 ; fh >= _nhandle ; i++ ) { if ( __pioinfo[i] == NULL ) { if ( (pio = _malloc_crt( IOINFO_ARRAY_ELTS * sizeof(ioinfo) )) != NULL ) { __pioinfo[i] = pio; _nhandle += IOINFO_ARRAY_ELTS; for ( ; pio < __pioinfo[i] + IOINFO_ARRAY_ELTS ; pio++ ) { pio->osfile = 0; pio->osfhnd = (long)INVALID_HANDLE_VALUE; pio->pipech = 10; #if defined(_MT) && !defined(DLL_FOR_WIN32S) pio->lockinitflag = 0; #endif } } else { /* * Couldn't allocate another array, return failure. */ return -1; } } } return 0; }
void __cdecl _getbuf ( FILE *str ) { FILE *stream; _ASSERTE(str != NULL); #if !defined (CRTDLL) /* force library pre-termination procedure */ _cflush++; #endif /* !defined (CRTDLL) */ /* Init pointers */ stream = str; /* Try to get a big buffer */ if (stream->_base = _malloc_crt(_INTERNAL_BUFSIZ)) { /* Got a big buffer */ stream->_flag |= _IOMYBUF; stream->_bufsiz = _INTERNAL_BUFSIZ; } else { /* Did NOT get a buffer - use single char buffering. */ stream->_flag |= _IONBF; stream->_base = (char *)&(stream->_charbuf); stream->_bufsiz = 2; } stream->_ptr = stream->_base; stream->_cnt = 0; return; }
LPVOID __cdecl __crtGetEnvironmentStringsW( VOID ) { void *penv; wchar_t *pwch; wchar_t *wbuffer; int total_size; if ( NULL == (penv = GetEnvironmentStringsW()) ) return NULL; /* find out how big a buffer is needed */ pwch = penv; while ( *pwch != L'\0' ) { if ( *++pwch == L'\0' ) pwch++; } total_size = (int)((char *)pwch - (char *)penv) + (int)sizeof( wchar_t ); /* allocate the buffer */ if ( NULL == (wbuffer = _malloc_crt( total_size )) ) { FreeEnvironmentStringsW( penv ); return NULL; } /* copy environment strings to buffer */ memcpy( wbuffer, penv, total_size ); FreeEnvironmentStringsW( penv ); return (LPVOID)wbuffer; }
void __cdecl _wperror ( REG1 const wchar_t *wmessage ) { REG2 int fh = 2; int size; char *amessage; /* convert WCS string into ASCII string */ size = wcslen(wmessage) + 1; if (NULL == (amessage = (char *)_malloc_crt(size * sizeof(char)))) return; if (0 == (wcstombs(amessage, wmessage, size))) { _free_crt (amessage); return; } _lock_fh(fh); /* acquire file handle lock */ if (amessage && *amessage) { _write_lk(fh,(char *)amessage,strlen(amessage)); _write_lk(fh,": ",2); } _free_crt(amessage); amessage = _sys_err_msg( errno ); _write_lk(fh,(char *)amessage,strlen(amessage)); _write_lk(fh,"\n",1); _unlock_fh(fh); /* release file handle lock */ }
int __cdecl __wtomb_environ ( void ) { char *envp; wchar_t **wenvp = _wenviron; /* * For every environment variable in the multibyte environment, * convert it and add it to the wide environment. */ while (*wenvp) { int size; /* find out how much space is needed */ if ((size = WideCharToMultiByte(CP_OEMCP, 0, *wenvp, -1, NULL, 0, NULL, NULL)) == 0) return -1; /* allocate space for variable */ if ((envp = (char *) _malloc_crt(size * sizeof(char))) == NULL) return -1; /* convert it */ if (WideCharToMultiByte(CP_OEMCP, 0, *wenvp, -1, envp, size, NULL, NULL) == 0) return -1; /* set it - this is not primary call, so set primary == 0 */ __crtsetenv(envp, 0); wenvp++; } return 0; }
static int __cdecl pre_c_init(void) { _PVFV * onexitbegin; /* * create the onexit table. */ onexitbegin = (_PVFV *)_malloc_crt(32 * sizeof(_PVFV)); __onexitend = __onexitbegin = (_PVFV *)_encode_pointer(onexitbegin); if ( onexitbegin == NULL ) /* * cannot allocate minimal required * size. generate failure to load DLL */ return 1; *onexitbegin = (_PVFV) NULL; /* * Run the RTC initialization code for this DLL */ #ifdef _RTC _RTC_Initialize(); atexit(_RTC_Terminate); #endif /* _RTC */ #ifndef _SYSCRT /* * Register __clean_type_info_names so that we clean up all the * type_info.names that are allocated */ atexit(__clean_type_info_names); #endif /* _SYSCRT */ return 0; }
void __cdecl _lock ( int locknum ) { PCRITICAL_SECTION pcs; /* * Create/open the lock, if necessary */ if ( _locktable[locknum] == NULL ) { if ( (pcs = _malloc_crt(sizeof(CRITICAL_SECTION))) == NULL ) _amsg_exit(_RT_LOCK); _mlock(_LOCKTAB_LOCK); /*** WARNING: Recursive lock call ***/ if ( _locktable[locknum] == NULL ) { InitializeCriticalSection(pcs); _locktable[locknum] = pcs; } else { _free_crt(pcs); } _munlock(_LOCKTAB_LOCK); } /* * Enter the critical section. */ EnterCriticalSection( _locktable[locknum] ); }
_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); }
int __cdecl __crtsetenv ( #endif const _TSCHAR *option, const int primary ) { int ix; int remove; /* 1 if variable is to be removed */ _TSCHAR **env; _TSCHAR *name, *value; const _TSCHAR *equal; /* * check that the option string is valid, find the equal sign * and verify '=' is not the first character in string. */ if ( (option == NULL) || ((equal = _tcschr(option, _T('='))) == NULL) || option == equal) return(-1); /* if the character following '=' is null, we are removing the * the environment variable. Otherwise, we are adding or updating * an environment variable. */ remove = (*(equal + 1) == _T('\0')); /* * the first time _[w]putenv() is called, copy the environment * block that was passed to [w]main to avoid making a * dangling pointer if the block is re-alloced. */ #ifdef WPRFLAG if (_wenviron == __winitenv) _wenviron = copy_environ(_wenviron); #else if (_environ == __initenv) _environ = copy_environ(_environ); #endif /* see if requested environment array exists */ if (_tenviron == NULL) { /* * The requested type of environment does not exist. * See if other type exists, if so convert it to requested type. * The functions that convert the enviroment (__mbtow_environ and * __wtomb_environ) will call this function (__crt[w]setenv) once * for each of the pre-existing environment variables. To avoid * an infinite loop, test the primary flag. */ #ifdef WPRFLAG if (primary && _environ) { if (__mbtow_environ() != 0) return -1; } #else if (primary && _wenviron) { if (__wtomb_environ() != 0) return -1; } #endif else { /* nothing to remove, return */ if ( remove ) return 0; else { /* create ones that do not exist */ if (_environ == NULL) { if ( (_environ = _malloc_crt(sizeof(char *))) == NULL) return -1; *_environ = NULL; } if (_wenviron == NULL) { if ( (_wenviron = _malloc_crt(sizeof(wchar_t *))) == NULL) return -1; *_wenviron = NULL; } } } } /* * At this point, the two types of environments are in sync (as much * as they can be anyway). The only way they can get out of sync * (besides users directly modifiying the environment) is if there * are conversion problems: If the user sets two Unicode EVs, * "foo1" and "foo2" and converting then to multibyte yields "foo?" * and "foo?", then the environment blocks will differ. */ /* init env pointers */ env = _tenviron; /* See if the string is already in the environment */ #ifdef WPRFLAG ix = wfindenv(option, equal - option); #else ix = findenv(option, equal - option); #endif if ((ix >= 0) && (*env != NULL)) { /* String is already in the environment - overwrite/remove it */ if (remove) { /* free the string being removed */ _free_crt(env[ix]); /* removing -- move all the later strings up */ for ( ; env[ix] != NULL; ++ix) { env[ix] = env[ix+1]; } /* shrink the environment memory block (ix now has number of strings, including NULL) -- this realloc probably can't fail, since we're shrinking a mem block, but we're careful anyway. */ if (env = (_TSCHAR **) _realloc_crt(env, ix * sizeof(_TSCHAR *))) _tenviron = env; } else { /* replace the option */ env[ix] = (_TSCHAR *) option; } } else { /* * String is NOT in the environment */ if ( !remove ) { /* * Append the string to the environ table. Note that * table must be grown to do this. */ if (ix < 0) ix = -ix; /* ix = length of environ table */ if ( (env = (_TSCHAR **)_realloc_crt(env, sizeof(_TSCHAR *) * (ix + 2))) == NULL ) return -1; env[ix] = (_TSCHAR *)option; env[ix + 1] = NULL; _tenviron = env; } else /* * We are asked to remove an environment var that * isn't there...just return success */ return 0; } /* * Update the OS environment. Don't give an error if this fails * since the failure will not affect the user unless he/she is making * direct API calls. Only need to do this for one type, OS converts * to other type automatically. */ if ( primary && (name = (_TSCHAR *)_malloc_crt((_tcslen(option) + 2) * sizeof(_TSCHAR))) != NULL ) { _tcscpy(name, option); value = name + (equal - option); *value++ = _T('\0'); SetEnvironmentVariable(name, remove ? NULL : value); _free_crt(name); } return 0; }
/* now define version that doesn't lock/unlock, validate fh */ int __cdecl _read_nolock ( int fh, void *inputbuf, unsigned cnt ) { int bytes_read; /* number of bytes read */ char *buffer; /* buffer to read to */ int os_read; /* bytes read on OS call */ char *p, *q; /* pointers into buffer */ wchar_t *pu, *qu; /* wchar_t pointers into buffer for UTF16 */ char peekchr; /* peek-ahead character */ wchar_t wpeekchr; /* peek-ahead wchar_t */ __int64 filepos; /* file position after seek */ ULONG dosretval; /* o.s. return value */ char tmode; /* textmode - ANSI/UTF-8/UTF-16 */ void *buf; /* buffer to read to */ int retval = -2; /* return value */ unsigned inputsize = cnt; /* validate fh */ _CHECK_FH_CLEAR_OSSERR_RETURN( fh, EBADF, -1 ); _VALIDATE_CLEAR_OSSERR_RETURN((fh >= 0 && (unsigned)fh < (unsigned)_nhandle), EBADF, -1); _VALIDATE_CLEAR_OSSERR_RETURN((_osfile(fh) & FOPEN), EBADF, -1); bytes_read = 0; /* nothing read yet */ if (cnt == 0 || (_osfile(fh) & FEOFLAG)) { /* nothing to read or at EOF, so return 0 read */ return 0; } _VALIDATE_CLEAR_OSSERR_RETURN( (inputbuf != NULL), EINVAL, -1 ); tmode = _textmode(fh); switch(tmode) { case __IOINFO_TM_UTF8 : /* For a UTF-8 file, we need 2 buffers, because after reading we need to convert it into UNICODE - MultiByteToWideChar doesn't do in-place conversions. */ /* MultiByte To WideChar conversion may double the size of the buffer required & hence we divide cnt by 2 */ /* * Since we are reading UTF8 stream, cnt bytes read may vary * from cnt wchar_t characters to cnt/4 wchar_t characters. For * this reason if we need to read cnt characters, we will * allocate MBCS buffer of cnt. In case cnt is 0, we will * have 4 as minimum value. This will make sure we don't * overflow for reading from pipe case. * * * In this case the numbers of wchar_t characters that we can * read is cnt/2. This means that the buffer size that we will * require is cnt/2. */ /* For UTF8 we want the count to be an even number */ _VALIDATE_CLEAR_OSSERR_RETURN(((cnt & 1) == 0), EINVAL, -1); cnt = (cnt/2) < 4 ? 4 : (cnt/2); buf = _malloc_crt(cnt); if(!buf) { errno = ENOMEM; _doserrno = E_nomem; return -1; } break; case __IOINFO_TM_UTF16LE : /* For UTF16 the count always needs to be an even number */ _VALIDATE_CLEAR_OSSERR_RETURN(((cnt & 1) == 0), EINVAL, -1); cnt &= (~1); /* Fall Through to default */ default : /* For non-UTF8 files, we need only 1 buffer - make buf point to the users input buffer */ buf = inputbuf; } buffer = buf; if ((_osfile(fh) & (FPIPE|FDEV)) && _pipech(fh) != LF && cnt != 0) { /* a pipe/device and pipe lookahead non-empty: read the lookahead * char */ *buffer++ = _pipech(fh); ++bytes_read; --cnt; _pipech(fh) = LF; /* mark as empty */ /* For UTF16, there maybe one more look ahead char. For UTF8, there maybe 2 more look ahead chars */ if((tmode != __IOINFO_TM_ANSI) && (_pipech2(fh)[0] != LF) && cnt != 0) { *buffer++ = _pipech2(fh)[0]; ++bytes_read; --cnt; _pipech2(fh)[0] = LF; /* mark as empty */ if((tmode == __IOINFO_TM_UTF8) && (_pipech2(fh)[1] != LF) && cnt != 0) { *buffer++ = _pipech2(fh)[1]; ++bytes_read; --cnt; _pipech2(fh)[1] = LF; /* mark as empty */ } } } /* read the data */ if ( !ReadFile( (HANDLE)_osfhnd(fh), buffer, cnt, (LPDWORD)&os_read, NULL ) || os_read < 0 || (size_t)os_read > cnt) { /* ReadFile has reported an error. recognize two special cases. * * 1. map ERROR_ACCESS_DENIED to EBADF * * 2. just return 0 if ERROR_BROKEN_PIPE has occurred. it * means the handle is a read-handle on a pipe for which * all write-handles have been closed and all data has been * read. */ if ( (dosretval = GetLastError()) == ERROR_ACCESS_DENIED ) { /* wrong read/write mode should return EBADF, not EACCES */ errno = EBADF; _doserrno = dosretval; retval = -1; goto error_return; } else if ( dosretval == ERROR_BROKEN_PIPE ) { retval = 0; goto error_return; } else { _dosmaperr(dosretval); retval = -1; goto error_return; } } bytes_read += os_read; /* update bytes read */ if (_osfile(fh) & FTEXT) { /* now must translate CR-LFs to LFs in the buffer */ /* For ANSI & UTF8, we read byte by byte. For UTF16, we need to read 2 bytes (wchar_t's) at a time */ if(tmode != __IOINFO_TM_UTF16LE) { /* set CRLF flag to indicate LF at beginning of buffer */ if ( (os_read != 0) && (*(char *)buf == LF) ) _osfile(fh) |= FCRLF; else _osfile(fh) &= ~FCRLF; /* convert chars in the buffer: p is src, q is dest */ p = q = buf; while (p < (char *)buf + bytes_read) { if (*p == CTRLZ) { /* if fh is not a device, set ctrl-z flag */ if ( !(_osfile(fh) & FDEV) ) _osfile(fh) |= FEOFLAG; else *q++ = *p++; break; /* stop translating */ } else if (*p != CR) *q++ = *p++; else { /* *p is CR, so must check next char for LF */ if (p < (char *)buf + bytes_read - 1) { if (*(p+1) == LF) { p += 2; *q++ = LF; /* convert CR-LF to LF */ } else *q++ = *p++; /* store char normally */ } else { /* This is the hard part. We found a CR at end of buffer. We must peek ahead to see if next char is an LF. */ ++p; dosretval = 0; if ( !ReadFile( (HANDLE)_osfhnd(fh), &peekchr, 1, (LPDWORD)&os_read, NULL ) ) dosretval = GetLastError(); if (dosretval != 0 || os_read == 0) { /* couldn't read ahead, store CR */ *q++ = CR; } else { /* * peekchr now has the extra character -- we now * have several possibilities: * * 1. disk file and char is not LF; just seek * back and copy CR * 2. disk file and char is LF; seek back and * discard CR * 3. disk file, char is LF but this is a * one-byte read: store LF, don't seek back * 4. pipe/device and char is LF; store LF. * 5. pipe/device and char isn't LF, store CR * and put char in pipe lookahead buffer. */ if (_osfile(fh) & (FDEV|FPIPE)) { /* non-seekable device */ if (peekchr == LF) *q++ = LF; else { *q++ = CR; _pipech(fh) = peekchr; } } else { /* disk file */ if (q == buf && peekchr == LF) { /* nothing read yet; must make some progress */ *q++ = LF; } else { /* seek back */ filepos = _lseeki64_nolock(fh, -1i64, FILE_CURRENT); if (peekchr != LF) *q++ = CR; } } } } } } /* we now change bytes_read to reflect the true number of chars in the buffer */ bytes_read = (int)(q - (char *)buf); if((tmode == __IOINFO_TM_UTF8) && (bytes_read != 0)) { /* UTF8 reads need to be converted into UTF16 */ --q; /* q has gone beyond the last char */ /* * If the last byte is a standalone UTF-8 char. We then * take the whole buffer. Otherwise we skip back till we * come to a lead byte. If the leadbyte forms a complete * UTF-8 character will the remaining part of the buffer, * then again we take the whole buffer. If not, we skip to * one byte which should be the final trail byte of the * previous UTF-8 char or a standalone UTF-8 character */ if(_utf8_is_independent(*q)) { ++q; /* * Final byte is standalone, we reset q, because we * will now consider the full buffer which we have read */ } else { int ctr = 1; int cnt_trailbytes; while(!_utf8_is_leadbyte(*q) && ctr <= 4 && q >= (char *)buf) { --q; ++ctr; } cnt_trailbytes = _utf8_no_of_trailbytes(*q); if(cnt_trailbytes == 0) { /* * Should have exited the while by finding a lead * byte else, the file has incorrect UTF-8 chars */ errno = EILSEQ; retval = -1; goto error_return; } if(cnt_trailbytes + 1 == ctr) { /* * The leadbyte + the remaining bytes form a full * set */ q += ctr; } else { /* Seek back */ if (_osfile(fh) & (FDEV|FPIPE)) { /* * non-seekable device. Put the extra chars in * _pipech & _pipech2. We would have a maximum * of 3 extra chars */ _pipech(fh) = *q; ++q; if(ctr >= 2) { _pipech2(fh)[0] = *q; ++q; } if(ctr == 3) { _pipech2(fh)[1] = *q; ++q; } /* * We need to point q back to beyond whatever * we actually took in. */ q -= ctr; } else { /* We have read extra chars, so we seek back */ filepos = _lseeki64_nolock(fh, -ctr, FILE_CURRENT); } } } bytes_read = (int)(q - (char *)buf); bytes_read = MultiByteToWideChar( CP_UTF8, 0, buf, bytes_read, inputbuf, inputsize/2); if(!bytes_read) { _dosmaperr(GetLastError()); retval = -1; goto error_return; } /* MultiByteToWideChar returns no of wchar_t's. Double it */ bytes_read = bytes_read*2; } } else { /* set CRLF flag to indicate LF at beginning of buffer */ if ( (os_read != 0) && (*(wchar_t *)buf == LF) ) _osfile(fh) |= FCRLF; else _osfile(fh) &= ~FCRLF; /* convert chars in the buffer: pu is src, qu is dest */ pu = qu = (wchar_t *)buf; while ((char *)pu < (char *)buf + bytes_read) { if (*pu == CTRLZ) { /* if fh is not a device, set ctrl-z flag */ if ( !(_osfile(fh) & FDEV) ) _osfile(fh) |= FEOFLAG; else *qu++ = *pu++; break; /* stop translating */ } else if (*pu != CR) *qu++ = *pu++; else { /* *pu is CR, so must check next wchar_t for LF */ if ((char *)pu < (char *)buf + bytes_read - 2) { if (*(pu+1) == LF) { pu += 2; *qu++ = LF; /* convert CR-LF to LF */ } else *qu++ = *pu++; /* store char normally */ } else { /* This is the hard part. We found a CR at end of buffer. We must peek ahead to see if next wchar_t is an LF. */ ++pu; dosretval = 0; if ( !ReadFile( (HANDLE)_osfhnd(fh), &wpeekchr, 2, (LPDWORD)&os_read, NULL ) ) dosretval = GetLastError(); if (dosretval != 0 || os_read == 0) { /* couldn't read ahead, store CR */ *qu++ = CR; } else { /* * peekchr now has the extra character -- we * now have several possibilities: * 1. wchar_t is not LF; just seek back and * copy CR * 2. wchar_t is LF; seek back and discard CR * 3. disk file, wchar_t is LF but this is a * one-byte read: store LF, don't seek back. */ if (_osfile(fh) & (FDEV|FPIPE)) { /* non-seekable device */ if (wpeekchr == LF) *qu++ = LF; else { char * pwpeekchr = (char *)&wpeekchr; *qu++ = CR; _pipech(fh) = *pwpeekchr; ++pwpeekchr; _pipech2(fh)[0] = *pwpeekchr; _pipech2(fh)[1] = LF; /* Mark as empty */ } } else { if ((char *)qu == buf && wpeekchr == LF) { /* nothing read yet; must make some progress */ *qu++ = LF; } else { /* seek back */ filepos = _lseeki64_nolock(fh, -2, FILE_CURRENT); if (wpeekchr != LF) *qu++ = CR; } } } } } } /* we now change bytes_read to reflect the true number of chars in the buffer */ bytes_read = (int)((char *)qu - (char *)buf); } } error_return: if(buf != inputbuf) { free(buf); } return (retval == -2) ? bytes_read : retval ; }
_MRTIMP2_NCEEPURE size_t __CLRCALL_PURE_OR_CDECL _Wcsxfrm( wchar_t* _string1, wchar_t* _end1, const wchar_t* _string2, const wchar_t* _end2, const _Collvec* ploc ) { size_t _n1 = _end1 - _string1; size_t _n2 = _end2 - _string2; size_t size = (size_t) - 1; unsigned char* bbuffer = NULL; LCID handle; if (ploc == 0) { handle = ___lc_handle_func()[LC_COLLATE]; } else { handle = ploc->_Hand; } if (handle == _CLOCALEHANDLE) { if (_n2 <= _n1) { memcpy(_string1, _string2, _n2 * sizeof(wchar_t)); } size = _n2; } else { /* * When using LCMAP_SORTKEY, LCMapStringW handles BYTES not wide * chars. We use a byte buffer to hold bytes and then convert the * byte string to a wide char string and return this so it can be * compared using wcscmp(). User's buffer is _n1 wide chars, so * use an internal buffer of _n1 bytes. */ if (NULL != (bbuffer = (unsigned char*)_malloc_crt(_n1))) { if (0 == (size = __crtLCMapStringW(NULL, handle, LCMAP_SORTKEY, _string2, (int)_n2, (wchar_t*)bbuffer, (int)_n1, ___lc_collate_cp_func()))) { /* buffer not big enough, get size required. */ if (0 == (size = __crtLCMapStringW(NULL, handle, LCMAP_SORTKEY, _string2, (int)_n2, NULL, 0, ___lc_collate_cp_func()))) { size = INT_MAX; /* default error */ } } else { size_t i; /* string successfully mapped, convert to wide char */ for (i = 0; i < size; i++) { _string1[i] = (wchar_t)bbuffer[i]; } } } } if (bbuffer) { _free_crt(bbuffer); } return (size_t)size; }
/*** *_setargv, __setargv - set up "argc" and "argv" for C programs * *Purpose: * Read the command line and create the argv array for C * programs. * *Entry: * Arguments are retrieved from the program command line, * pointed to by _acmdln. * *Exit: * "argv" points to a null-terminated list of pointers to ASCIZ * strings, each of which is an argument from the command line. * "argc" is the number of arguments. The strings are copied from * the environment segment into space allocated on the heap/stack. * The list of pointers is also located on the heap or stack. * _pgmptr points to the program name. * *Exceptions: * Terminates with out of memory error if no memory to allocate. * *******************************************************************************/ #ifdef WILDCARD #ifdef WPRFLAG void __cdecl __wsetargv ( #else /* WPRFLAG */ void __cdecl __setargv ( #endif /* WPRFLAG */ #else /* WILDCARD */ #ifdef WPRFLAG void __cdecl _wsetargv ( #else /* WPRFLAG */ void __cdecl _setargv ( #endif /* WPRFLAG */ #endif /* WILDCARD */ void ) { _TSCHAR *p; _TSCHAR *cmdstart; /* start of command line to parse */ int numargs, numchars; static _TSCHAR _pgmname[ MAX_PATH ]; #if !defined (CRTDLL) && defined (_MBCS) /* If necessary, initialize the multibyte ctype table. */ if ( __mbctype_initialized == 0 ) __initmbctable(); #endif /* !defined (CRTDLL) && defined (_MBCS) */ /* Get the program name pointer from Win32 Base */ GetModuleFileName( NULL, _pgmname, sizeof( _pgmname ) / sizeof(_TSCHAR)); #ifdef WPRFLAG _wpgmptr = _pgmname; #else /* WPRFLAG */ _pgmptr = _pgmname; #endif /* WPRFLAG */ /* if there's no command line at all (won't happen from cmd.exe, but possibly another program), then we use _pgmptr as the command line to parse, so that argv[0] is initialized to the program name */ #ifdef WPRFLAG cmdstart = (*_wcmdln == NULCHAR) ? _wpgmptr : _wcmdln; #else /* WPRFLAG */ cmdstart = (*_acmdln == NULCHAR) ? _pgmptr : _acmdln; #endif /* WPRFLAG */ /* first find out how much space is needed to store args */ #ifdef WPRFLAG wparse_cmdline(cmdstart, NULL, NULL, &numargs, &numchars); #else /* WPRFLAG */ parse_cmdline(cmdstart, NULL, NULL, &numargs, &numchars); #endif /* WPRFLAG */ /* allocate space for argv[] vector and strings */ p = _malloc_crt(numargs * sizeof(_TSCHAR *) + numchars * sizeof(_TSCHAR)); if (p == NULL) _amsg_exit(_RT_SPACEARG); /* store args and argv ptrs in just allocated block */ #ifdef WPRFLAG wparse_cmdline(cmdstart, (wchar_t **)p, (wchar_t *)(((char *)p) + numargs * sizeof(wchar_t *)), &numargs, &numchars); #else /* WPRFLAG */ parse_cmdline(cmdstart, (char **)p, p + numargs * sizeof(char *), &numargs, &numchars); #endif /* WPRFLAG */ /* set argv and argc */ __argc = numargs - 1; #ifdef WPRFLAG __wargv = (wchar_t **)p; #else /* WPRFLAG */ __argv = (char **)p; #endif /* WPRFLAG */ #ifdef WILDCARD /* call _[w]cwild to expand wildcards in arg vector */ #ifdef WPRFLAG if (_wcwild()) #else /* WPRFLAG */ if (_cwild()) #endif /* WPRFLAG */ _amsg_exit(_RT_SPACEARG); /* out of space */ #endif /* WILDCARD */ }
int __cdecl _tspawnvpe ( int modeflag, REG3 const _TSCHAR *filename, const _TSCHAR * const *argv, const _TSCHAR * const *envptr ) { int i; REG1 _TSCHAR *env; REG2 _TSCHAR *buf = NULL; _TSCHAR *pfin; _ASSERTE(filename != NULL); _ASSERTE(*filename != _T('\0')); _ASSERTE(argv != NULL); _ASSERTE(*argv != NULL); _ASSERTE(**argv != _T('\0')); if ( (i = _tspawnve(modeflag, filename, argv, envptr)) != -1 /* everything worked just fine; return i */ || (errno != ENOENT) /* couldn't spawn the process, return failure */ || (_tcschr(filename, XSLASHCHAR) != NULL) /* filename contains a '/', return failure */ || !(env = _tgetenv(_T("PATH"))) /* no PATH environment string name, return failure */ || ( (buf = _malloc_crt(_MAX_PATH * sizeof(_TSCHAR))) == NULL ) /* cannot allocate buffer to build alternate pathnames, return * failure */ ) { goto done; } /* could not find the file as specified, search PATH. try each * component of the PATH until we get either no error return, or the * error is not ENOENT and the component is not a UNC name, or we run * out of components to try. */ #ifdef WPRFLAG while ( (env = _wgetpath(env, buf, _MAX_PATH - 1)) && (*buf) ) { #else /* WPRFLAG */ while ( (env = _getpath(env, buf, _MAX_PATH - 1)) && (*buf) ) { #endif /* WPRFLAG */ pfin = buf + _tcslen(buf) - 1; /* if necessary, append a '/' */ #ifdef _MBCS if (*pfin == SLASHCHAR) { if (pfin != _mbsrchr(buf,SLASHCHAR)) /* fin is the second byte of a double-byte char */ strcat(buf, SLASH ); } else if (*pfin !=XSLASHCHAR) strcat(buf, SLASH); #else /* _MBCS */ if (*pfin != SLASHCHAR && *pfin != XSLASHCHAR) _tcscat(buf, SLASH); #endif /* _MBCS */ /* check that the final path will be of legal size. if so, * build it. otherwise, return to the caller (return value * and errno rename set from initial call to _spawnve()). */ if ( (_tcslen(buf) + _tcslen(filename)) < _MAX_PATH ) _tcscat(buf, filename); else break; /* try spawning it. if successful, or if errno comes back with a * value other than ENOENT and the pathname is not a UNC name, * return to the caller. */ if ( (i = _tspawnve(modeflag, buf, argv, envptr)) != -1 || ((errno != ENOENT) #ifdef _MBCS && (!ISPSLASH(buf) || !ISPSLASH(buf+1))) ) #else /* _MBCS */ && (!ISSLASH(*buf) || !ISSLASH(*(buf+1)))) ) #endif /* _MBCS */ break; } done: if (buf != NULL) _free_crt(buf); return(i); }
int __cdecl __init_numeric ( void ) { #ifdef DLL_FOR_WIN32S #define dec_pnt (_GetPPD()->_ppd_dec_pnt) #define thous_sep (_GetPPD()->_ppd_thous_sep) #define grping (_GetPPD()->_ppd_grping) #else /* ndef DLL_FOR_WIN32S */ static char *dec_pnt = NULL; static char *thous_sep = NULL; static char *grping = NULL; #endif /* DLL_FOR_WIN32S */ int ret = 0; /* Numeric data is country--not language--dependent. NT work-around. */ LCID ctryid = MAKELCID(__lc_id[LC_NUMERIC].wCountry, SORT_DEFAULT); if (__lc_handle[LC_NUMERIC] != _CLOCALEHANDLE) { ret |= __getlocaleinfo(LC_STR_TYPE, ctryid, LOCALE_SDECIMAL, (void *)&dec_pnt); ret |= __getlocaleinfo(LC_STR_TYPE, ctryid, LOCALE_STHOUSAND, (void *)&thous_sep); ret |= __getlocaleinfo(LC_STR_TYPE, ctryid, LOCALE_SGROUPING, (void *)&grping); fix_grouping(grping); if (ret) { _free_crt (dec_pnt); _free_crt (thous_sep); _free_crt (grping); dec_pnt = NULL; thous_sep = NULL; grping = NULL; return -1; } if (__lconv->decimal_point != __lconv_static_decimal) { _free_crt(__lconv->decimal_point); _free_crt(__lconv->thousands_sep); _free_crt(__lconv->grouping); } __lconv->decimal_point = dec_pnt; __lconv->thousands_sep = thous_sep; __lconv->grouping = grping; /* set global decimal point character */ *__decimal_point = *__lconv->decimal_point; __decimal_point_length = 1; return 0; } else { _free_crt (dec_pnt); _free_crt (thous_sep); _free_crt (grping); dec_pnt = NULL; thous_sep = NULL; grping = NULL; /* malloc them so we can free them */ if ((__lconv->decimal_point = _malloc_crt(2)) == NULL) return -1; strcpy(__lconv->decimal_point, "."); if ((__lconv->thousands_sep = _malloc_crt(2)) == NULL) return -1; __lconv->thousands_sep[0] = '\0'; if ((__lconv->grouping = _malloc_crt(2)) == NULL) return -1; __lconv->grouping[0] = '\0'; /* set global decimal point character */ *__decimal_point = *__lconv->decimal_point; __decimal_point_length = 1; return 0; } }
LPVOID __cdecl __crtGetEnvironmentStringsA( VOID ) { static int f_use = 0; wchar_t *wEnv; wchar_t *wTmp; char *aEnv; char *aTmp; int nSizeW; int nSizeA; /* * Look for 'preferred' flavor. Otherwise use available flavor. * Must actually call the function to ensure it's not a stub. */ if ( 0 == f_use ) { if ( NULL != (wEnv = GetEnvironmentStringsW()) ) f_use = USE_W; else if ( NULL != (aEnv = GetEnvironmentStringsA()) ) f_use = USE_A; else return NULL; } /* Use "W" version */ if (USE_W == f_use) { /* obtain wide environment block */ if ( NULL == wEnv ) if ( NULL == (wEnv = GetEnvironmentStringsW()) ) return NULL; /* look for double null that indicates end of block */ wTmp = wEnv; while ( *wTmp != L'\0' ) { if ( *++wTmp == L'\0' ) wTmp++; } /* calculate total size of block, including all nulls */ nSizeW = wTmp - wEnv + 1; /* find out how much space needed for multi-byte environment */ nSizeA = WideCharToMultiByte( CP_ACP, 0, wEnv, nSizeW, NULL, 0, NULL, NULL ); /* allocate space for multi-byte string */ if ( (nSizeA == 0) || ((aEnv = (char *)_malloc_crt(nSizeA)) == NULL) ) { FreeEnvironmentStringsW( wEnv ); return NULL; } /* do the conversion */ if ( !WideCharToMultiByte( CP_ACP, 0, wEnv, nSizeW, aEnv, nSizeA, NULL, NULL ) ) { _free_crt( aEnv ); aEnv = NULL; } FreeEnvironmentStringsW( wEnv ); return aEnv; } /* Use "A" version */ if ( USE_A == f_use ) { if ( NULL == aEnv ) if ( NULL == (aEnv = GetEnvironmentStringsA()) ) return NULL; /* determine how big a buffer is needed */ aTmp = aEnv; while ( *aTmp != '\0' ) { if ( *++aTmp == '\0' ) aTmp++; } nSizeA = aTmp - aEnv + 1; if ( NULL == (aTmp = _malloc_crt( nSizeA )) ) { FreeEnvironmentStringsA( aEnv ); return NULL; } memcpy( aTmp, aEnv, nSizeA ); FreeEnvironmentStringsA( aEnv ); return aTmp; } return NULL; }
FILE * __cdecl _getstream ( void ) { FILE *retval = NULL; int i; /* Get the iob[] scan lock */ _mlock(_IOB_SCAN_LOCK); __try { /* * Loop through the __piob table looking for a free stream, or the * first NULL entry. */ for ( i = 0 ; i < _nstream ; i++ ) { if ( __piob[i] != NULL ) { /* * if the stream is not inuse, return it. */ if ( !inuse( (FILE *)__piob[i] ) && !str_locked( (FILE *)__piob[i] ) ) { /* * Allocate the FILE lock, in case it hasn't already been * allocated (only necessary for the first _IOB_ENTRIES * locks, not including stdin/stdout/stderr). Return * failure if lock can't be allocated. */ if ( i > 2 && i < _IOB_ENTRIES ) if ( !_mtinitlocknum( _STREAM_LOCKS + i ) ) break; _lock_str2(i, __piob[i]); if ( inuse( (FILE *)__piob[i] ) ) { _unlock_str2(i, __piob[i]); continue; } retval = (FILE *)__piob[i]; break; } } else { /* * allocate a new _FILEX, set _piob[i] to it and return a * pointer to it. */ if ( (__piob[i] = _malloc_crt( sizeof(_FILEX) )) != NULL ) { __crtInitializeCriticalSectionEx(&(((_FILEX *)__piob[i])->lock), _CRT_SPINCOUNT, 0); EnterCriticalSection( &(((_FILEX *)__piob[i])->lock) ); retval = (FILE *)__piob[i]; retval->_flag = 0; } break; } } /* * Initialize the return stream. */ if ( retval != NULL ) { /* make sure that _IOLOCKED is preserved (if set) and zero out the other bits of _flag */ retval->_flag &= _IOLOCKED; retval->_cnt = 0; retval->_tmpfname = retval->_ptr = retval->_base = NULL; retval->_file = -1; } } __finally { _munlock(_IOB_SCAN_LOCK); } return(retval); }
double __cdecl wcstod ( const wchar_t *nptr, REG2 wchar_t **endptr ) { #ifdef _MT struct _flt answerstruct; #endif FLT answer; double tmp; unsigned int flags; REG1 wchar_t *ptr = (wchar_t *) nptr; char * cptr; int retval, len; int clen = 0; /* scan past leading space/tab characters */ while (iswspace(*ptr)) ptr++; cptr = (char *)_malloc_crt((wcslen(ptr)+1) * sizeof(wchar_t)); // UNDONE: check for errors for (len = 0; ptr[len]; len++) { if ((retval = wctomb(cptr+len,ptr[len]))<=0) break; clen += retval; } cptr[clen++] = '\0'; /* let _fltin routine do the rest of the work */ #ifdef _MT /* ok to take address of stack variable here; fltin2 knows to use ss */ answer = _fltin2( &answerstruct, cptr, clen, 0, 0); #else answer = _fltin(cptr, clen, 0, 0); #endif _free_crt(cptr); if ( endptr != NULL ) *endptr = (wchar_t *) ptr + answer->nbytes; /* UNDONE: assumes no multi-byte chars in string */ flags = answer->flags; if ( flags & (512 | 64)) { /* no digits found or invalid format: ANSI says return 0.0, and *endptr = nptr */ tmp = 0.0; if ( endptr != NULL ) *endptr = (wchar_t *) nptr; } else if ( flags & (128 | 1) ) { if ( *ptr == '-' ) tmp = -HUGE_VAL; /* negative overflow */ else tmp = HUGE_VAL; /* positive overflow */ errno = ERANGE; } else if ( flags & 256 ) { tmp = 0.0; /* underflow */ errno = ERANGE; } else tmp = answer->dval; return(tmp); }
LPVOID __cdecl __crtGetEnvironmentStringsW( VOID ) { static int f_use = 0; void *penv = NULL; char *pch; wchar_t *pwch; wchar_t *wbuffer; int total_size = 0; int str_size; /* * Look for unstubbed 'preferred' flavor. Otherwise use available flavor. * Must actually call the function to ensure it's not a stub. */ if ( 0 == f_use ) { if ( NULL != (penv = GetEnvironmentStringsW()) ) f_use = USE_W; else if ( NULL != (penv = GetEnvironmentStringsA()) ) f_use = USE_A; else return NULL; } /* Use "W" version */ if ( USE_W == f_use ) { if ( NULL == penv ) if ( NULL == (penv = GetEnvironmentStringsW()) ) return NULL; /* find out how big a buffer is needed */ pwch = penv; while ( *pwch != L'\0' ) { if ( *++pwch == L'\0' ) pwch++; } total_size = (char *)pwch - (char *)penv + sizeof( wchar_t ); /* allocate the buffer */ if ( NULL == (wbuffer = _malloc_crt( total_size )) ) { FreeEnvironmentStringsW( penv ); return NULL; } /* copy environment strings to buffer */ memcpy( wbuffer, penv, total_size ); FreeEnvironmentStringsW( penv ); return (LPVOID)wbuffer; } /* Use "A" version */ if ( USE_A == f_use ) { /* * Convert strings and return the requested information. */ if ( NULL == penv ) if ( NULL == (penv = GetEnvironmentStringsA()) ) return NULL; pch = penv; /* find out how big a buffer we need */ while ( *pch != '\0' ) { if ( 0 == (str_size = MultiByteToWideChar( __lc_codepage, MB_PRECOMPOSED, pch, -1, NULL, 0 )) ) return 0; total_size += str_size; pch += strlen(pch) + 1; } /* room for final NULL */ total_size++; /* allocate enough space for chars */ if ( NULL == (wbuffer = (wchar_t *) _malloc_crt( total_size * sizeof( wchar_t ) )) ) { FreeEnvironmentStringsA( penv ); return NULL; } /* do the conversion */ pch = penv; pwch = wbuffer; while (*pch != '\0') { if ( 0 == MultiByteToWideChar( __lc_codepage, MB_PRECOMPOSED, pch, -1, pwch, total_size - (pwch - wbuffer) ) ) { _free_crt( wbuffer ); FreeEnvironmentStringsA( penv ); return NULL; } pch += strlen(pch) + 1; pwch += wcslen(pwch) + 1; } *pwch = L'\0'; FreeEnvironmentStringsA( penv ); return (LPVOID)wbuffer; } else /* f_use is neither USE_A nor USE_W */ return NULL; }
void __cdecl _ioinit ( void ) { STARTUPINFO StartupInfo; int cfi_len; int fh; int i; ioinfo *pio; char *posfile; UNALIGNED long *posfhnd; long stdfh; DWORD htype; /* * Allocate and initialize the first array of ioinfo structs. This * array is pointed to by __pioinfo[0] */ if ( (pio = _malloc_crt( IOINFO_ARRAY_ELTS * sizeof(ioinfo) )) == NULL ) { _amsg_exit( _RT_LOWIOINIT ); } __pioinfo[0] = pio; _nhandle = IOINFO_ARRAY_ELTS; for ( ; pio < __pioinfo[0] + IOINFO_ARRAY_ELTS ; pio++ ) { pio->osfile = 0; pio->osfhnd = (long)INVALID_HANDLE_VALUE; pio->pipech = 10; /* linefeed/newline char */ #if defined(_MT) && !defined(DLL_FOR_WIN32S) pio->lockinitflag = 0; /* uninitialized lock */ #endif } /* * Process inherited file handle information, if any */ GetStartupInfo( &StartupInfo ); if ( (StartupInfo.cbReserved2 != 0) && (StartupInfo.lpReserved2 != NULL) ) { /* * Get the number of handles inherited. */ cfi_len = *(UNALIGNED int *)(StartupInfo.lpReserved2); /* * Set pointers to the start of the passed file info and OS * HANDLE values. */ posfile = (char *)(StartupInfo.lpReserved2) + sizeof( int ); posfhnd = (UNALIGNED long *)(posfile + cfi_len); /* * Ensure cfi_len does not exceed the number of supported * handles! */ cfi_len = __min( cfi_len, _NHANDLE_ ); /* * Allocate sufficient arrays of ioinfo structs to hold inherited * file information. */ for ( i = 1 ; _nhandle < cfi_len ; i++ ) { /* * Allocate another array of ioinfo structs */ if ( (pio = _malloc_crt( IOINFO_ARRAY_ELTS * sizeof(ioinfo) )) == NULL ) { /* * No room for another array of ioinfo structs, reduce * the number of inherited handles we process. */ cfi_len = _nhandle; break; } /* * Update __pioinfo[] and _nhandle */ __pioinfo[i] = pio; _nhandle += IOINFO_ARRAY_ELTS; for ( ; pio < __pioinfo[i] + IOINFO_ARRAY_ELTS ; pio++ ) { pio->osfile = 0; pio->osfhnd = (long)INVALID_HANDLE_VALUE; pio->pipech = 10; #if defined(_MT) && !defined(DLL_FOR_WIN32S) pio->lockinitflag = 0; #endif } } /* * Validate and copy the passed file information */ for ( fh = 0 ; fh < cfi_len ; fh++, posfile++, posfhnd++ ) { /* * Copy the passed file info iff it appears to describe * an open, valid file. */ if ( (*posfhnd != (long)INVALID_HANDLE_VALUE) && (*posfile & FOPEN) && (GetFileType( (HANDLE)(*posfhnd) ) != FILE_TYPE_UNKNOWN) ) { pio = _pioinfo( fh ); pio->osfhnd = *posfhnd; pio->osfile = *posfile; } } } /* * If valid HANDLE-s for standard input, output and error were not * inherited, try to obtain them directly from the OS. Also, set the * appropriate bits in the osfile fields. */ for ( fh = 0 ; fh < 3 ; fh++ ) { pio = __pioinfo[0] + fh; if ( pio->osfhnd == (long)INVALID_HANDLE_VALUE ) { /* * mark the handle as open in text mode. */ pio->osfile = (char)(FOPEN | FTEXT); if ( ((stdfh = (long)GetStdHandle( stdhndl(fh) )) != (long)INVALID_HANDLE_VALUE) && ((htype = GetFileType( (HANDLE)stdfh )) != FILE_TYPE_UNKNOWN) ) { /* * obtained a valid HANDLE from GetStdHandle */ pio->osfhnd = stdfh; /* * finish setting osfile: determine if it is a character * device or pipe. */ if ( (htype & 0xFF) == FILE_TYPE_CHAR ) pio->osfile |= FDEV; else if ( (htype & 0xFF) == FILE_TYPE_PIPE ) pio->osfile |= FPIPE; } else { /* * if there is no valid HANDLE, treat the CRT handle as * being open in text mode on a device (with * INVALID_HANDLE_VALUE underlying it). */ pio->osfile |= FDEV; } } else { /* * handle was passed to us by parent process. make * sure it is text mode. */ pio->osfile |= FTEXT; } } /* * Set the number of supported HANDLE-s to _nhandle */ (void)SetHandleCount( (unsigned)_nhandle ); }
FILE * __cdecl _getstream ( void ) { REG2 FILE *retval = NULL; #ifdef _WIN32 REG1 int i; /* Get the iob[] scan lock */ _mlock(_IOB_SCAN_LOCK); /* * Loop through the __piob table looking for a free stream, or the * first NULL entry. */ for ( i = 0 ; i < _nstream ; i++ ) { if ( __piob[i] != NULL ) { /* * if the stream is not inuse, return it. */ if ( !inuse( (FILE *)__piob[i] ) ) { #ifdef _MT _lock_str2(i, __piob[i]); if ( inuse( (FILE *)__piob[i] ) ) { _unlock_str2(i, __piob[i]); continue; } #endif /* _MT */ retval = (FILE *)__piob[i]; break; } } else { /* * allocate a new _FILEX, set _piob[i] to it and return a * pointer to it. */ if ( (__piob[i] = _malloc_crt( sizeof(_FILEX) )) != NULL ) { #if defined (_MT) InitializeCriticalSection( &(((_FILEX *)__piob[i])->lock) ); EnterCriticalSection( &(((_FILEX *)__piob[i])->lock) ); #endif /* defined (_MT) */ retval = (FILE *)__piob[i]; } break; } } /* * Initialize the return stream. */ if ( retval != NULL ) { retval->_flag = retval->_cnt = 0; retval->_tmpfname = retval->_ptr = retval->_base = NULL; retval->_file = -1; } _munlock(_IOB_SCAN_LOCK); #else /* _WIN32 */ #if defined (_M_MPPC) || defined (_M_M68K) REG1 FILE *stream = _iob; /* Loop through the _iob table looking for a free stream.*/ for (; stream <= _lastiob; stream++) { if ( !inuse(stream) ) { stream->_flag = stream->_cnt = 0; stream->_tmpfname = stream->_ptr = stream->_base = NULL; stream->_file = -1; retval = stream; break; } } #endif /* defined (_M_MPPC) || defined (_M_M68K) */ #endif /* _WIN32 */ return(retval); }
int __cdecl _stbuf ( FILE *str ) { REG1 FILE *stream; int index; _ASSERTE(str != NULL); /* Init near stream pointer */ stream = str; /* do nothing if not a tty device */ #ifdef _POSIX_ if (!isatty(fileno(stream))) #else if (!_isatty(_fileno(stream))) #endif return(0); /* Make sure stream is stdout/stderr and init _stdbuf index */ if (stream == stdout) index = 0; else if (stream == stderr) index = 1; else return(0); #ifndef CRTDLL /* force library pre-termination procedure */ _cflush++; #endif /* CRTDLL */ /* Make sure the stream is not already buffered. */ if (anybuf(stream)) return(0); /* Allocate a buffer for this stream if we haven't done so yet. */ if (_stdbuf[index] == NULL) #ifdef _WIN32 if ( (_stdbuf[index]=_malloc_crt(_INTERNAL_BUFSIZ)) == NULL ) #else #if defined(_M_MPPC) || defined(_M_M68K) if ( (_stdbuf[index]=_malloc_crt(BUFSIZ)) == NULL ) #endif #endif return(0); /* error */ /* Set up the buffer */ stream->_ptr = stream->_base = _stdbuf[index]; #ifdef _WIN32 stream->_cnt = stream->_bufsiz = _INTERNAL_BUFSIZ; #else #if defined(_M_MPPC) || defined(_M_M68K) stream->_cnt = stream->_bufsiz = BUFSIZ; #endif #endif stream->_flag |= (_IOWRT | _IOYOURBUF | _IOFLRTN); return(1); }
int __cdecl _cenvarg ( #endif const _TSCHAR * const *argv, const _TSCHAR * const *envp, _TSCHAR **argblk, _TSCHAR **envblk, const _TSCHAR *name ) { REG1 const _TSCHAR * const *vp; REG2 unsigned tmp; REG3 _TSCHAR *cptr; unsigned arg_len; int cfi_len; /* counts the number of file handles in CFI */ /* * Null environment pointer "envp" means use global variable, * "_environ" */ int cwd_start; int cwd_end; /* length of "cwd" strings in environment */ /* * Allocate space for command line string * tmp counts the number of bytes in the command line string * including spaces between arguments * An empty string is special -- 2 bytes */ for (vp = argv, tmp = 2; *vp; tmp += _tcslen(*vp++) + 1) if( tmp > ENV_MAX ) break; /* * Make sure there are not already > 32 KB in strings */ if ((arg_len = tmp) >= ENV_MAX / sizeof(_TSCHAR)) { *envblk = NULL; errno = E2BIG; _doserrno = E_badenv; return(-1); } /* * Allocate space for the command line plus 2 null bytes */ if ( (*argblk = _malloc_crt(tmp * sizeof(_TSCHAR))) == NULL) { *envblk = NULL; errno = ENOMEM; _doserrno = E_nomem; return(-1); } /* * Allocate space for environment strings * tmp counts the number of bytes in the environment strings * including nulls between strings * Also add "_C_FILE_INFO=" string */ if (envp) for (vp = envp, tmp = 2; *vp; tmp += _tcslen(*vp++) + 1) if( tmp > ENV_MAX ) break; /* * The _osfile and _osfhnd arrays are passed as binary data in * dospawn.c */ cfi_len = 0; /* no _C_FILE_INFO */ if (!envp) *envblk = NULL; else { /* * Now that we've decided to pass our own environment block, * compute the size of the "current directory" strings to * propagate to the new environment. */ #ifdef WPRFLAG /* * Make sure wide environment exists. */ if (!_wenvptr) { if ((_wenvptr = (wchar_t *)__crtGetEnvironmentStringsW()) == NULL) return -1; } #endif /* * search for the first one */ for (cwd_start = 0; _tenvptr[cwd_start] != _T('\0') && _tenvptr[cwd_start] != _T('='); cwd_start += _tcslen(&_tenvptr[cwd_start]) + 1) { } /* find the total size of all contiguous ones */ cwd_end = cwd_start; while (_tenvptr[cwd_end+0] == _T('=') && _tenvptr[cwd_end+1] != _T('\0') && _tenvptr[cwd_end+2] == _T(':') && _tenvptr[cwd_end+3] == _T('=')) { cwd_end += 4 + _tcslen(&_tenvptr[cwd_end+4]) + 1; } tmp += cwd_end - cwd_start; /* * Check for too many strings to be placed in the environment * Increment tmp for final null byte after environment strings * "tmp + arg_len + _tcslen(name) + 1" must also be < ENV_MAX */ if( (long) tmp + arg_len + _tcslen(name) > (ENV_MAX - 1) / sizeof(_TSCHAR) ) { _free_crt(*argblk); *argblk = NULL; errno = E2BIG; _doserrno = E_badenv; return(-1); } /* * Allocate space for the environment strings plus extra null byte */ if( !(*envblk = _malloc_crt(tmp * sizeof(_TSCHAR))) ) { _free_crt(*argblk); *argblk = NULL; errno = ENOMEM; _doserrno = E_nomem; return(-1); } } /* * Build the command line by concatenating the argument strings * with spaces between, and two null bytes at the end. * NOTE: The argv[0] argument is followed by a null. */ cptr = *argblk; vp = argv; if (!*vp) /* Empty argument list ? */ ++cptr; /* just two null bytes */ else { /* argv[0] must be followed by a null */ _tcscpy(cptr, *vp); cptr += _tcslen(*vp++) + 1; } while( *vp ) { _tcscpy(cptr, *vp); cptr += _tcslen(*vp++); *cptr++ = ' '; } *cptr = cptr[ -1 ] = _T('\0'); /* remove extra blank, add double null */ /* * Build the environment block by concatenating the environment * strings with nulls between and two null bytes at the end */ cptr = *envblk; if (envp != NULL) { /* * Copy the "cwd" strings to the new environment. */ memcpy(cptr, &_tenvptr[cwd_start], (cwd_end - cwd_start) * sizeof(_TSCHAR)); cptr += cwd_end - cwd_start; /* * Copy the environment strings from "envp". */ vp = envp; while( *vp ) { _tcscpy(cptr, *vp); cptr += 1 + _tcslen(*vp++); } } if (cptr != NULL) { if (cptr == *envblk) { /* * Empty environment block ... this requires two * nulls. */ *cptr++ = _T('\0'); } /* * Extra null terminates the segment */ *cptr = _T('\0'); } return(0); }