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

📄 osfinfo.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 2 页
字号:
/***
*osfinfo.c - Win32 _osfhnd[] support routines
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       Defines the internally used routine _alloc_osfhnd()
*       and the user visible routine _get_osfhandle().
*
*******************************************************************************/

#include <cruntime.h>
#include <oscalls.h>
#include <errno.h>
#include <internal.h>
#include <fcntl.h>
#include <malloc.h>
#include <msdos.h>
#include <mtdll.h>
#include <stdlib.h>
#include <dbgint.h>
#include <io.h>


/***
*int _alloc_osfhnd() - get free _ioinfo struct
*
*Purpose:
*       Finds the first free entry in the arrays of ioinfo structs and
*       returns the index of that entry (which is the CRT file handle to the
*       caller) to the caller.  The FOPEN flag is turned on in the new entry,
*       to prevent multithreaded race conditions/deadlocks.
*
*Entry:
*       none
*
*Exit:
*       returns index of the entry, if successful
*       return -1, if no free entry is available or out of memory
*
*       MULTITHREAD NOTE: IF SUCCESSFUL, THE HANDLE IS LOCKED WHEN IT IS
*       RETURNED TO THE CALLER!  ALSO, FOPEN HAS BEEN TURNED ON, SO IF THE
*       CALLER ABANDONS THE HANDLE, FOPEN MUST BE CLEARED!
*
*Exceptions:
*
*******************************************************************************/

int __cdecl _alloc_osfhnd(
        void
        )
{
        int fh = -1;    /* file handle */
        int i;
        ioinfo *pio;
        int failed=FALSE;

        if (!_mtinitlocknum(_OSFHND_LOCK))
            return -1;

        _mlock(_OSFHND_LOCK);   /* lock the __pioinfo[] array */
        __TRY

            /*
             * Search the arrays of ioinfo structs, in order, looking for the
             * first free entry. The compound index of this free entry is the
             * return value. Here, the compound index of the ioinfo struct
             * *(__pioinfo[i] + j) is k = i * IOINFO_ARRAY_ELTS + j, and k = 0,
             * 1, 2,... is the order of the search.
             */
            for ( i = 0 ; i < IOINFO_ARRAYS ; i++ ) {
                /*
                 * If __pioinfo[i] is non-empty array, search it looking for
                 * the first free entry. Otherwise, allocate a new array and use
                 * its first entry.
                 */
                if ( __pioinfo[i] != NULL ) {
                    /*
                     * Search for an available entry.
                     */
                    for ( pio = __pioinfo[i] ;
                          pio < __pioinfo[i] + IOINFO_ARRAY_ELTS ;
                          pio++ )
                    {
                        if ( (pio->osfile & FOPEN) == 0 ) {
                            /*
                             * Make sure the lock is initialized.
                             */
                            if ( pio->lockinitflag == 0 ) {
                                _mlock( _LOCKTAB_LOCK );
                                __TRY
                                    if ( pio->lockinitflag == 0 ) {
                                        if ( !InitializeCriticalSectionAndSpinCount( &(pio->lock), _CRT_SPINCOUNT ))
                                        {
                                            /*
                                             * Lock initialization failed.  Release
                                             * held locks and return failure.
                                            */
                                            failed=TRUE;
                                        }
                                        else
                                        {
                                            pio->lockinitflag++;
                                        }
                                    }
                                __FINALLY
                                    _munlock( _LOCKTAB_LOCK );
                                __END_TRY_FINALLY
                            }

                            if(!failed)
                            {
                                EnterCriticalSection( &(pio->lock) );

                                /*
                                * Check for the case where another thread has
                                * managed to grab the handle out from under us.
                                */
                                if ( (pio->osfile & FOPEN) != 0 ) {
                                        LeaveCriticalSection( &(pio->lock) );
                                        continue;
                                }
                            }

                            if(!failed)
                            {
                                pio->osfile = FOPEN;
                                pio->osfhnd = (intptr_t)INVALID_HANDLE_VALUE;
                                fh = i * IOINFO_ARRAY_ELTS + (int)(pio - __pioinfo[i]);
                                break;
                            }
                        }
                    }

                    /*
                     * Check if a free entry has been found.
                     */
                    if ( fh != -1 )
                        break;
                }
                else {
                    /*
                     * Allocate and initialize another array of ioinfo structs.
                     */
                    if ( (pio = _calloc_crt( IOINFO_ARRAY_ELTS, sizeof(ioinfo) ))
                        != NULL )
                    {

                        /*
                         * Update __pioinfo[] and _nhandle
                         */
                        __pioinfo[i] = pio;
                        _nhandle += IOINFO_ARRAY_ELTS;

                        for ( ; pio < __pioinfo[i] + IOINFO_ARRAY_ELTS ; pio++ ) {
                            pio->osfile = 0;
                            pio->osfhnd = (intptr_t)INVALID_HANDLE_VALUE;
                            pio->pipech = 10;
                            pio->lockinitflag = 0;
                        }

                        /*
                         * The first element of the newly allocated array of ioinfo
                         * structs, *(__pioinfo[i]), is our first free entry.
                         */
                        fh = i * IOINFO_ARRAY_ELTS;
                        _osfile(fh) = FOPEN;
                        if ( !__lock_fhandle( fh ) ) {
                            /*
                             * The lock initialization failed, return the failure
                             */
                            fh = -1;
                        }
                    }

                    break;
                }
            }
        __FINALLY
            _munlock(_OSFHND_LOCK); /* unlock the __pioinfo[] table */
        __END_TRY_FINALLY

        /*
         * return the index of the previously free table entry, if one was
         * found. return -1 otherwise.
         */
        return( fh );
}


/***
*int _set_osfhnd(int fh, long value) - set Win32 HANDLE value
*
*Purpose:
*       If fh is in range and if _osfhnd(fh) is marked with
*       INVALID_HANDLE_VALUE then set _osfhnd(fh) to the passed value.
*
*Entry:
*       int fh      - CRT file handle
*       long value  - new Win32 HANDLE value for this handle
*
*Exit:
*       Returns zero if successful.
*       Returns -1 and sets errno to EBADF otherwise.
*
*Exceptions:
*
*******************************************************************************/

int __cdecl _set_osfhnd (
        int fh,
        intptr_t value
        )
{
        if ( fh >= 0 && ((unsigned)fh < (unsigned)_nhandle) &&
             (_osfhnd(fh) == (intptr_t)INVALID_HANDLE_VALUE)
           ) {
            if ( __app_type == _CONSOLE_APP ) {
                switch (fh) {
                case 0:
                    SetStdHandle( STD_INPUT_HANDLE, (HANDLE)value );
                    break;
                case 1:
                    SetStdHandle( STD_OUTPUT_HANDLE, (HANDLE)value );
                    break;
                case 2:
                    SetStdHandle( STD_ERROR_HANDLE, (HANDLE)value );
                    break;
                }
            }

            _osfhnd(fh) = value;
            return(0);
        } else {
            errno = EBADF;      /* bad handle */
            _doserrno = 0L;     /* not an OS error */
            return -1;
        }
}


/***
*int _free_osfhnd(int fh) - mark osfhnd field of ioinfo struct as free
*
*Purpose:
*       If fh is in range, the corrsponding ioinfo struct is marked as
*       being open, and the osfhnd field is NOT set to INVALID_HANDLE_VALUE,

⌨️ 快捷键说明

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