⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmpfile.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 2 页
字号:
/***
*tmpfile.c - create unique file name or file
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       defines tmpnam() and tmpfile().
*
*******************************************************************************/

#include <cruntime.h>
#include <errno.h>
#include <process.h>
#include <fcntl.h>
#include <io.h>
#include <mtdll.h>
#include <share.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <file2.h>
#include <internal.h>
#include <tchar.h>
#include <dbgint.h>

/*
 * Buffers used by tmpnam() and tmpfile() to build filenames.
 * (Taken from stdio.h)
 * L_tmpnam(_s) = length of string _P_tmpdir
 *            + 1 if _P_tmpdir does not end in "/" or "\", else 0
 *            + 12 (for the filename string)
 *            + 1 (for the null terminator)
 * L_tmpnam_s = length of string _P_tmpdir
 *            + 1 if _P_tmpdir does not end in "/" or "\", else 0
 *            + 16 (for the filename string)
 *            + 1 (for the null terminator)
 *
 *
 *  #define L_tmpnam   (sizeof(_P_tmpdir) + 12)
 *  #define L_tmpnam_s (sizeof(_P_tmpdir) + 16)
 *
 *
 *  The 12/16 is calculated as follows
 *  The tmpname(_s) strings look like "Prefix1stPart.2ndPart"
 *  Prefix is "s" - 1 character long.
 *  1st Part is generated by ProcessID converted to string by _ultot
 *      Even for max process id == UINT_MAX, the resultant string is "3vvvvvv"
 *      i.e. 7 characters long
 *  1 character for the "."
 *  This gives a subtotal of 1 + 7 + 1 = 9 for the "Prefix1stPart."
 *
 *  The 2ndPart is generated by passing a number to _ultot.
 *  In tmpnam, the max number passed is SHRT_MAX, generating the string "vvv".
 *  i.e. 3 characters long.
 *  In tmpnam_s, the max number passed is INT_MAX, generating "1vvvvvv"
 *  i.e. 7 characters long.
 *
 *  L_tmpnam   = sizeof(_P_tmpdir + 9 + 3)
 *  L_tmpnam_s = sizeof(_P_tmpdir + 9 + 7)
 *
 */

static _TSCHAR tmpnam_buf[L_tmpnam] = { 0 };      /* used by tmpnam()  */
static _TSCHAR tmpfile_buf[L_tmpnam_s] = { 0 };      /* used by tmpfile() */
static _TSCHAR tmpnam_s_buf[L_tmpnam_s] = { 0 };      /* used by tmpnam_s() */

#define _TMPNAM_BUFFER 0
#define _TMPFILE_BUFFER 1
#define _TMPNAM_S_BUFFER 2

/*
 * Initializing function for tmpnam_buf and tmpfile_buf.
 */
#ifdef _UNICODE
static void __cdecl winit_namebuf(int);
#else  /* _UNICODE */
static void __cdecl init_namebuf(int);
#endif  /* _UNICODE */

/*
 * Generator function that produces temporary filenames
 */
#ifdef _UNICODE
static int __cdecl wgenfname(wchar_t *, size_t, unsigned long);
#else  /* _UNICODE */
static int __cdecl genfname(char *, size_t, unsigned long);
#endif  /* _UNICODE */


errno_t _ttmpnam_helper (
        _TSCHAR *s, size_t sz, int buffer_no, unsigned long tmp_max, _TSCHAR **ret
        )

