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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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" ) );
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
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] );

}
Exemplo n.º 16
0
_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);
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
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 ;

}
Exemplo n.º 19
0
_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;
}
Exemplo n.º 20
0
/***
*_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 */
}
Exemplo n.º 21
0
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);
}
Exemplo n.º 22
0
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;
	}
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
0
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);
}
Exemplo n.º 25
0
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;
}
Exemplo n.º 27
0
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 );
}
Exemplo n.º 28
0
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);
}
Exemplo n.º 29
0
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);
}
Exemplo n.º 30
0
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);
}