예제 #1
0
/***
*errno_t _strerror_s(buffer, sizeInTChars, message) - get system error message
*
*Purpose:
*   builds an error message consisting of the users error message
*   (the message parameter), followed by ": ", followed by the system
*   error message (index through errno), followed by a newline.  If
*   message is NULL or a null string, returns a pointer to just
*   the system error message.
*
*Entry:
*   TCHAR * buffer - Destination buffer.
*   size_t sizeInTChars - Size of the destination buffer.
*   TCHAR * message - user's message to prefix system error message
*
*Exit:
*   The error code.
*
*Exceptions:
*   Input parameters are validated. Refer to the validation section of the function.
*
*******************************************************************************/

#define _MIN_MSG_LENGTH 5

#ifdef _UNICODE
errno_t __cdecl __wcserror_s(
#else  /* _UNICODE */
errno_t __cdecl _strerror_s(
#endif  /* _UNICODE */
    TCHAR* buffer,
    size_t sizeInTChars,
    const _TCHAR *message
    )
{
    errno_t e = 0;

    /* validation section */
    _VALIDATE_RETURN_ERRCODE(buffer != NULL, EINVAL);
    _VALIDATE_RETURN_ERRCODE(sizeInTChars > 0, EINVAL);
    buffer[0] = '\0';

    if (message &&
        *message &&
        _tcslen(message) < (sizeInTChars - 2 - _MIN_MSG_LENGTH))
    {
        _ERRCHECK(_tcscpy_s(buffer, sizeInTChars, message));
        _ERRCHECK(_tcscat_s(buffer, sizeInTChars, _T(": ")));
    }

    /* append the error message at the end of the buffer */
    return _tcserror_s(buffer + _tcslen(buffer), sizeInTChars - _tcslen(buffer), errno);
}
예제 #2
0
파일: strerror.c 프로젝트: jetlive/skiaming
/***
*char *strerror(errnum) - Map error number to error message string.
*
*Purpose:
*       The strerror runtime takes an error number for input and
*       returns the corresponding error message string.  This routine
*       conforms to the ANSI standard interface.
*
*Entry:
*       int errnum - Integer error number (corresponding to an errno value).
*
*Exit:
*       char * - Strerror returns a pointer to the error message string.
*       This string is internal to the strerror routine (i.e., not supplied
*       by the user).
*
*Exceptions:
*       None.
*
*******************************************************************************/

#ifdef _UNICODE
wchar_t * cdecl _wcserror(
#else  /* _UNICODE */
char * __cdecl strerror (
#endif  /* _UNICODE */
        int errnum
        )
{

        _TCHAR *errmsg;
        _ptiddata ptd = _getptd_noexit();
        if (!ptd)
                return _T("Visual C++ CRT: Not enough memory to complete call to strerror.");



        if ( (ptd->_terrmsg == NULL) && ((ptd->_terrmsg =
                        _calloc_crt(_ERRMSGLEN_, sizeof(_TCHAR)))
                        == NULL) )
                return _T("Visual C++ CRT: Not enough memory to complete call to strerror.");
        else
                errmsg = ptd->_terrmsg;


#ifdef _UNICODE
        _ERRCHECK(mbstowcs_s(NULL, errmsg, _ERRMSGLEN_, _get_sys_err_msg(errnum), _ERRMSGLEN_ - 1));
#else  /* _UNICODE */
        _ERRCHECK(strcpy_s(errmsg, _ERRMSGLEN_, _get_sys_err_msg(errnum)));
#endif  /* _UNICODE */

        return(errmsg);
}
예제 #3
0
static Character* __cdecl common_tempnam(
    Character const* const alternative,
    Character const* const prefix,
    int              const block_use,
    char const*      const file_name,
    int              const line_number
    ) throw()
{
    // These are referenced only in the Debug CRT build
    UNREFERENCED_PARAMETER(block_use);
    UNREFERENCED_PARAMETER(file_name);
    UNREFERENCED_PARAMETER(line_number);

    typedef __acrt_stdio_char_traits<Character> stdio_traits;

    Character const* directory = nullptr;
    __crt_unique_heap_ptr<Character const> const directory_cleanup(get_directory(alternative, &directory));

    unsigned const prefix_length = prefix != nullptr
        ? static_cast<unsigned>(stdio_traits::tcslen(prefix))
        : 0;

    // The 12 allows for a backslash, a ten character temporary string, and a
    // null terminator.
    unsigned const buffer_size = static_cast<unsigned>(stdio_traits::tcslen(directory)) + prefix_length + 12;

    __crt_unique_heap_ptr<Character, __crt_public_free_policy> result(
            static_cast<Character*>(_calloc_dbg(
                buffer_size,
                sizeof(Character),
                block_use,
                file_name,
                line_number)));

    if (!result)
        return nullptr;

    *result.get() = 0;
    _ERRCHECK(stdio_traits::tcscat_s(result.get(), buffer_size, directory));

    if (__crt_stdio_path_requires_backslash(directory))
    {
        static Character const backslash[] = { '\\', '\0' };
        _ERRCHECK(stdio_traits::tcscat_s(result.get(), buffer_size, backslash));
    }

    if (prefix != nullptr)
    {
        _ERRCHECK(stdio_traits::tcscat_s(result.get(), buffer_size, prefix));
    }

    Character* const ptr = result.get() + stdio_traits::tcslen(result.get());
    size_t     const ptr_size = buffer_size - (ptr - result.get());

    if (!compute_name(result.get(), ptr, ptr_size, prefix_length))
        return nullptr;

    return result.detach();
}
예제 #4
0
static bool __cdecl initialize_tmpfile_buffer_nolock(buffer_id const buffer_id) throw()
{
    typedef __acrt_stdio_char_traits<Character> stdio_traits;

    Character* const buffer       = get_tmpfile_buffer_nolock<Character>(buffer_id);
    size_t     const buffer_count = L_tmpnam;

    if (!buffer)
    {
        return false;
    }

    // The temporary path must be short enough so that we can append a file name
    // of the form [buffer id][process id].[unique id], which is at most 21
    // characters in length (plus we must leave room for the null terminator).
    //    1 Buffer Id              ("s", "t", or "u")
    //    7 Base-36 Process Id     (maximum: "1z141z3")
    //   13 Base-36 Unique File Id (maximum: "3w5e11264sgsf")
    DWORD const max_supported_temp_path_length = buffer_count - 22;

    // Generate the path prefix; make sure it ends with a slash or backslash:
    // CRT_REFACTOR TODO We need to use the WinRT temp path logic here.
    DWORD const temp_path_length = stdio_traits::get_temp_path(static_cast<DWORD>(buffer_count), buffer);
    if (temp_path_length == 0 || temp_path_length > max_supported_temp_path_length)
    {
        buffer[0] = '\0';
        return false;
    }

    Character* tail = buffer + temp_path_length;

    auto tail_count = [&]() {
        return buffer_count - (tail - buffer);
    };

    // Append the buffer identifier part of the file name:
    switch (buffer_id)
    {
    case buffer_id::tmpnam:
        *tail++ = sizeof(Character) == 1 ? 's' : 'v';
        break;
    case buffer_id::tmpfile:
        *tail++ = sizeof(Character) == 1 ? 't' : 'w';
        break;
    case buffer_id::tmpnam_s:
        *tail++ = sizeof(Character) == 1 ? 'u' : 'x';
        break;
    }

    // Append the process identifier part of the file name:
    _ERRCHECK(stdio_traits::ulltot_s(GetCurrentProcessId(), tail, tail_count(), 36));
    tail += stdio_traits::tcslen(tail);

    // Append the dot part of the file name and the initial unique id:
    *tail++ = '.';
    *tail++ = '0';
    *tail++ = '\0';

    return true;
}
예제 #5
0
wchar_t * __cdecl _wcsdup (
        const wchar_t * string
        )

#endif  /* _DEBUG */

{
        wchar_t *memory;
    size_t size = 0;

        if (!string)
                return(NULL);

    size = wcslen(string) + 1;
#ifdef _DEBUG
        if (memory = (wchar_t *) _calloc_dbg(size, sizeof(wchar_t), nBlockUse, szFileName, nLine))
#else  /* _DEBUG */
        if (memory = (wchar_t *) calloc(size, sizeof(wchar_t)))
#endif  /* _DEBUG */
        {
                _ERRCHECK(wcscpy_s(memory, size, string));
        return memory;
        }

        return(NULL);
}
예제 #6
0
파일: strerror.c 프로젝트: jetlive/skiaming
/***
*errno_t strerror_s(buffer, sizeInTChars, errnum) - Map error number to error message string.
*
*Purpose:
*       The strerror_s runtime takes an error number for input and
*       copies the corresponding error message string in the destination
*       buffer. If the buffer is too small, the message is truncated.
*
*Entry:
*       TCHAR * buffer - Destination buffer.
*       size_t sizeInTChars - Size of the destination buffer.
*       int errnum - Integer error number (corresponding to an errno value).
*
*Exit:
*       The error code.
*
*Exceptions:
*       Input parameters are validated. Refer to the validation section of the function.
*
*******************************************************************************/

#ifdef _UNICODE
errno_t __cdecl _wcserror_s(
#else  /* _UNICODE */
errno_t __cdecl strerror_s(
#endif  /* _UNICODE */
        TCHAR* buffer,
        size_t sizeInTChars,
        int errnum
        )
{
        errno_t e = 0;

        /* validation section */
        _VALIDATE_RETURN_ERRCODE(buffer != NULL, EINVAL);
        _VALIDATE_RETURN_ERRCODE(sizeInTChars > 0, EINVAL);

        /* we use mbstowcs_s or strncpy_s because we want to truncate the error string
         * if the destination is not big enough
         */
#ifdef _UNICODE
        e = _ERRCHECK_EINVAL_ERANGE(mbstowcs_s(NULL, buffer, sizeInTChars, _get_sys_err_msg(errnum), _TRUNCATE));
        /* ignore the truncate information */
        if (e == STRUNCATE)
        {
                e = 0;
        }
#else  /* _UNICODE */
        _ERRCHECK(strncpy_s(buffer, sizeInTChars, _get_sys_err_msg(errnum), sizeInTChars - 1));
#endif  /* _UNICODE */
    return e;
}
예제 #7
0
char * __cdecl _strdup (
        const char * string
        )

#endif  /* _DEBUG */

{
        char *memory;
    size_t size = 0;

        if (!string)
                return(NULL);

    size = strlen(string) + 1;
#ifdef _DEBUG
        if (memory = _malloc_dbg(size, nBlockUse, szFileName, nLine))
#else  /* _DEBUG */
        if (memory = malloc(size))
#endif  /* _DEBUG */
        {
                _ERRCHECK(strcpy_s(memory, size, string));
        return memory;
        }

        return(NULL);
}
예제 #8
0
static bool __cdecl compute_name(
    Character const* const path_buffer,
    Character*       const suffix_pointer,
    size_t           const suffix_count,
    size_t           const prefix_length
    ) throw()
{
    typedef __acrt_stdio_char_traits<Character> stdio_traits;

    // Re-initialize _tempoff if necessary.  If we don't re-init _tempoff, we
    // can get into an infinate loop (e.g., (a) _tempoff is a big number on
    // entry, (b) prefix is a long string (e.g., 8 chars) and all tempfiles
    // with that prefix exist, (c) _tempoff will never equal first and we'll
    // loop forever).

    // [NOTE: To avoid a conflict that causes the same bug as that discussed
    // above, _tempnam() uses _tempoff; tmpnam() uses _tmpoff]

    bool return_value = false;

    __acrt_lock(__acrt_tempnam_lock);
    __try
    {
        if (_old_pfxlen < prefix_length)
            _tempoff = 1;

        _old_pfxlen = static_cast<unsigned int>(prefix_length);

        unsigned const first = _tempoff;

        errno_t const saved_errno = errno;
        do
        {
            ++_tempoff;
            if (_tempoff - first > _TMP_MAX_S)
            {
                errno = saved_errno;
                __leave;
            }

            // The maximum length string returned by the conversion is ten
            // characters, assuming a 32-bit unsigned integer, so there is
            // sufficient room in the result buffer for it.
            _ERRCHECK(stdio_traits::ultot_s(_tempoff, suffix_pointer, suffix_count, 10));
            errno = 0;
        }
        while (stdio_traits::taccess_s(path_buffer, 0) == 0 || errno == EACCES);

        errno = saved_errno;
        return_value = true;
    }
    __finally
    {
        __acrt_unlock(__acrt_tempnam_lock);
    }

    return return_value;
}
예제 #9
0
파일: ftime64.c 프로젝트: flychen50/clib
_CRTIMP errno_t __cdecl _ftime64_s (
        struct __timeb64 *tp
        )
{
        FT nt_time;
        __time64_t t;
        TIME_ZONE_INFORMATION tzinfo;
        DWORD tzstate;
        long timezone = 0;

        _VALIDATE_RETURN_ERRCODE( ( tp != NULL ), EINVAL )

        __tzset();

        _ERRCHECK(_get_timezone(&timezone));
        tp->timezone = (short)(timezone / 60);

        GetSystemTimeAsFileTime( &(nt_time.ft_struct) );

        /*
         * Obtain the current DST status. Note the status is cached and only
         * updated once per minute, if necessary.
         */
        if ( (t = (__time64_t)(nt_time.ft_scalar / 600000000i64))
             != elapsed_minutes_cache )
        {
            if ( (tzstate = GetTimeZoneInformation( &tzinfo )) != 0xFFFFFFFF )
            {
                /*
                 * Must be very careful in determining whether or not DST is
                 * really in effect.
                 */
                if ( (tzstate == TIME_ZONE_ID_DAYLIGHT) &&
                     (tzinfo.DaylightDate.wMonth != 0) &&
                     (tzinfo.DaylightBias != 0) )
                    dstflag_cache = DAYLIGHT_TIME;
                else
                    /*
                     * When in doubt, assume standard time
                     */
                    dstflag_cache = STANDARD_TIME;
            }
            else
                dstflag_cache = UNKNOWN_TIME;

            elapsed_minutes_cache = t;
        }

        tp->dstflag = (short)dstflag_cache;

        tp->millitm = (unsigned short)((nt_time.ft_scalar / 10000i64) %
                      1000i64);

        tp->time = (__time64_t)((nt_time.ft_scalar - EPOCH_BIAS) / 10000000i64);

        return 0;
}
예제 #10
0
파일: findf64.c 프로젝트: flychen50/clib
intptr_t __cdecl _tfindfirst64i32(
        const _TSCHAR * szWild,
        struct _tfinddata64i32_t * pfd
        )

#endif  /* _USE_INT64 */

{
        WIN32_FIND_DATA wfd;
        HANDLE          hFile;
        DWORD           err;

        _VALIDATE_RETURN( (pfd != NULL), EINVAL, -1);

        /* We assert to make sure the underlying Win32 struct WIN32_FIND_DATA's
        cFileName member doesn't have an array size greater than ours */

        _VALIDATE_RETURN( (sizeof(pfd->name) <= sizeof(wfd.cFileName)), ENOMEM, -1);
        _VALIDATE_RETURN( (szWild != NULL), EINVAL, -1);

        if ((hFile = FindFirstFile(szWild, &wfd)) == INVALID_HANDLE_VALUE) {
            err = GetLastError();
            switch (err) {
                case ERROR_NO_MORE_FILES:
                case ERROR_FILE_NOT_FOUND:
                case ERROR_PATH_NOT_FOUND:
                    errno = ENOENT;
                    break;

                case ERROR_NOT_ENOUGH_MEMORY:
                    errno = ENOMEM;
                    break;

                default:
                    errno = EINVAL;
                    break;
            }
            return (-1);
        }

        pfd->attrib       = (wfd.dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
                            ? 0 : wfd.dwFileAttributes;
        pfd->time_create  = __time64_t_from_ft(&wfd.ftCreationTime);
        pfd->time_access  = __time64_t_from_ft(&wfd.ftLastAccessTime);
        pfd->time_write   = __time64_t_from_ft(&wfd.ftLastWriteTime);
#if _USE_INT64
        pfd->size         = ((__int64)(wfd.nFileSizeHigh)) * (0x100000000i64) +
                            (__int64)(wfd.nFileSizeLow);
#else  /* _USE_INT64 */
    pfd->size         = wfd.nFileSizeLow;
#endif  /* _USE_INT64 */

        _ERRCHECK(_tcscpy_s(pfd->name, _countof(pfd->name), wfd.cFileName));

        return ((intptr_t)hFile);
}
예제 #11
0
/***
*char *_strerror(message) - get system error message
*
*Purpose:
*   builds an error message consisting of the users error message
*   (the message parameter), followed by ": ", followed by the system
*   error message (index through errno), followed by a newline.  If
*   message is NULL or a null string, returns a pointer to just
*   the system error message.
*
*Entry:
*   char *message - user's message to prefix system error message
*
*Exit:
*   returns pointer to static memory containing error message.
*   returns NULL if malloc() fails in multi-thread versions.
*
*Exceptions:
*
*******************************************************************************/

#ifdef _UNICODE
wchar_t * __cdecl __wcserror(
#else  /* _UNICODE */
char * __cdecl _strerror (
#endif  /* _UNICODE */
    const _TCHAR *message
    )
{
    const char *sysErrorMsg = NULL;
    _TCHAR *bldmsg;
    _ptiddata ptd = _getptd_noexit();
    if (!ptd)
        return NULL;

    /* Use per thread buffer area (malloc space, if necessary) */
    /* [NOTE: This buffer is shared between _strerror and streror.] */

    if ( (ptd->_terrmsg == NULL) && ((ptd->_terrmsg =
            _calloc_crt(_ERRMSGLEN_, sizeof(_TCHAR))) == NULL) )
            return(NULL);
    bldmsg = ptd->_terrmsg;

    /* Build the error message */

    bldmsg[0] = '\0';

    if (message && *message) {
        // should leave space for ": \n\0"
        _ERRCHECK(_tcsncat_s( bldmsg, _ERRMSGLEN_, message, _ERRMSGLEN_-4 ));
        _ERRCHECK(_tcscat_s( bldmsg, _ERRMSGLEN_, _T(": ")));
    }

    //  We should have extra space for "\n\0"
    sysErrorMsg = _get_sys_err_msg(errno);

#ifdef _UNICODE
    _ERRCHECK(mbstowcs_s(NULL, bldmsg + wcslen(bldmsg), _ERRMSGLEN_ - wcslen(bldmsg), sysErrorMsg, _ERRMSGLEN_ - wcslen(bldmsg) - 2));
#else  /* _UNICODE */
    _ERRCHECK(strncat_s(bldmsg, _ERRMSGLEN_, sysErrorMsg, _ERRMSGLEN_ - strlen(bldmsg) - 2));
#endif  /* _UNICODE */

    _ERRCHECK(_tcscat_s( bldmsg, _ERRMSGLEN_, _T("\n")));
    return bldmsg;
}
예제 #12
0
파일: findf64.c 프로젝트: flychen50/clib
int __cdecl _tfindnext64i32(intptr_t hFile, struct _tfinddata64i32_t * pfd)

#endif  /* _USE_INT64 */

{
        WIN32_FIND_DATA wfd;
        DWORD           err;

        _VALIDATE_RETURN( ((HANDLE)hFile != INVALID_HANDLE_VALUE), EINVAL, -1);
        _VALIDATE_RETURN( (pfd != NULL), EINVAL, -1);
        _VALIDATE_RETURN( (sizeof(pfd->name) <= sizeof(wfd.cFileName)), ENOMEM, -1);

        if (!FindNextFile((HANDLE)hFile, &wfd)) {
            err = GetLastError();
            switch (err) {
                case ERROR_NO_MORE_FILES:
                case ERROR_FILE_NOT_FOUND:
                case ERROR_PATH_NOT_FOUND:
                    errno = ENOENT;
                    break;

                case ERROR_NOT_ENOUGH_MEMORY:
                    errno = ENOMEM;
                    break;

                default:
                    errno = EINVAL;
                    break;
            }
            return (-1);
        }

        pfd->attrib       = (wfd.dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
                            ? 0 : wfd.dwFileAttributes;
        pfd->time_create  = __time64_t_from_ft(&wfd.ftCreationTime);
        pfd->time_access  = __time64_t_from_ft(&wfd.ftLastAccessTime);
        pfd->time_write   = __time64_t_from_ft(&wfd.ftLastWriteTime);
#if _USE_INT64
        pfd->size         = ((__int64)(wfd.nFileSizeHigh)) * (0x100000000i64) +
                            (__int64)(wfd.nFileSizeLow);
#else  /* _USE_INT64 */
        pfd->size         = wfd.nFileSizeLow;
#endif  /* _USE_INT64 */

        _ERRCHECK(_tcscpy_s(pfd->name, _countof(pfd->name), wfd.cFileName));

        return (0);
}
예제 #13
0
__RELIABILITY_CONTRACT
const char * type_info::_Name_base(const type_info *_This,__type_info_node* __ptype_info_node)
{
        void *pTmpUndName;
        size_t len;

        if (_This->_m_data == NULL) {
            if ((pTmpUndName = __unDNameHelper(NULL,
                                               (_This->_m_d_name)+1,
                                               0,
                                               0)) == NULL)
                return NULL;

            /*
             * Pad all the trailing spaces with null. Note that len-- > 0 is used
             * at left side which depends on operator associativity. Also note
             * that len will be used later so don't trash.
             */
            for (len=strlen((char *)pTmpUndName); len-- > 0 && ((char *)pTmpUndName)[len] == ' ';) {
                ((char *)pTmpUndName)[len] = '\0';
            }

            bool _MustReleaseLock = false;
            __PREPARE_CONSTRAINED_REGION
            __TRY
                __BEGIN_CONSTRAINED_REGION
                    System::Threading::Thread::BeginThreadAffinity();
                    _mlock(_TYPEINFO_LOCK);
                    _MustReleaseLock = true;
                __END_CONSTRAINED_REGION
                /*
                 * We need to check if this->_m_data is still NULL, this will
                 * prevent the memory leak.
                 */
                if (_This->_m_data == NULL) {
                    /*
                     * allocate a node which will store the pointer to the memory
                     * allocated for this->_m_data. We need to store all this in
                     * linklist so that we can free them as process exit. Note
                     * that __clean_type_info_names is freeing this memory.
                     */
                    __type_info_node *pNode = (__type_info_node *)_malloc_base(sizeof(__type_info_node));
                    if (pNode != NULL) {

                        /*
                         * We should be doing only if we are sucessful in allocating
                         * node pointer. Note that we need to add 2 to len, this
                         * is because len = strlen(pTmpUndName)-1.
                         */
                        if ((((type_info *)_This)->_m_data = _malloc_base(len+2)) != NULL) {
                            _ERRCHECK(strcpy_s ((char *)((type_info *)_This)->_m_data, len+2, (char *)pTmpUndName));
                            pNode->memPtr = _This->_m_data;

                            /*
                             * Add this to global linklist. Note that we always
                             * add this as second element in linklist.
                             */
                            pNode->next = __ptype_info_node->next;
                            __ptype_info_node->next = pNode;
                        } else {
                            /*
                             * Free node pointer as there is no allocation for
                             * this->_m_data, this means that we don't really
                             * need this in the link list.
                             */
                            _free_base(pNode);
                        }
                    }
                }
                /*
                 * Free the temporary undecorated name.
                 */
                _free_base (pTmpUndName);
            __FINALLY
                if (_MustReleaseLock)
                {
                    _munlock(_TYPEINFO_LOCK);
                    System::Threading::Thread::EndThreadAffinity();
                }
            __END_TRY_FINALLY


        }

        return (char *) _This->_m_data;
}
예제 #14
0
int __set_loosefpmath(void)
{
    _ERRCHECK(_controlfp_s(NULL, _DN_FLUSH, _MCW_DN));
    return 0;
}
예제 #15
0
static __time64_t __cdecl _make__time64_t (
        struct tm *tb,
        int ultflag
        )
{
        __time64_t tmptm1, tmptm2, tmptm3;
        struct tm tbtemp;
        long dstbias = 0;
        long timezone = 0;

        _VALIDATE_RETURN( ( tb != NULL ), EINVAL, ( ( __time64_t )( -1 ) ) )

        /*
         * First, make sure tm_year is reasonably close to being in range.
         */
        if ( ((tmptm1 = tb->tm_year) < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR64
          + 1) )
            goto err_mktime;


        /*
         * Adjust month value so it is in the range 0 - 11.  This is because
         * we don't know how many days are in months 12, 13, 14, etc.
         */

        if ( (tb->tm_mon < 0) || (tb->tm_mon > 11) ) {

            tmptm1 += (tb->tm_mon / 12);

            if ( (tb->tm_mon %= 12) < 0 ) {
                tb->tm_mon += 12;
                tmptm1--;
            }

            /*
             * Make sure year count is still in range.
             */
            if ( (tmptm1 < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR64 + 1) )
                goto err_mktime;
        }

        /***** HERE: tmptm1 holds number of elapsed years *****/

        /*
         * Calculate days elapsed minus one, in the given year, to the given
         * month. Check for leap year and adjust if necessary.
         */
        tmptm2 = _days[tb->tm_mon];
        if ( _IS_LEAP_YEAR(tmptm1) && (tb->tm_mon > 1) )
                tmptm2++;

        /*
         * Calculate elapsed days since base date (midnight, 1/1/70, UTC)
         *
         *
         * 365 days for each elapsed year since 1970, plus one more day for
         * each elapsed leap year. no danger of overflow because of the range
         * check (above) on tmptm1.
         */
        tmptm3 = (tmptm1 - _BASE_YEAR) * 365 + _ELAPSED_LEAP_YEARS(tmptm1);

        /*
         * elapsed days to current month (still no possible overflow)
         */
        tmptm3 += tmptm2;

        /*
         * elapsed days to current date.
         */
        tmptm1 = tmptm3 + (tmptm2 = (__time64_t)(tb->tm_mday));

        /***** HERE: tmptm1 holds number of elapsed days *****/

        /*
         * Calculate elapsed hours since base date
         */
        tmptm2 = tmptm1 * 24;

        tmptm1 = tmptm2 + (tmptm3 = (__time64_t)tb->tm_hour);

        /***** HERE: tmptm1 holds number of elapsed hours *****/

        /*
         * Calculate elapsed minutes since base date
         */

        tmptm2 = tmptm1 * 60;

        tmptm1 = tmptm2 + (tmptm3 = (__time64_t)tb->tm_min);

        /***** HERE: tmptm1 holds number of elapsed minutes *****/

        /*
         * Calculate elapsed seconds since base date
         */

        tmptm2 = tmptm1 * 60;

        tmptm1 = tmptm2 + (tmptm3 = (__time64_t)tb->tm_sec);

        /***** HERE: tmptm1 holds number of elapsed seconds *****/

        if  ( ultflag ) {

            /*
             * Adjust for timezone. No need to check for overflow since
             * localtime() will check its arg value
             */

            __tzset();

            _ERRCHECK(_get_dstbias(&dstbias));
            _ERRCHECK(_get_timezone(&timezone));

            tmptm1 += timezone;

            /*
             * Convert this second count back into a time block structure.
             * If localtime returns NULL, return an error.
             */
            if ( _localtime64_s(&tbtemp, &tmptm1) != 0 )
                goto err_mktime;

            /*
             * Now must compensate for DST. The ANSI rules are to use the
             * passed-in tm_isdst flag if it is non-negative. Otherwise,
             * compute if DST applies. Recall that tbtemp has the time without
             * DST compensation, but has set tm_isdst correctly.
             */
            if ( (tb->tm_isdst > 0) || ((tb->tm_isdst < 0) &&
              (tbtemp.tm_isdst > 0)) ) {
                tmptm1 += dstbias;
                if ( _localtime64_s(&tbtemp, &tmptm1) != 0 )
                    goto err_mktime;
            }

        }
        else {
            if ( _gmtime64_s(&tbtemp, &tmptm1) != 0)
                goto err_mktime;
        }

        /***** HERE: tmptm1 holds number of elapsed seconds, adjusted *****/
        /*****       for local time if requested                      *****/

        *tb = tbtemp;
        return tmptm1;

err_mktime:
        /*
         * All errors come to here
         */

        errno = EINVAL;
        return (__time64_t)(-1);
}
예제 #16
0
파일: w_map.c 프로젝트: mysticTot/learn_c
static int __cdecl __crtLCMapStringW_stat(
    _locale_t plocinfo,
    LCID     Locale,
    DWORD    dwMapFlags,
    LPCWSTR  lpSrcStr,
    int      cchSrc,
    LPWSTR   lpDestStr,
    int      cchDest,
    int      code_page
) {
    static int f_use = 0;

    /*
     * 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 (0 != LCMapStringW(0, LCMAP_LOWERCASE, L"\0", 1, NULL, 0)) {
            f_use = USE_W;
        } else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
            f_use = USE_A;
        }
    }

    /*
     * LCMapString will map past NULL. Must find NULL if in string
     * before cchSrc wide characters.
     */
    if (cchSrc > 0) {
        cchSrc = wcsncnt(lpSrcStr, cchSrc);
    }

    /* Use "W" version */

    if (USE_W == f_use) {
        return LCMapStringW(Locale, dwMapFlags, lpSrcStr, cchSrc,
                            lpDestStr, cchDest);
    }

    /* Use "A" version */

    if (USE_A == f_use || f_use == 0) {
        int retval = 0;
        int inbuff_size;
        int outbuff_size;
        unsigned char* inbuffer = NULL;
        unsigned char* outbuffer = NULL;
        int AnsiCP = 0;

        /*
         * Convert string and return the requested information. Note that
         * we are converting to a multibyte string so there is not a
         * one-to-one correspondence between number of wide chars in the
         * input string and the number of *bytes* in the buffer. However,
         * there had *better be* a one-to-one correspondence between the
         * number of wide characters and the number of multibyte characters
         * (enforced by WC_SEPCHARS) in the buffer or the resulting mapped
         * string will be worthless to the user.
         *
         */

        /*
         * Use __lc_codepage for conversion if code_page not specified
         */

        if (0 == Locale) {
            Locale = plocinfo->locinfo->lc_handle[LC_CTYPE];
        }

        if (0 == code_page) {
            code_page = plocinfo->locinfo->lc_codepage;
        }

        /*
         * Always use Ansi codepage with Ansi WinAPI because they use
         * Ansi codepage
         */
        if (code_page != (AnsiCP = __ansicp(Locale))) {
            if (AnsiCP != -1) {
                code_page = AnsiCP;
            }
        }

        /* find out how big a buffer we need (includes NULL if any) */
        if (0 == (inbuff_size = WideCharToMultiByte(code_page,
                                0,
                                lpSrcStr,
                                cchSrc,
                                NULL,
                                0,
                                NULL,
                                NULL))) {
            return 0;
        }

        /* allocate enough space for chars */
        inbuffer = (unsigned char*)_calloca(inbuff_size, sizeof(char));

        if (inbuffer == NULL) {
            return 0;
        }

        /* do the conversion */
        if (0 ==  WideCharToMultiByte(code_page,
                                      0,
                                      lpSrcStr,
                                      cchSrc,
                                      (char*)inbuffer,
                                      inbuff_size,
                                      NULL,
                                      NULL)) {
            goto error_cleanup;
        }

        /* get size required for string mapping */
        if (0 == (outbuff_size = LCMapStringA(Locale,
                                              dwMapFlags,
                                              (const char*)inbuffer,
                                              inbuff_size,
                                              NULL,
                                              0))) {
            goto error_cleanup;
        }

        /* allocate enough space for chars and NULL */
        outbuffer = (unsigned char*)_calloca(outbuff_size, sizeof(char));

        if (outbuffer == NULL) {
            goto error_cleanup;
        }

        /* do string mapping */
        if (0 == LCMapStringA(Locale,
                              dwMapFlags,
                              (const char*)inbuffer,
                              inbuff_size,
                              (char*)outbuffer,
                              outbuff_size)) {
            goto error_cleanup;
        }

        if (dwMapFlags & LCMAP_SORTKEY) {
            /* outbuff_size > cchDest is allowed */
            retval = outbuff_size;

            if (0 != cchDest)
                /* SORTKEY returns BYTES, just copy */
                _ERRCHECK(strncpy_s((char*)lpDestStr,
                                    cchDest,
                                    (char*)outbuffer,
                                    cchDest <= outbuff_size ? cchDest - 1 : outbuff_size));
        } else {
            if (0 == cchDest) {
                /* get size required */
                if (0 == (retval = MultiByteToWideChar(code_page,
                                                       MB_PRECOMPOSED,
                                                       (const char*)outbuffer,
                                                       outbuff_size,
                                                       NULL,
                                                       0))) {
                    goto error_cleanup;
                }
            } else {
                /* convert mapping */
                if (0 == (retval = MultiByteToWideChar(code_page,
                                                       MB_PRECOMPOSED,
                                                       (const char*)outbuffer,
                                                       outbuff_size,
                                                       lpDestStr,
                                                       cchDest))) {
                    goto error_cleanup;
                }
            }
        }

    error_cleanup:

        if (outbuffer != NULL) {
            _freea(outbuffer);
        }

        _freea(inbuffer);
        return retval;
    } else { /* f_use is neither USE_A nor USE_W */
        return 0;
    }
}
예제 #17
0
파일: popen.c 프로젝트: flychen50/clib
FILE * __cdecl _tpopen (
        const _TSCHAR *cmdstring,
        const _TSCHAR *type
        )
{

        int phdls[2];             /* I/O handles for pipe */
        int ph_open[2];           /* flags, set if correspond phdls is open */
        int i1;                   /* index into phdls[] */
        int i2;                   /* index into phdls[] */

        int tm = 0;               /* flag indicating text or binary mode */

        int stdhdl;               /* either STDIN or STDOUT */

        HANDLE newhnd;            /* ...in calls to DuplicateHandle API */

        FILE *pstream = NULL;     /* stream to be associated with pipe */

        HANDLE prochnd;           /* handle for current process */

        _TSCHAR *cmdexe;          /* pathname for the command processor */
        _TSCHAR *envbuf = NULL;   /* buffer for the env variable */
        intptr_t childhnd;        /* handle for child process (cmd.exe) */

        IDpair *locidpair;        /* pointer to IDpair table entry */
        _TSCHAR *buf = NULL, *pfin, *env;
        _TSCHAR *CommandLine;
        size_t CommandLineSize = 0;
        _TSCHAR _type[3] = {0, 0, 0};

        /* Info for spawning the child. */
        STARTUPINFO StartupInfo;  /* Info for spawning a child */
        BOOL childstatus = 0;
        PROCESS_INFORMATION ProcessInfo; /* child process information */

        errno_t save_errno;

        int fh_lock_held = 0;
        int popen_lock_held = 0;

        /* first check for errors in the arguments
         */
        _VALIDATE_RETURN((cmdstring != NULL), EINVAL,NULL);
        _VALIDATE_RETURN((type != NULL), EINVAL,NULL);

        while (*type == _T(' '))
        {
            type++;
        }
        _VALIDATE_RETURN(((*type == _T('w')) || (*type == _T('r'))), EINVAL,NULL);
        _type[0] = *type;
        ++type;
        while (*type == _T(' '))
        {
            ++type;
        }
        _VALIDATE_RETURN(((*type == 0) || (*type == _T('t')) || (*type == _T('b'))), EINVAL, NULL);
        _type[1] = *type;

        /* do the _pipe(). note that neither of the resulting handles will
         * be inheritable.
         */

        if ( _type[1] == _T('t') )
                tm = _O_TEXT;
        else if ( _type[1] == _T('b') )
                tm = _O_BINARY;

        tm |= _O_NOINHERIT;

        if ( _pipe( phdls, PSIZE, tm ) == -1 )
                goto error1;

        /* test _type[0] and set stdhdl, i1 and i2 accordingly.
         */
        if ( _type[0] == _T('w') ) {
                stdhdl = STDIN;
                i1 = 0;
                i2 = 1;
        }
        else {
                stdhdl = STDOUT;
                i1 = 1;
                i2 = 0;
        }

        /* ASSERT LOCK FOR IDPAIRS HERE!!!!
         */
        if ( !_mtinitlocknum( _POPEN_LOCK )) {
            _close( phdls[0] );
            _close( phdls[1] );
            return NULL;
        }
        _mlock( _POPEN_LOCK );
        __try
        {

        /* set flags to indicate pipe handles are open. note, these are only
         * used for error recovery.
         */
        ph_open[ 0 ] = ph_open[ 1 ] = 1;


        /* get the process handle, it will be needed in some API calls
         */
        prochnd = GetCurrentProcess();



        if ( !DuplicateHandle( prochnd,
                               (HANDLE)_osfhnd( phdls[i1] ),
                               prochnd,
                               &newhnd,
                               0L,
                               TRUE,                    /* inheritable */
                               DUPLICATE_SAME_ACCESS )
        ) {
                goto error2;
        }
        (void)_close( phdls[i1] );
        ph_open[ i1 ] = 0;

        /* associate a stream with phdls[i2]. note that if there are no
         * errors, pstream is the return value to the caller.
         */
        if ( (pstream = _tfdopen( phdls[i2], _type )) == NULL )
                goto error2;

        /* next, set locidpair to a free entry in the idpairs table.
         */
        if ( (locidpair = idtab( NULL )) == NULL )
                goto error3;


        /* Find what to use. command.com or cmd.exe */
        if ( (_ERRCHECK_EINVAL(_tdupenv_s_crt(&envbuf, NULL, _T("COMSPEC"))) != 0) || (envbuf == NULL) )
        {
            unsigned int osver = 0;
            _get_osver(&osver);
            cmdexe = ( osver & 0x8000 ) ? _T("command.com") : _T("cmd.exe");
        }
        else
        {
            cmdexe = envbuf;
        }

        /*
         * Initialise the variable for passing to CreateProcess
         */

        memset(&StartupInfo, 0, sizeof(StartupInfo));
        StartupInfo.cb = sizeof(StartupInfo);

        /* Used by os for duplicating the Handles. */

        StartupInfo.dwFlags = STARTF_USESTDHANDLES;
        StartupInfo.hStdInput = stdhdl == STDIN ? (HANDLE) newhnd
                                                : (HANDLE) _osfhnd(0);
        StartupInfo.hStdOutput = stdhdl == STDOUT ? (HANDLE) newhnd
                                                  : (HANDLE) _osfhnd(1);
        StartupInfo.hStdError = (HANDLE) _osfhnd(2);


        CommandLineSize = _tcslen(cmdexe) + _tcslen(_T(" /c ")) + (_tcslen(cmdstring)) +1;
        if ((CommandLine = _calloc_crt( CommandLineSize, sizeof(_TSCHAR))) == NULL)
            goto error3;
        _ERRCHECK(_tcscpy_s(CommandLine, CommandLineSize, cmdexe));
        _ERRCHECK(_tcscat_s(CommandLine, CommandLineSize, _T(" /c ")));
        _ERRCHECK(_tcscat_s(CommandLine, CommandLineSize, cmdstring));

        /* Check if cmdexe can be accessed. If yes CreateProcess else try
         * searching path.
         */
        save_errno = errno;
        if (_taccess_s(cmdexe, 0) == 0) {
            childstatus = CreateProcess( (LPTSTR) cmdexe,
                                         (LPTSTR) CommandLine,
                                         NULL,
                                         NULL,
                                         TRUE,
                                         0,
                                         NULL,
                                         NULL,
                                         &StartupInfo,
                                         &ProcessInfo
                                         );
        }
        else {
            TCHAR* envPath = NULL;
            size_t envPathSize = 0;
            if ((buf = _calloc_crt(_MAX_PATH, sizeof(_TSCHAR))) == NULL)
            {
                _free_crt(buf);
                _free_crt(CommandLine);
                _free_crt(envbuf);
                cmdexe = NULL;
                errno = save_errno;
                goto error3;
            }
            if (_ERRCHECK_EINVAL(_tdupenv_s_crt(&envPath, NULL, _T("PATH"))) != 0)
            {
                _free_crt(envPath);
                _free_crt(buf);
                _free_crt(CommandLine);
                _free_crt(envbuf);
                cmdexe = NULL;
                errno = save_errno;
                goto error3;
            }
            env = envPath;

#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;

#ifdef _MBCS
                if (*pfin == SLASHCHAR) {
                    if (pfin != _mbsrchr(buf, SLASHCHAR))
                        _ERRCHECK(strcat_s(buf, _MAX_PATH, SLASH));
                }
                else if (*pfin != XSLASHCHAR)
                    _ERRCHECK(strcat_s(buf, _MAX_PATH, SLASH));

#else  /* _MBCS */
                if (*pfin != SLASHCHAR && *pfin != XSLASHCHAR)
                    _ERRCHECK(_tcscat_s(buf, _MAX_PATH, 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(cmdexe)) < _MAX_PATH )
                    _ERRCHECK(_tcscat_s(buf, _MAX_PATH, cmdexe));
                else
                    break;

                /* Check if buf can be accessed. If yes CreateProcess else try
                 * again.
                 */
                if (_taccess_s(buf, 0) == 0) {
                    childstatus = CreateProcess( (LPTSTR) buf,
                                                 CommandLine,
                                                 NULL,
                                                 NULL,
                                                 TRUE,
                                                 0,
                                                 NULL,
                                                 NULL,
                                                 &StartupInfo,
                                                 &ProcessInfo
                                                 );
                    break;
                }
            }
            _free_crt(envPath);
            _free_crt(buf);
        }
        _free_crt(CommandLine);
        _free_crt(envbuf);
        cmdexe = NULL;
        CloseHandle((HANDLE)newhnd);
        CloseHandle((HANDLE)ProcessInfo.hThread);
                errno = save_errno;

        /* check if the CreateProcess was sucessful.
         */
        if ( childstatus)
            childhnd = (intptr_t)ProcessInfo.hProcess;
        else
            goto error4;
        locidpair->prochnd = childhnd;
        locidpair->stream = pstream;

        /* success, return the stream to the caller
         */
        goto done;

        /**
         * error handling code. all detected errors end up here, entering
         * via a goto one of the labels. note that the logic is currently
         * a straight fall-thru scheme (e.g., if entered at error4, the
         * code for error4, error3,...,error1 is all executed).
         **********************************************************************/

error4:         /* make sure locidpair is reusable
                 */
                locidpair->stream = NULL;

error3:         /* close pstream (also, clear ph_open[i2] since the stream
                 * close will also close the pipe handle)
                 */
                (void)fclose( pstream );
                ph_open[ i2 ] = 0;
                pstream = NULL;

error2:         /* close handles on pipe (if they are still open)
                 */

                if ( ph_open[i1] )
                        _close( phdls[i1] );
                if ( ph_open[i2] )
                        _close( phdls[i2] );
done:

        ;}
        __finally {
            _munlock(_POPEN_LOCK);
        }


error1:
        return pstream;
}

#ifndef _UNICODE

/***
*int _pclose(pstream) - wait on a child command and close the stream on the
*   associated pipe
*
*Purpose:
*       Closes pstream then waits on the associated child command. The
*       argument, pstream, must be the return value from a previous call to
*       _popen. _pclose first looks up the process handle of child command
*       started by that _popen and does a cwait on it. Then, it closes pstream
*       and returns the exit status of the child command to the caller.
*
*Entry:
*       FILE *pstream - file stream returned by a previous call to _popen
*
*Exit:
*       If successful, _pclose returns the exit status of the child command.
*       The format of the return value is that same as for cwait, except that
*       the low order and high order bytes are swapped.
*
*       If an error occurs, -1 is returned.
*
*Exceptions:
*
*******************************************************************************/

int __cdecl _pclose (
        FILE *pstream
        )
{
        IDpair *locidpair;        /* pointer to entry in idpairs table */
        int termstat;             /* termination status word */
        int retval = -1;          /* return value (to caller) */
        errno_t save_errno;

        _VALIDATE_RETURN((pstream != NULL), EINVAL, -1);

        if (!_mtinitlocknum(_POPEN_LOCK))
            return -1;
        _mlock(_POPEN_LOCK);
        __try {

        if ((locidpair = idtab(pstream)) == NULL)
        {
                /* invalid pstream, exit with retval == -1
                 */
                errno = EBADF;
                goto done;
        }

        /* close pstream
         */
        (void)fclose(pstream);

        /* wait on the child (copy of the command processor) and all of its
         * children.
         */
        save_errno = errno;
        errno = 0;
        if ( (_cwait(&termstat, locidpair->prochnd, _WAIT_GRANDCHILD) != -1) ||
             (errno == EINTR) )
                retval = termstat;
        errno = save_errno;

        /* Mark the IDpairtable entry as free (note: prochnd was closed by the
         * preceding call to _cwait).
         */
        locidpair->stream = NULL;
        locidpair->prochnd = 0;

        /* only return path!
         */
        done:

        ; }
        __finally {
            _munlock(_POPEN_LOCK);
        }
        return(retval);
}
예제 #18
0
static errno_t __cdecl common_localtime_s(
    tm*             const ptm,
    TimeType const* const ptime
    ) throw()
{
    typedef __crt_time_time_t_traits<TimeType> time_traits;

    _VALIDATE_RETURN_ERRCODE(ptm != nullptr, EINVAL);
    memset(ptm, 0xff, sizeof(tm));

    _VALIDATE_RETURN_ERRCODE(ptime != nullptr, EINVAL);

    // Check for illegal time_t value:
    _VALIDATE_RETURN_ERRCODE_NOEXC(*ptime >= 0,                       EINVAL);
    _VALIDATE_RETURN_ERRCODE_NOEXC(*ptime <= time_traits::max_time_t, EINVAL);

    __tzset();

    int  daylight = 0;
    long dstbias  = 0;
    long timezone = 0;
    _ERRCHECK(_get_daylight(&daylight));
    _ERRCHECK(_get_dstbias (&dstbias ));
    _ERRCHECK(_get_timezone(&timezone));

    if (*ptime > 3 * _DAY_SEC && *ptime < time_traits::max_time_t - 3 * _DAY_SEC)
    {
        // The date does not fall within the first three or last three representable
        // days; therefore, there is no possibility of overflowing or underflowing
        // the time_t representation as we compensate for time zone and daylight
        // savings time.
        TimeType ltime = *ptime - timezone;

        errno_t status0 = time_traits::gmtime_s(ptm, &ltime);
        if (status0 != 0)
            return status0;

        // Check and adjust for daylight savings time:
        if (daylight && _isindst(ptm))
        {
            ltime -= dstbias;
            
            errno_t const status1 = time_traits::gmtime_s(ptm, &ltime);
            if (status1 != 0)
                return status1;

            ptm->tm_isdst = 1;
        }
    }
    else
    {
        // The date falls within the first three or last three representable days;
        // therefore, it is possible that the time_t representation would overflow
        // or underflow while compensating for time zone and daylight savings time.
        // Therefore, we make the time zone and daylight savings time adjustments
        // directly in the tm structure.
        errno_t const status0 = time_traits::gmtime_s(ptm, ptime);
        if (status0 != 0)
            return status0;

        TimeType ltime = static_cast<TimeType>(ptm->tm_sec);

        // First, adjust for the time zone:
        if (daylight && _isindst(ptm))
        {
            ltime -= (timezone + dstbias);
            ptm->tm_isdst = 1;
        }
        else
        {
            ltime -= timezone;
        }

        ptm->tm_sec = static_cast<int>(ltime % 60);
        if (ptm->tm_sec < 0)
        {
            ptm->tm_sec += 60;
            ltime -= 60;
        }

        ltime = static_cast<TimeType>(ptm->tm_min) + ltime / 60;
        ptm->tm_min = static_cast<int>(ltime % 60);
        if (ptm->tm_min < 0)
        {
            ptm->tm_min += 60;
            ltime -= 60;
        }

        ltime = static_cast<TimeType>(ptm->tm_hour) + ltime / 60;
        ptm->tm_hour = static_cast<int>(ltime % 24);
        if (ptm->tm_hour < 0)
        {
            ptm->tm_hour += 24;
            ltime -=24;
        }

        ltime /= 24;

        if (ltime > 0)
        {
            // There is no possibility of overflowing the tm_day and tm_yday
            // members because the date can be no later than January 19.
            ptm->tm_wday = (ptm->tm_wday + static_cast<int>(ltime)) % 7;
            ptm->tm_mday += static_cast<int>(ltime);
            ptm->tm_yday += static_cast<int>(ltime);
        }
        else if (ltime < 0)
        {
            // It is possible to underflow the tm_mday and tm_yday fields.  If
            // this happens, then the adjusted date must lie in December 1969:
            ptm->tm_wday = (ptm->tm_wday + 7 + static_cast<int>(ltime)) % 7;
            ptm->tm_mday += static_cast<int>(ltime);
            if (ptm->tm_mday <= 0)
            {
                ptm->tm_mday += 31;

                // Per assumption #4 above, the time zone can cause the date to
                // underflow the epoch by more than a day.
                ptm->tm_yday = ptm->tm_yday + static_cast<int>(ltime) + 365;
                ptm->tm_mon = 11;
                ptm->tm_year--;
            }
            else
            {
                ptm->tm_yday += static_cast<int>(ltime);
            }
        }
    }

    return 0;
}
예제 #19
0
파일: cenvarg.c 프로젝트: jetlive/skiaming
/***
*int _cenvarg(argv, envp, argblk, envblk, name) - set up cmd line/environ
*
*Purpose:
*       Set up the block forms of  the environment and the command line.
*       If "envp" is null, "_environ" is used instead.
*
*Entry:
*       _TSCHAR **argv   - argument vector
*       _TSCHAR **envp   - environment vector
*       _TSCHAR **argblk - pointer to pointer set to malloc'ed space for args
*       _TSCHAR **envblk - pointer to pointer set to malloc'ed space for env
*       _TSCHAR *name    - name of program being invoked
*
*Exit:
*       returns 0 if ok, -1 if fails
*       stores through argblk and envblk
*       (calls malloc)
*
*Exceptions:
*
*******************************************************************************/

#ifdef WPRFLAG
int __cdecl _wcenvarg (
#else  /* WPRFLAG */
int __cdecl _cenvarg (
#endif  /* WPRFLAG */
        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;
        unsigned env_len;
        int cfi_len;            /* counts the number of file handles in CFI */
        int retval = 0;

        /*
         * Null environment pointer "envp" means use global variable,
         * "_environ"
         */

        int cwd_start;
        int cwd_end;            /* length of "cwd" strings in environment */

        _TSCHAR envpfx[] = _T("SystemRoot");
        _TSCHAR *envbuf = NULL;
        int envsize = 0;
        int defined = 0;

        /*
         * 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 += (unsigned int)_tcslen(*vp++) + 1) ;

        arg_len = tmp;

        /*
         * Allocate space for the command line plus 2 null bytes
         */

        if ( (*argblk = _calloc_crt(tmp, sizeof(_TSCHAR))) == NULL)
        {
                *envblk = NULL;
                errno = ENOMEM;
                _doserrno = E_nomem;
                return(-1);
        }

        if (_ERRCHECK_EINVAL(_tdupenv_s_crt(&envbuf, NULL, envpfx)) != 0)
        {
                retval = -1;
                goto error;
        }

        envsize = (int)_tcslen(envpfx) + 2;
        if (envbuf != NULL)
        {
            envsize += (int)_tcslen(envbuf);
        }

        /*
         * 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 += (unsigned int)_tcslen(*vp++) + 1) ;

        /*
         * 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)
                        {
                                retval = -1;
                                goto error;
                        }
                }
#else  /* WPRFLAG */
                if (!_aenvptr)
                {
                        if ((_aenvptr = (char *)__crtGetEnvironmentStringsA()) == NULL)
                        {
                                retval = -1;
                                goto error;
                        }
                }
#endif  /* WPRFLAG */

                /*
                 * search for the first one
                 */
                for (cwd_start = 0;
                     _tenvptr[cwd_start] != _T('\0') &&
                       _tenvptr[cwd_start] != _T('=');
                     cwd_start += (int)_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 + (int)_tcslen(&_tenvptr[cwd_end+4]) + 1;
                }
                tmp += cwd_end - cwd_start;

                /*
                 * Allocate space for the environment strings plus extra null byte
                 */
                env_len = tmp;

                /*
                 * Check if SystemRoot is already defined in environment provided
                 */
                for (vp = envp; *vp; vp++) {
                        if (_tcsncicmp(*vp, envpfx, _tcslen(envpfx)) == 0) {
                                defined = 1;
                                break;
                        }
                }

                if (!defined)
                        tmp += envsize;

                if( !(*envblk = _calloc_crt(tmp, sizeof(_TSCHAR))) )
                {
                        _free_crt(*argblk);
                        *argblk = NULL;
                        errno = ENOMEM;
                        _doserrno = E_nomem;
                        retval = -1;
                        goto done;
                }
        }

        /*
         * 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 */
                _ERRCHECK(_tcscpy_s(cptr, arg_len - (cptr - *argblk), *vp));
                cptr += (int)_tcslen(*vp++) + 1;
        }

        while( *vp ) {
                _ERRCHECK(_tcscpy_s(cptr, arg_len - (cptr - *argblk), *vp));
                cptr += (int)_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 ) {
                        _ERRCHECK(_tcscpy_s(cptr, env_len - (cptr - *envblk), *vp));
                        cptr += 1 + (int)_tcslen(*vp++);
                }

                if (!defined) {
                        /*
                         * Copy SystemRoot to the new environment.
                         */
                        _ERRCHECK(_tcscpy_s(cptr, envsize, envpfx));
                        _ERRCHECK(_tcscat_s(cptr, envsize, _T("=")));
                        if (envbuf != NULL)
                        {
                            _ERRCHECK(_tcscat_s(cptr, envsize, envbuf));
                        }
                        cptr += envsize;
                }
        }

        if (cptr != NULL) {
                if (cptr == *envblk) {
                        /*
                         * Empty environment block ... this requires two
                         * nulls.
                         */
                        *cptr++ = _T('\0');
                }
                /*
                 * Extra null terminates the segment
                 */
                *cptr = _T('\0');
        }

        goto done;

error:
        _free_crt(*argblk);
        *argblk = NULL;
        *envblk = NULL;

done:

#ifdef WPRFLAG
        if (_wenvptr)
                _free_crt(_wenvptr);
        _wenvptr = NULL;
#else  /* WPRFLAG */
        if (_aenvptr)
                _free_crt(_aenvptr);
        _aenvptr = NULL;
#endif  /* WPRFLAG */
        if (envbuf)
                _free_crt(envbuf);

        return retval;
}
예제 #20
0
int __cdecl _resetstkoflw(void) {
    LPBYTE pStack, pStackBase, pMaxGuard, pMinGuard;
#if defined (_M_IA64)
    LPBYTE pBspBase;
    DWORD BspRegionSize;
#endif  /* defined (_M_IA64) */
    MEMORY_BASIC_INFORMATION mbi;
    SYSTEM_INFO si;
    DWORD PageSize;
    DWORD RegionSize;
    DWORD flNewProtect;
    DWORD flOldProtect;
    BOOL
    (*SetThreadStackGuaranteePointer)(
        ULONG * StackSizeInBytes
    );
    unsigned int osplatform = 0;
    // Use _alloca() to get the current stack pointer
#pragma warning(push)
#pragma warning(disable:6255)
    // prefast(6255): This alloca is safe and we do not want a __try here
    pStack = (LPBYTE)_alloca(1);
#pragma warning(pop)

    // Find the base of the stack.

    if (VirtualQuery(pStack, &mbi, sizeof mbi) == 0) {
        return 0;
    }

    pStackBase = (LPBYTE)mbi.AllocationBase;
    GetSystemInfo(&si);
    PageSize = si.dwPageSize;
    RegionSize = 0;
    // Enable the new guard page.
    _ERRCHECK(_get_osplatform(&osplatform));

    if (osplatform == VER_PLATFORM_WIN32_NT) {
        //
        // Note: if the GuaranteedStackBytes TEB field is 0
        // (on older OS versions or if SetThreadStackGuarantee is
        // not being used) we will use the default value of
        // RegionSize (2 pages for ia64, 1 page for other platforms).
        //
        ULONG StackSizeInBytes;
        HMODULE ModuleHandle;
        //
        // Don't call SetThreadStackGuarantee directly as older kernel32.dll
        // versions do not have this export.
        //
        ModuleHandle = GetModuleHandle("kernel32.dll");

        if (ModuleHandle != NULL) {
            SetThreadStackGuaranteePointer = (PVOID) GetProcAddress(ModuleHandle, "SetThreadStackGuarantee");

            if (SetThreadStackGuaranteePointer != NULL) {
                StackSizeInBytes = 0;       // Indicate just querying

                if (SetThreadStackGuaranteePointer(&StackSizeInBytes) == TRUE &&
                        StackSizeInBytes > 0) {
                    RegionSize = StackSizeInBytes;
                }
            }
        }
    }

    flNewProtect = (osplatform == VER_PLATFORM_WIN32_WINDOWS)
                   ? PAGE_NOACCESS
                   : PAGE_READWRITE | PAGE_GUARD;
    RegionSize = (RegionSize + PageSize - 1) & ~(PageSize - 1);

    //
    // If there is a stack guarantee (RegionSize nonzero), then increase
    // our guard page size by 1 so that even a subsequent fault that occurs
    // midway (instead of at the beginning) through the first guard page
    // will have the extra page to preserve the guarantee.
    //

    if (RegionSize != 0) {
        RegionSize += PageSize;
    }

#if defined (_M_IA64)
    //
    // Reset the backstore stack pages.
    //
    //
    // Calculate the top of the BSP stack, by getting the size of the normal
    // stack and adding it to the StackBase.
    //
    pBspBase = (LPBYTE)(((ULONG_PTR)(((PNT_TIB)NtCurrentTeb())->StackBase) - (ULONG_PTR) mbi.AllocationBase) +
                        (ULONG_PTR)(((PNT_TIB)NtCurrentTeb())->StackBase));
    //
    // Get the current BSP and round up since the BSP grows up.
    //
    pMinGuard = (LPBYTE)((__getReg(__REG_IA64_RsBSP) + PageSize) & ~(ULONG_PTR)(PageSize - 1));
    //
    // The highest BSP address is the top of the BSP stack less one page for
    // the guard.
    //
    pMaxGuard = pBspBase - PageSize;
    BspRegionSize = RegionSize;

    if (BspRegionSize < MIN_BSP_REQ_WINNT * PageSize) {
        BspRegionSize = MIN_BSP_REQ_WINNT * PageSize;
    }

    if (((ULONG_PTR)pMaxGuard < BspRegionSize) ||
            (pMaxGuard - BspRegionSize) < pMinGuard) {
        //
        // The current BSP is already in the highest guard region.
        //
        return 0;
    }

    if (VirtualAlloc(pMinGuard, BspRegionSize, MEM_COMMIT, PAGE_READWRITE) == NULL ||
            VirtualProtect(pMinGuard, BspRegionSize, flNewProtect, &flOldProtect) == 0) {
        return 0;
    }

#endif  /* defined (_M_IA64) */

    if (RegionSize < MIN_STACK_REQ_WINNT * PageSize) {
        RegionSize = MIN_STACK_REQ_WINNT * PageSize;
    }

    //
    // Find the page(s) just below where the stack pointer currently points.
    // This is the highest potential guard page.
    //
    pMaxGuard = (LPBYTE)(((DWORD_PTR)pStack & ~(DWORD_PTR)(PageSize - 1))
                         - RegionSize);
    //
    // If the potential guard page is too close to the start of the stack
    // region, abandon the reset effort for lack of space.  Win9x has a
    // larger reserved stack requirement.
    //
    pMinGuard = pStackBase + (
                    (osplatform == VER_PLATFORM_WIN32_WINDOWS)
                    ? MIN_STACK_REQ_WIN9X
                    : PageSize);

    if (pMaxGuard < pMinGuard) {
        return 0;
    }

    // Set the new guard page just below the current stack page.

    if (VirtualAlloc(pMaxGuard, RegionSize, MEM_COMMIT, PAGE_READWRITE) == NULL ||
            VirtualProtect(pMaxGuard, RegionSize, flNewProtect, &flOldProtect) == 0) {
        return 0;
    }

    return 1;
}
예제 #21
0
// prefast (6262): This func uses lots of stack because we want to tolerate very large reports, and we can't use malloc here.
int __cdecl _VCrtDbgReportA(
    int nRptType,
    void * returnAddress,
    char const* szFile,
    int nLine,
    char const* szModule,
    char const* szFormat,
    va_list arglist
    )
{
    int retval=0;
    int handled=FALSE;

    char    szLineMessage[DBGRPT_MAX_MSG]{0};
    char    szOutMessage [DBGRPT_MAX_MSG]{0};
    wchar_t szOutMessage2[DBGRPT_MAX_MSG]{0};
    char    szUserMessage[DBGRPT_MAX_MSG]{0};

    if (nRptType < 0 || nRptType >= _CRT_ERRCNT)
        return -1;

    /*
     * handle the (hopefully rare) case of
     *
     * 1) ASSERT while already dealing with an ASSERT
     *      or
     * 2) two threads asserting at the same time
     */

    __try
    {
        if (_CRT_ASSERT == nRptType && _InterlockedIncrement(&_crtAssertBusy) > 0)
        {
            /* use only 'safe' functions -- must not assert in here! */

            _ERRCHECK(_itoa_s(nLine, szLineMessage, DBGRPT_MAX_MSG, 10));

            OutputDebugStringA("Second Chance Assertion Failed: File ");
            OutputDebugStringA(szFile ? szFile : "<file unknown>");
            OutputDebugStringA(", Line ");
            OutputDebugStringA(szLineMessage);
            OutputDebugStringA("\n");

            _CrtDbgBreak();
            retval=-1;
            __leave;
        }

        // Leave space for ASSERTINTRO1 and "\r\n"
        if (szFormat)
        {
            int szlen = 0;
            _ERRCHECK_SPRINTF(szlen = _vsnprintf_s(szUserMessage, DBGRPT_MAX_MSG,
                                                    DBGRPT_MAX_MSG - 2- max(sizeof(ASSERTINTRO1),sizeof(ASSERTINTRO2)),
                                                    szFormat, arglist));
            if (szlen < 0)
            {
                _ERRCHECK(strcpy_s(szUserMessage, DBGRPT_MAX_MSG, DBGRPT_TOOLONGMSG));
            }
        }

        if (_CRT_ASSERT == nRptType)
        {
            _ERRCHECK(strcpy_s(szLineMessage, DBGRPT_MAX_MSG, szFormat ? ASSERTINTRO1 : ASSERTINTRO2));
        }

        _ERRCHECK(strcat_s(szLineMessage, DBGRPT_MAX_MSG, szUserMessage));

        if (_CRT_ASSERT == nRptType)
        {
            if (_CrtDbgMode[nRptType] & _CRTDBG_MODE_FILE)
            {
                _ERRCHECK(strcat_s(szLineMessage, DBGRPT_MAX_MSG, "\r"));
            }

            _ERRCHECK(strcat_s(szLineMessage, DBGRPT_MAX_MSG, "\n"));
        }

        if (szFile)
        {
            int szlen = 0;
            _ERRCHECK_SPRINTF(szlen = _snprintf_s(szOutMessage, DBGRPT_MAX_MSG, DBGRPT_MAX_MSG - 1, "%s(%d) : %s",
                                                    szFile, nLine, szLineMessage));
            if (szlen < 0)
            {
                _ERRCHECK(strcpy_s(szOutMessage, DBGRPT_MAX_MSG, DBGRPT_TOOLONGMSG));
            }
        }
        else
        {
            _ERRCHECK(strcpy_s(szOutMessage, DBGRPT_MAX_MSG, szLineMessage));
        }

        {
            size_t ret = 0;
            errno_t e = 0;
            _ERRCHECK_EINVAL_ERANGE(e = mbstowcs_s(&ret, szOutMessage2, DBGRPT_MAX_MSG, szOutMessage, _TRUNCATE));
            if(e != 0)
            {
                _ERRCHECK(wcscpy_s(szOutMessage2, DBGRPT_MAX_MSG, _CRT_WIDE(DBGRPT_INVALIDMSG)));
            }
        }

        /* User hook may handle report.
            We have to check the ANSI Hook2 List & then the UNICODE Hook2 List.
            Then we have check any ANSI individual Hook set through
            SetReportHook */

        if (_pReportHookList || _pReportHookListW)
        {
            __crt_report_hook_node<char> *pnode=nullptr;
            __crt_report_hook_node<wchar_t> *pnodeW=nullptr;

            __acrt_lock(__acrt_debug_lock);
            __try
            {
                for (pnode = _pReportHookList; pnode; pnode = pnode->next)
                {
                    int hook_retval=0;
                    if (pnode->hook(nRptType, szOutMessage, &hook_retval))
                    {
                        handled=TRUE;
                        retval=hook_retval;
                        __leave;
                    }
                }

                for (pnodeW = _pReportHookListW; pnodeW; pnodeW = pnodeW->next)
                {
                    int hook_retval=0;
                    if (pnodeW->hook(nRptType, szOutMessage2, &hook_retval))
                    {
                        handled=TRUE;
                        retval=hook_retval;
                        __leave;
                    }
                }
            }
            __finally
            {
                __acrt_unlock(__acrt_debug_lock);
            }
        }

        if (handled)
            __leave;

        if (_pfnReportHook)
        {
            int hook_retval=0;
            if (_pfnReportHook(nRptType, szOutMessage, &hook_retval))
            {
                retval = hook_retval;
                __leave;
            }
        }

        if (_CrtDbgMode[nRptType] & _CRTDBG_MODE_FILE)
        {
            if (_CrtDbgFile[nRptType] != _CRTDBG_INVALID_HFILE)
            {
                DWORD bytes_written = 0;
                WriteFile(_CrtDbgFile[nRptType], szOutMessage, static_cast<DWORD>(strlen(szOutMessage)), &bytes_written, nullptr);
            }
        }

        if (_CrtDbgMode[nRptType] & _CRTDBG_MODE_DEBUG)
        {
            OutputDebugStringA(szOutMessage);
        }

        if (_CrtDbgMode[nRptType] & _CRTDBG_MODE_WNDW)
        {
            szLineMessage[0] = 0;
            if (nLine)
            {
                _ERRCHECK(_itoa_s(nLine, szLineMessage, DBGRPT_MAX_MSG, 10));
            }

            retval = __acrt_MessageWindowA(nRptType, returnAddress, szFile, (nLine ? szLineMessage : nullptr), szModule, szUserMessage);
        }
    }