in mysql_sys/my_winfile.cc [230:370]
File my_win_sopen(const char *path, int oflag, int shflag, int pmode) {
DBUG_TRACE;
WindowsErrorGuard weg;
if (check_if_legal_filename(path)) {
assert(GetLastError() == ERROR_SUCCESS);
errno = EACCES;
return -1;
}
SECURITY_ATTRIBUTES SecurityAttributes;
SecurityAttributes.nLength = sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor = nullptr;
SecurityAttributes.bInheritHandle = !(oflag & _O_NOINHERIT);
// Decode the (requested) OS file access flags
DWORD fileaccess;
switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
case _O_RDONLY: /* read access */
fileaccess = GENERIC_READ;
break;
case _O_WRONLY: /* write access */
fileaccess = GENERIC_WRITE;
break;
case _O_RDWR: /* read and write access */
fileaccess = GENERIC_READ | GENERIC_WRITE;
break;
default: /* error, bad oflag */
errno = EINVAL;
return -1;
}
// Decode OS file sharing flags
DWORD fileshare;
switch (shflag) {
case _SH_DENYRW: /* exclusive access except delete */
fileshare = FILE_SHARE_DELETE;
break;
case _SH_DENYWR: /* share read and delete access */
fileshare = FILE_SHARE_READ | FILE_SHARE_DELETE;
break;
case _SH_DENYRD: /* share write and delete access */
fileshare = FILE_SHARE_WRITE | FILE_SHARE_DELETE;
break;
case _SH_DENYNO: /* share read, write and delete access */
fileshare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
break;
case _SH_DENYRWD: /* exclusive access */
fileshare = 0L;
break;
case _SH_DENYWRD: /* share read access */
fileshare = FILE_SHARE_READ;
break;
case _SH_DENYRDD: /* share write access */
fileshare = FILE_SHARE_WRITE;
break;
case _SH_DENYDEL: /* share read and write access */
fileshare = FILE_SHARE_READ | FILE_SHARE_WRITE;
break;
default: /* error, bad shflag */
errno = EINVAL;
return -1;
}
// Decode OS method of opening/creating
DWORD filecreate;
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 */
errno = EINVAL;
return -1;
}
// Decode OS file attribute flags if _O_CREAT was specified
DWORD fileattrib;
fileattrib = FILE_ATTRIBUTE_NORMAL; /* default */
int mask;
if (oflag & _O_CREAT) {
_umask((mask = _umask(0)));
assert(errno == 0);
if (!((pmode & ~mask) & _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;
}
/* 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;
/* try to open/create the file */
HANDLE osfh = CreateFile(path, fileaccess, fileshare, &SecurityAttributes,
filecreate, fileattrib, nullptr);
if (osfh == INVALID_HANDLE_VALUE) {
/*
Note that it's not necessary to
call _free_osfhnd (it hasn't been used yet).
*/
return -1;
}
int fh = RegisterHandle(osfh, oflag & (_O_APPEND | _O_RDONLY | _O_TEXT));
if (fh == -1) {
// No scope_guard for this since we only close in one place.
CloseHandle(osfh);
return -1;
}
return fh;
}