📄 open.c
字号:
retvalue = errno;
goto exit;
}
break;
}
}
/* New or truncated file. Always write BOM */
case CREATE_NEW :
case CREATE_ALWAYS :
case TRUNCATE_EXISTING :
{
bWriteBom = 1;
break;
}
}
break;
}
case GENERIC_READ | GENERIC_WRITE :
{
switch ( filecreate ) {
/* Check for existing BOM, 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);
retvalue = errno;
goto exit;
}
bCheckBom = 1;
}
else {
bWriteBom = 1; /* reset if file is not zero size */
}
break;
}
/* New or truncated file. Always write BOM */
case CREATE_NEW :
case TRUNCATE_EXISTING :
case CREATE_ALWAYS :
{
bWriteBom = 1;
break;
}
}
break;
}
}
}
if ( bCheckBom ) {
count = _read_nolock(*pfh, &bom, UTF8_BOMLEN);
/*
Internal Validation.
This branch should never be taken if bWriteBom is 1 and count > 0
*/
if (count > 0 && bWriteBom == 1) {
_ASSERTE(0 && "Internal Error");
bWriteBom = 0;
}
switch(count) {
case -1 :
_close_nolock(*pfh);
retvalue = errno;
goto exit;
case UTF8_BOMLEN:
if(bom == UTF8_BOM) {
tmode = __IOINFO_TM_UTF8;
break;
}
case UTF16_BOMLEN:
if((bom & BOM_MASK) == UTF16BE_BOM) {
_close_nolock(*pfh);
_ASSERTE(0 && "Only UTF-16 little endian & UTF-8 is supported for reads");
retvalue = errno = EINVAL;
goto exit;
}
if((bom & BOM_MASK) == UTF16LE_BOM) {
/* We have read 3 bytes, so we should seek back
1 byte */
if((filepos = _lseek_nolock(*pfh, UTF16_BOMLEN, SEEK_SET)) == -1) {
_close_nolock(*pfh);
retvalue = errno;
goto exit;
}
tmode = __IOINFO_TM_UTF16LE;
break;
}
/* Fall through to default case to lseek to
beginning of file */
default:
if((filepos = _lseek_nolock(*pfh, 0, SEEK_SET)) == -1) {
/* No BOM, so we should seek back to the beginning
of the file */
_close_nolock(*pfh);
retvalue = errno;
goto exit;
}
break;
}
}
if( bWriteBom ) {
int written = 0;
int bomlen = 0;
bom = 0;
/* If we are creating a new file, we write a UTF-16LE or UTF8 BOM */
switch (tmode)
{
case __IOINFO_TM_UTF16LE :
{
bom = UTF16LE_BOM;
bomlen = UTF16_BOMLEN;
break;
}
case __IOINFO_TM_UTF8 :
{
bom = UTF8_BOM;
bomlen = UTF8_BOMLEN;
break;
}
}
while (bomlen > written) {
int tmp = 0;
/*
* Note that write may write less than bomlen characters, but not really fail.
* Retry till write fails or till we wrote all the characters.
*/
if ((tmp = _write(*pfh, ((char *)(&bom)) + written, bomlen - written)) == -1) {
_close_nolock(*pfh);
retvalue = errno;
goto exit;
}
written += tmp;
}
}
}
}
_textmode(*pfh) = tmode;
_tm_unicode(*pfh) = ((oflag & _O_WTEXT) == 0) ? 0 : 1;
/*
* Set FAPPEND flag if appropriate. Don't do this for devices or pipes.
*/
if ( !(fileflags & (FDEV|FPIPE)) && (oflag & _O_APPEND) )
_osfile(*pfh) |= FAPPEND;
/*
* re-open the file with write access only if we opened the file
* with read access to read the BOM before
*/
if ((fileaccess & (GENERIC_READ | GENERIC_WRITE)) == (GENERIC_READ|GENERIC_WRITE) &&
(oflag & _O_WRONLY))
{
// we will have to reopen the file again with the write access (but not read)
CloseHandle(osfh);
fileaccess &= ~GENERIC_READ;
// we want to use OPEN_EXISTING here, because the user can open the an non-existing
// file for append with _O_EXCL flag
filecreate = OPEN_EXISTING;
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 *necessary* to
* call _free_osfhnd (unlike the situation before), because we have
* already set the file handle in the _ioinfo structure
*/
_dosmaperr(GetLastError());
_osfile(*pfh) &= ~FOPEN;
_free_osfhnd(*pfh);
retvalue = errno;
goto exit;
}
else
{
// We were able to open the file successfully, set the file
// handle in the _ioinfo structure, then we are done. All
// the fileflags should have been set properly already.
_osfhnd(*pfh) = (intptr_t)osfh;
}
}
exit:
return retvalue;
}
/***
*int _sopen(path, oflag, shflag, pmode) - opne a file with sharing
*
*Purpose:
* Opens the file with possible file sharing.
* shflag defines the sharing flags:
* _SH_COMPAT - set compatability mode
* _SH_DENYRW - deny read and write access to the file
* _SH_DENYWR - deny write access to the file
* _SH_DENYRD - deny read access to the file
* _SH_DENYNO - permit read and write access
*
* Other flags are the same as _open().
*
* SOPEN is the routine used when file sharing is desired.
*
*Entry:
* _TSCHAR *path - file to open
* int oflag - open flag
* int shflag - sharing flag
* int pmode - permission mode (needed only when creating file)
*
*Exit:
* returns file handle for the opened file
* returns -1 and sets errno if fails.
*
*Exceptions:
*
*******************************************************************************/
int __cdecl _tsopen (
const _TSCHAR *path,
int oflag,
int shflag,
...
)
{
va_list ap;
int pmode = 0;
int fh = -1;
errno_t e;
va_start(ap, shflag);
pmode = va_arg(ap, int);
va_end(ap);
/* Last parameter passed as 0 because we don't want to
validate pmode from open */
e = _tsopen_helper(path, oflag, shflag, pmode, &fh, 0);
return e ? -1 : fh;
}
/***
*int _sopen_s(pfh, path, oflag, shflag, pmode) - open a file with sharing
*
*Purpose:
* Check comments for _sopen. This works similiar to _sopen except
* it validates the pmode.
*
*Entry:
* _TSCHAR *path - file to open
* int oflag - open flag
* int shflag - sharing flag
* int pmode - permission mode (needed only when creating file)
* int * pfh - pointer to write the file handle to.
*
*Exit:
* returns 0 on success & sets pfile
* returns errno_t on failure.
* On success, the file handle is written to the pfh parameter.
*
*Exceptions:
*
*******************************************************************************/
errno_t __cdecl _tsopen_s (
int * pfh,
const _TSCHAR *path,
int oflag,
int shflag,
int pmode
)
{
/* Last parameter passed as 1 because we want to validate
* pmode from the secure open_s */
return _tsopen_helper(path, oflag, shflag, pmode, pfh, 1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -