📄 os0file.c
字号:
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN); if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) { os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; os_mutex_exit(os_file_count_mutex); goto error_handling; } ret = ReadFile(file, buf, (DWORD) n, &len, NULL); os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; os_mutex_exit(os_file_count_mutex); if (ret && len == n) { return(TRUE); } #else ibool retry; ssize_t ret; os_bytes_read_since_printout += n;try_again: ret = os_file_pread(file, buf, n, offset, offset_high); if ((ulint)ret == n) { return(TRUE); } fprintf(stderr,"InnoDB: Error: tried to read %lu bytes at offset %lu %lu.\n""InnoDB: Was only able to read %ld.\n", (ulong)n, (ulong)offset_high, (ulong)offset, (long)ret);#endif #ifdef __WIN__error_handling:#endif retry = os_file_handle_error(NULL, "read"); if (retry) { goto try_again; } fprintf(stderr,"InnoDB: Fatal error: cannot read from file. OS error number %lu.\n",#ifdef __WIN__ (ulong) GetLastError()#else (ulong) errno#endif ); fflush(stderr); ut_error; return(FALSE);}/***********************************************************************Requests a synchronous positioned read operation. This function does not doany error handling. In case of error it returns FALSE. */iboolos_file_read_no_error_handling(/*===========================*/ /* out: TRUE if request was successful, FALSE if fail */ os_file_t file, /* in: handle to a file */ void* buf, /* in: buffer where to read */ ulint offset, /* in: least significant 32 bits of file offset where to read */ ulint offset_high, /* in: most significant 32 bits of offset */ ulint n) /* in: number of bytes to read */ {#ifdef __WIN__ BOOL ret; DWORD len; DWORD ret2; DWORD low; DWORD high; ibool retry; ulint i; ut_a((offset & 0xFFFFFFFFUL) == offset); os_n_file_reads++; os_bytes_read_since_printout += n;try_again: ut_ad(file); ut_ad(buf); ut_ad(n > 0); low = (DWORD) offset; high = (DWORD) offset_high; os_mutex_enter(os_file_count_mutex); os_n_pending_reads++; os_mutex_exit(os_file_count_mutex); /* Protect the seek / read operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; os_mutex_enter(os_file_seek_mutexes[i]); ret2 = SetFilePointer(file, low, &high, FILE_BEGIN); if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) { os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; os_mutex_exit(os_file_count_mutex); goto error_handling; } ret = ReadFile(file, buf, (DWORD) n, &len, NULL); os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_enter(os_file_count_mutex); os_n_pending_reads--; os_mutex_exit(os_file_count_mutex); if (ret && len == n) { return(TRUE); } #else ibool retry; ssize_t ret; os_bytes_read_since_printout += n;try_again: ret = os_file_pread(file, buf, n, offset, offset_high); if ((ulint)ret == n) { return(TRUE); }#endif #ifdef __WIN__error_handling:#endif retry = os_file_handle_error_no_exit(NULL, "read"); if (retry) { goto try_again; } return(FALSE);}/***********************************************************************Rewind file to its start, read at most size - 1 bytes from it to str, andNUL-terminate str. All errors are silently ignored. This function ismostly meant to be used with temporary files. */voidos_file_read_string(/*================*/ FILE* file, /* in: file to read from */ char* str, /* in: buffer where to read */ ulint size) /* in: size of buffer */{ size_t flen; if (size == 0) { return; } rewind(file); flen = fread(str, 1, size - 1, file); str[flen] = '\0';}/***********************************************************************Requests a synchronous write operation. */iboolos_file_write(/*==========*/ /* out: TRUE if request was successful, FALSE if fail */ const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ const void* buf, /* in: buffer from which to write */ ulint offset, /* in: least significant 32 bits of file offset where to write */ ulint offset_high, /* in: most significant 32 bits of offset */ ulint n) /* in: number of bytes to write */ {#ifdef __WIN__ BOOL ret; DWORD len; DWORD ret2; DWORD low; DWORD high; ulint i; ulint n_retries = 0; ulint err; ut_a((offset & 0xFFFFFFFF) == offset); os_n_file_writes++; ut_ad(file); ut_ad(buf); ut_ad(n > 0);retry: low = (DWORD) offset; high = (DWORD) offset_high; os_mutex_enter(os_file_count_mutex); os_n_pending_writes++; os_mutex_exit(os_file_count_mutex); /* Protect the seek / write operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; os_mutex_enter(os_file_seek_mutexes[i]); ret2 = SetFilePointer(file, low, &high, FILE_BEGIN); if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) { os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_enter(os_file_count_mutex); os_n_pending_writes--; os_mutex_exit(os_file_count_mutex); ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Error: File pointer positioning to file %s failed at\n""InnoDB: offset %lu %lu. Operating system error number %lu.\n""InnoDB: Some operating system error numbers are described at\n""InnoDB: ""http://dev.mysql.com/doc/mysql/en/Operating_System_error_codes.html\n", name, (ulong) offset_high, (ulong) offset, (ulong) GetLastError()); return(FALSE); } ret = WriteFile(file, buf, (DWORD) n, &len, NULL); /* Always do fsync to reduce the probability that when the OS crashes, a database page is only partially physically written to disk. */# ifdef UNIV_DO_FLUSH if (!os_do_not_call_flush_at_each_write) { ut_a(TRUE == os_file_flush(file)); }# endif /* UNIV_DO_FLUSH */ os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_enter(os_file_count_mutex); os_n_pending_writes--; os_mutex_exit(os_file_count_mutex); if (ret && len == n) { return(TRUE); } /* If some background file system backup tool is running, then, at least in Windows 2000, we may get here a specific error. Let us retry the operation 100 times, with 1 second waits. */ if (GetLastError() == ERROR_LOCK_VIOLATION && n_retries < 100) { os_thread_sleep(1000000); n_retries++; goto retry; } if (!os_has_said_disk_full) { err = (ulint)GetLastError(); ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Error: Write to file %s failed at offset %lu %lu.\n""InnoDB: %lu bytes should have been written, only %lu were written.\n""InnoDB: Operating system error number %lu.\n""InnoDB: Check that your OS and file system support files of this size.\n""InnoDB: Check also that the disk is not full or a disk quota exceeded.\n", name, (ulong) offset_high, (ulong) offset, (ulong) n, (ulong) len, (ulong) err); if (strerror((int)err) != NULL) { fprintf(stderr,"InnoDB: Error number %lu means '%s'.\n", (ulong) err, strerror((int)err)); } fprintf(stderr,"InnoDB: Some operating system error numbers are described at\n""InnoDB: ""http://dev.mysql.com/doc/mysql/en/Operating_System_error_codes.html\n"); os_has_said_disk_full = TRUE; } return(FALSE);#else ssize_t ret; ret = os_file_pwrite(file, buf, n, offset, offset_high); if ((ulint)ret == n) { return(TRUE); } if (!os_has_said_disk_full) { ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Error: Write to file %s failed at offset %lu %lu.\n""InnoDB: %lu bytes should have been written, only %ld were written.\n""InnoDB: Operating system error number %lu.\n""InnoDB: Check that your OS and file system support files of this size.\n""InnoDB: Check also that the disk is not full or a disk quota exceeded.\n", name, offset_high, offset, n, (long int)ret, (ulint)errno); if (strerror(errno) != NULL) { fprintf(stderr,"InnoDB: Error number %lu means '%s'.\n", (ulint)errno, strerror(errno)); } fprintf(stderr,"InnoDB: Some operating system error numbers are described at\n""InnoDB: ""http://dev.mysql.com/doc/mysql/en/Operating_System_error_codes.html\n"); os_has_said_disk_full = TRUE; } return(FALSE); #endif}/***********************************************************************Check the existence and type of the given file. */iboolos_file_status(/*===========*/ /* out: TRUE if call succeeded */ const char* path, /* in: pathname of the file */ ibool* exists, /* out: TRUE if file exists */ os_file_type_t* type) /* out: type of the file (if it exists) */{#ifdef __WIN__ int ret; struct _stat statinfo; ret = _stat(path, &statinfo); if (ret && (errno == ENOENT || errno == ENOTDIR)) { /* file does not exist */ *exists = FALSE; return(TRUE); } else if (ret) { /* file exists, but stat call failed */ os_file_handle_error_no_exit(path, "stat"); return(FALSE); } if (_S_IFDIR & statinfo.st_mode) { *type = OS_FILE_TYPE_DIR; } else if (_S_IFREG & statinfo.st_mode) { *type = OS_FILE_TYPE_FILE; } else { *type = OS_FILE_TYPE_UNKNOWN; } *exists = TRUE; return(TRUE);#else int ret; struct stat statinfo; ret = stat(path, &statinfo); if (ret && (errno == ENOENT || errno == ENOTDIR)) { /* file does not exist */ *exists = FALSE; return(TRUE); } else if (ret) { /* file exists, but stat call failed */ os_file_handle_error_no_exit(path, "stat"); return(FALSE); } if (S_ISDIR(statinfo.st_mode)) { *type = OS_FILE_TYPE_DIR; } else if (S_ISLNK(statinfo.st_mode)) { *type = OS_FILE_TYPE_LINK; } else if (S_ISREG(statinfo.st_mode)) { *type = OS_FILE_TYPE_FILE; } else { *type = OS_FILE_TYPE_UNKNOWN; } *exists = TRUE; return(TRUE);#endif}/***********************************************************************This function returns information about the specified file */iboolos_file_get_status(/*===========*/ /* out: TRUE if stat information found */ const char* path, /* in: pathname of the file */ os_file_stat_t* stat_info) /* information of a file in a directory */{#ifdef __WIN__ int ret; struct _stat statinfo; ret = _stat(path, &statinfo); if (ret && (errno == ENOENT || errno == ENOTDIR)) { /* file does not exist */ return(FALSE); } else if (ret) { /* file exists, but stat call failed */ os_file_handle_error_no_exit(path, "stat"); return(FALSE); } if (_S_IFDIR & statinfo.st_mode) { stat_info->type = OS_FILE_TYPE_DIR; } else if (_S_IFREG & statinfo.st_mode) { stat_info->type = OS_FILE_TYPE_FILE; } else { stat_info->type = OS_FILE_TYPE_UNKNOWN; } stat_info->ctime = statinfo.st_ctime; stat_info->atime = statinfo.st_atime; stat_info->mtime = statinfo.st_mtime; stat_info->size = statinfo.st_size; return(TRUE);#else int ret; struct stat statinfo; ret = stat(path, &statinfo); if (ret && (errno == ENOENT || errno == ENOTDIR)) { /* file does not exist */ return(FALSE); } else if (ret) { /* file exists, but stat call failed */ os_file_handle_error_no_exit(path, "stat"); return(FALSE); } if (S_ISDIR(statinfo.st_mode)) { stat_info->type = OS_FILE_TYPE_DIR; } else if (S_ISLNK(statinfo.st_mode)) { stat_info->type = OS_FILE_TYPE_LINK; } else if (S_ISREG(statinfo.st_mode)) { stat_info->type = OS_FILE_TYPE_FILE; } else { stat_info->type = OS_FILE_TYPE_UNKNOWN; } stat_info->ctime = statinfo.st_ctime; stat_info->atime = statinfo.st_atime; stat_info->mtime = statinfo.st_mtime; stat_info->size = statinfo.st_size; return(TRUE);#endif}/* path name separator character */#ifdef __WIN__# define OS_FILE_PATH_SEPARATOR '\\'#else# define OS_FILE_PATH_SEPARATOR '/'#endif/********************************************************************The function os_file_dirname returns a directory component of anull-terminated pathname string. In the usual case, dirname returnsthe string up to, but not including, the final '/', and basenameis the component following the final '/'. Trailing '/' charac
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -