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

📄 open.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 3 页
字号:

        /*
         * decode open/create method flags
         */
        switch ( oflag & (_O_CREAT | _O_EXCL | _O_TRUNC) ) {
            case 0:
            case _O_EXCL:                   // ignore EXCL w/o CREAT
                filecreate = OPEN_EXISTING;
                break;

            case _O_CREAT:
                filecreate = OPEN_ALWAYS;
                break;

            case _O_CREAT | _O_EXCL:
            case _O_CREAT | _O_TRUNC | _O_EXCL:
                filecreate = CREATE_NEW;
                break;

            case _O_TRUNC:
            case _O_TRUNC | _O_EXCL:        // ignore EXCL w/o CREAT
                filecreate = TRUNCATE_EXISTING;
                break;

            case _O_CREAT | _O_TRUNC:
                filecreate = CREATE_ALWAYS;
                break;

            default:
                // this can't happen ... all cases are covered
                _doserrno = 0L;
                *pfh = -1;
                _VALIDATE_RETURN_ERRCODE(( "Invalid open flag" , 0 ), EINVAL);
        }

        /*
         * decode file attribute flags if _O_CREAT was specified
         */
        fileattrib = FILE_ATTRIBUTE_NORMAL;     /* default */

        if ( oflag & _O_CREAT ) {

            if ( !((pmode & ~_umaskval) & _S_IWRITE) )
                fileattrib = FILE_ATTRIBUTE_READONLY;
        }

        /*
         * Set temporary file (delete-on-close) attribute if requested.
         */
        if ( oflag & _O_TEMPORARY ) {
            fileattrib |= FILE_FLAG_DELETE_ON_CLOSE;
            fileaccess |= DELETE;
            fileshare |= FILE_SHARE_DELETE;
        }

        /*
         * Set temporary file (delay-flush-to-disk) attribute if requested.
         */
        if ( oflag & _O_SHORT_LIVED )
            fileattrib |= FILE_ATTRIBUTE_TEMPORARY;

        /*
         * Set sequential or random access attribute if requested.
         */
        if ( oflag & _O_SEQUENTIAL )
            fileattrib |= FILE_FLAG_SEQUENTIAL_SCAN;
        else if ( oflag & _O_RANDOM )
            fileattrib |= FILE_FLAG_RANDOM_ACCESS;

        /*
         * get an available handle.
         *
         * multi-thread note: the returned handle is locked!
         */
        if ( (*pfh = _alloc_osfhnd()) == -1 ) {
            _doserrno = 0L;         /* not an OS error */
            *pfh = -1;
            errno = EMFILE;
            return errno;          /* return error to caller */
        }

        /* Beyond this do not set *pfh = -1 on errors for MT.
            Because the caller needs to release the lock on the
            handle */

        *punlock_flag = 1;

        /*
         * try to open/create the file
         */
        if ( (osfh = CreateFile( (LPTSTR)path,
                                 fileaccess,
                                 fileshare,
                                 &SecurityAttributes,
                                 filecreate,
                                 fileattrib,
                                 NULL ))
             == (HANDLE)(-1) )
        {
            if ((fileaccess & (GENERIC_READ | GENERIC_WRITE)) == (GENERIC_READ | GENERIC_WRITE) &&
                    (oflag & _O_WRONLY))
            {
                /*
                 * We just failed on CreateFile(), because we might be trying
                 * open something for read while it cannot be read (eg. pipes or devices).
                 * So try again with GENERIC_WRITE and we will have to use the default
                 * encoding.  We won't be able to determine the encoding from reading
                 * the BOM.
                 */
                fileaccess &= ~GENERIC_READ;
                if ( (osfh = CreateFile( (LPTSTR)path,
                                         fileaccess,
                                         fileshare,
                                         &SecurityAttributes,
                                         filecreate,
                                         fileattrib,
                                         NULL ))
                     == (HANDLE)(-1) )
                {
                    /*
                     * OS call to open/create file failed! map the error, release
                     * the lock, and return -1. note that it's not necessary to
                     * call _free_osfhnd (it hasn't been used yet), but we do need
                     * to clear the FOPEN that was set by _alloc_osfhnd.
                     */
                    _osfile(*pfh) &= ~FOPEN;
                    _dosmaperr(GetLastError());
                    retvalue = errno;
                    goto exit;
                }
            }
            else
            {
                /*
                 * OS call to open/create file failed! map the error, release
                 * the lock, and return -1. note that it's not necessary to
                 * call _free_osfhnd (it hasn't been used yet), but we do need
                 * to clear the FOPEN that was set by _alloc_osfhnd.
                 */
                _osfile(*pfh) &= ~FOPEN;
                _dosmaperr(GetLastError());
                retvalue = errno;
                goto exit;
            }
        }

        /* find out what type of file (file/device/pipe) */
        if ( (isdev = GetFileType(osfh)) == FILE_TYPE_UNKNOWN) {
            DWORD dwLastError = 0;
            _osfile(*pfh) &= ~FOPEN;
            dwLastError = GetLastError();
            _dosmaperr(dwLastError);
            CloseHandle(osfh);
            if (dwLastError == ERROR_SUCCESS)
            {
               /*
                * If GetFileType returns FILE_TYPE_UNKNOWN but doesn't fail,
                * GetLastError returns ERROR_SUCCESS.
                * This function is not designed to deal with unknown types of files
                * and must return an error.
               */
               errno = EACCES;
            }
            retvalue = errno;
            goto exit;
        }

        /* use isdev value to set flags */
        if (isdev == FILE_TYPE_CHAR)
            fileflags |= FDEV;
        else if (isdev == FILE_TYPE_PIPE) {
            fileflags |= FPIPE;
        }

        /*
         * the file is open. now, set the info in _osfhnd array
         */
        _set_osfhnd(*pfh, (intptr_t)osfh);

        /*
         * mark the handle as open. store flags gathered so far in _osfile
         * array.
         */
        fileflags |= FOPEN;
        _osfile(*pfh) = fileflags;

        /* TextMode set to ANSI by default, if we find a BOM, then
        we reset it to the appropriate type below */
        _textmode(*pfh) = __IOINFO_TM_ANSI;

        if ( !(fileflags & (FDEV|FPIPE)) && (fileflags & FTEXT) &&
             (oflag & _O_RDWR) )
        {
            /* We have a text mode file.  If it ends in CTRL-Z, we wish to
               remove the CTRL-Z character, so that appending will work.
               We do this by seeking to the end of file, reading the last
               byte, and shortening the file if it is a CTRL-Z. */

            if ((filepos = _lseek_nolock(*pfh, -1, SEEK_END)) == -1) {
                /* OS error -- should ignore negative seek error,
                   since that means we had a zero-length file. */
                if (_doserrno != ERROR_NEGATIVE_SEEK) {
                    _close_nolock(*pfh);
                    retvalue = errno;
                    goto exit;
                }
            }
            else {
                /* Seek was OK, read the last char in file. The last
                   char is a CTRL-Z if and only if _read returns 0
                   and ch ends up with a CTRL-Z. */
                ch = 0;
                if (_read_nolock(*pfh, &ch, 1) == 0 && ch == 26) {
                    /* read was OK and we got CTRL-Z! Wipe it
                       out! */
                    if (_chsize_nolock(*pfh,filepos) == -1)
                    {
                        _close_nolock(*pfh);
                        retvalue = errno;
                        goto exit;
                    }
                }

                /* now rewind the file to the beginning */
                if ((filepos = _lseek_nolock(*pfh, 0, SEEK_SET)) == -1) {
                    _close_nolock(*pfh);
                    retvalue = errno;
                    goto exit;
                }
            }
        }

        if ( fileflags & FTEXT) {

            int count;

            /* Set default tmode per oflag. BOM will change the defualt. */
            /* If oflag does not specify file type get type from _fmode  */
            if ( (oflag & (_O_TEXT | _O_WTEXT | _O_U16TEXT | _O_U8TEXT) ) == 0 )
            {
                /* Type specified in default mode? */
                if ( (fmode & (_O_TEXT | _O_WTEXT | _O_U16TEXT | _O_U8TEXT) ) == 0)
                    oflag |= _O_TEXT; /* default to ANSI */
                else
                    oflag |= fmode & (_O_TEXT | _O_WTEXT | _O_U16TEXT | _O_U8TEXT);
            }

            /* Now oflags should be set to one of the text modes */
            _ASSERTE( (oflag & (_O_TEXT | _O_WTEXT | _O_U16TEXT | _O_U8TEXT) ) != 0 );

            switch ( oflag & (_O_TEXT | _O_WTEXT | _O_U16TEXT | _O_U8TEXT) )
            {
            case _O_TEXT :
                tmode = __IOINFO_TM_ANSI;
                break;
            case _O_WTEXT :
            case _O_WTEXT | _O_TEXT :
                if ( (oflag & (_O_WRONLY | _O_CREAT | _O_TRUNC)) ==
                    (_O_WRONLY | _O_CREAT | _O_TRUNC) )
                    tmode = __IOINFO_TM_UTF16LE;
                break;
            case _O_U16TEXT :
            case _O_U16TEXT | _O_TEXT :
                tmode = __IOINFO_TM_UTF16LE;
                break;

            case _O_U8TEXT :
            case _O_U8TEXT | _O_TEXT :
                tmode = __IOINFO_TM_UTF8;
                break;
            }

            /* If the file hasn't been opened with the UNICODE flags then we
            have nothing to do - textmode's already set to default specified in oflag */
            if((oflag & (_O_WTEXT | _O_U16TEXT | _O_U8TEXT)) != 0) {

                int bom = 0;
                int bWriteBom = 0;
                int bCheckBom = 0;

                if ( !(fileflags & FDEV) ) {
                        switch ( fileaccess & (GENERIC_READ | GENERIC_WRITE) ) {

                        case GENERIC_READ :
                                {
                                        bCheckBom = 1;
                                        break;
                                }

                        case GENERIC_WRITE :
                                {
                                        switch ( filecreate ) {
                                            /* Write BOM if empty file */
                                        case OPEN_EXISTING :
                                        case OPEN_ALWAYS :
                                        {
                                            /* Check if the file contains at least one byte */
                                            /* Fall through otherwise */
                                            if( _lseeki64_nolock(*pfh, 0, SEEK_END) != 0) {
                                                if(_lseeki64_nolock(*pfh, 0, SEEK_SET) == -1) {
                                                    _close_nolock(*pfh);

⌨️ 快捷键说明

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