{
        _TSCHAR *pfnam = NULL;
        size_t pfnameSize = 0;
        errno_t retval = 0;
        errno_t saved_errno=errno;

        _ptiddata ptd;

        if ( !_mtinitlocknum( _TMPNAM_LOCK ))
        {
                *ret = NULL;
                return errno;
        }

        _mlock(_TMPNAM_LOCK);

        __try {

        /* buffer_no is either _TMPNAM_BUFFER or _TMPNAM_S_BUFFER
        It's never _TMPFILE_BUFFER */

        if (buffer_no == _TMPNAM_BUFFER)
        {
            pfnam = tmpnam_buf;
            pfnameSize = _countof(tmpnam_buf);
        }
        else
        {
            pfnam = tmpnam_s_buf;
            pfnameSize = _countof(tmpnam_s_buf);
        }

        /*
         * Initialize tmpnam_buf, if needed. Otherwise, call genfname() to
         * generate the next filename.
         */
        if ( *pfnam == 0 ) {
#ifdef _UNICODE
                winit_namebuf(buffer_no);
#else  /* _UNICODE */
                init_namebuf(buffer_no);
#endif  /* _UNICODE */
        }
#ifdef _UNICODE
        else if ( wgenfname(pfnam, pfnameSize, tmp_max) )
#else  /* _UNICODE */
        else if ( genfname(pfnam, pfnameSize, tmp_max) )
#endif  /* _UNICODE */
                goto tmpnam_err;

        /*
         * Generate a filename that doesn't already exist.
         */
        while ( _taccess_s(pfnam, 0) == 0 )
#ifdef _UNICODE
                if ( wgenfname(pfnam, pfnameSize, tmp_max) )
#else  /* _UNICODE */
                if ( genfname(pfnam, pfnameSize, tmp_max) )
#endif  /* _UNICODE */
                        goto tmpnam_err;

        /*
         * Filename has successfully been generated.
         */
        if ( s == NULL )
        {

                /* Will never come here for tmpnam_s */
                _ASSERTE(pfnam == tmpnam_buf);
                /*
                 * Use a per-thread buffer to hold the generated file name.
                 */
                ptd = _getptd_noexit();
                if (!ptd) {
                    retval = ENOMEM;
                    goto tmpnam_err;
                }
#ifdef _UNICODE
                if ( (ptd->_wnamebuf0 != NULL) || ((ptd->_wnamebuf0 =
                      _calloc_crt(L_tmpnam, sizeof(wchar_t))) != NULL) )
                {
                        s = ptd->_wnamebuf0;
                        _ERRCHECK(wcscpy_s(s, L_tmpnam, pfnam));
                }
#else  /* _UNICODE */
                if ( (ptd->_namebuf0 != NULL) || ((ptd->_namebuf0 =
                      _malloc_crt(L_tmpnam)) != NULL) )
                {
                        s = ptd->_namebuf0;
                        _ERRCHECK(strcpy_s(s, L_tmpnam, pfnam));
                }
#endif  /* _UNICODE */
                else
                {
                        retval = ENOMEM;
                        goto tmpnam_err;
                }
        }
        else
        {
            if((buffer_no != _TMPNAM_BUFFER) && (_tcslen(pfnam) >= sz))
            {
                retval = ERANGE;

                if(sz != 0)
                    s[0] = 0;

                goto tmpnam_err;
            }

            _ERRCHECK(_tcscpy_s(s, sz, pfnam));
        }


        /*
         * All errors come here.
         */
tmpnam_err:;
        }
        __finally {
                _munlock(_TMPNAM_LOCK);
        }
        *ret = s;
        if (retval != 0)
        {
            errno = retval;
        }
        else
        {
            errno = saved_errno;
        }
        return retval ;
}


errno_t __cdecl _ttmpnam_s(_TSCHAR * s, size_t sz)
{
    _TSCHAR * ret; /* Not used by tmpnam_s */

    _VALIDATE_RETURN_ERRCODE( (s != NULL), EINVAL);

    return _ttmpnam_helper(s, sz, _TMPNAM_S_BUFFER, _TMP_MAX_S, &ret);
}

/***
*_TSCHAR *tmpnam(_TSCHAR *s) - generate temp file name
*
*Purpose:
*       Creates a file name that is unique in the directory specified by
*       _P_tmpdir in stdio.h.  Places file name in string passed by user or
*       in static mem if pass NULL.
*
*Entry:
*       _TSCHAR *s - ptr to place to put temp name
*
*Exit:
*       returns pointer to constructed file name (s or address of static mem)
*       returns NULL if fails
*
*Exceptions:
*
*******************************************************************************/

_TSCHAR * __cdecl _ttmpnam (
        _TSCHAR *s
        )
{
    _TSCHAR * ret = NULL;
    _ttmpnam_helper(s, (size_t)-1, _TMPNAM_BUFFER, TMP_MAX, &ret) ;
    return ret;
}


#ifndef _UNICODE

errno_t __cdecl _tmpfile_helper (FILE ** pFile, int shflag)
{
        FILE *stream;
        int fh;
        errno_t retval = 0;
        errno_t save_errno;

        int stream_lock_held = 0;

        _VALIDATE_RETURN_ERRCODE( (pFile != NULL), EINVAL);
        *pFile = NULL;

        if ( !_mtinitlocknum( _TMPNAM_LOCK ))
        {
                return errno;
        }

        _mlock(_TMPNAM_LOCK);

        __try {

        /*
         * Initialize tmpfile_buf, if needed. Otherwise, call genfname() to
         * generate the next filename.
         */
        if ( *tmpfile_buf == 0 ) {
                init_namebuf(_TMPFILE_BUFFER);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -