📄 os0file.c
字号:
char* name = tempnam(fil_path_to_mysql_datadir, "ib"); if (!name) { break; } fd = open(name,# ifdef __WIN__ O_SEQUENTIAL | O_SHORT_LIVED | O_TEMPORARY |# endif /* __WIN__ */ O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE); if (fd >= 0) {# ifndef __WIN__ unlink(name);# endif /* !__WIN__ */ free(name); break; } ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Warning: " "unable to create temporary file %s, retrying\n", name); free(name); }# else /* UNIV_HOTBACKUP */ fd = innobase_mysql_tmpfile();# endif /* UNIV_HOTBACKUP */ if (fd >= 0) { file = fdopen(fd, "w+b"); }#endif /* __NETWARE__ */ if (!file) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Error: unable to create temporary file;" " errno: %d\n", errno);#ifndef __NETWARE__ if (fd >= 0) { close(fd); }#endif /* !__NETWARE__ */ } return(file);}/***************************************************************************The os_file_opendir() function opens a directory stream corresponding to thedirectory named by the dirname argument. The directory stream is positionedat the first entry. In both Unix and Windows we automatically skip the '.'and '..' items at the start of the directory listing. */os_file_dir_tos_file_opendir(/*============*/ /* out: directory stream, NULL if error */ const char* dirname, /* in: directory name; it must not contain a trailing '\' or '/' */ ibool error_is_fatal) /* in: TRUE if we should treat an error as a fatal error; if we try to open symlinks then we do not wish a fatal error if it happens not to be a directory */{ os_file_dir_t dir;#ifdef __WIN__ LPWIN32_FIND_DATA lpFindFileData; char path[OS_FILE_MAX_PATH + 3]; ut_a(strlen(dirname) < OS_FILE_MAX_PATH); strcpy(path, dirname); strcpy(path + strlen(path), "\\*"); /* Note that in Windows opening the 'directory stream' also retrieves the first entry in the directory. Since it is '.', that is no problem, as we will skip over the '.' and '..' entries anyway. */ lpFindFileData = ut_malloc(sizeof(WIN32_FIND_DATA)); dir = FindFirstFile((LPCTSTR) path, lpFindFileData); ut_free(lpFindFileData); if (dir == INVALID_HANDLE_VALUE) { if (error_is_fatal) { os_file_handle_error(dirname, "opendir"); } return(NULL); } return(dir); #else dir = opendir(dirname); if (dir == NULL && error_is_fatal) { os_file_handle_error(dirname, "opendir"); } return(dir);#endif}/***************************************************************************Closes a directory stream. */intos_file_closedir(/*=============*/ /* out: 0 if success, -1 if failure */ os_file_dir_t dir) /* in: directory stream */{#ifdef __WIN__ BOOL ret; ret = FindClose(dir); if (!ret) { os_file_handle_error_no_exit(NULL, "closedir"); return(-1); } return(0);#else int ret; ret = closedir(dir); if (ret) { os_file_handle_error_no_exit(NULL, "closedir"); } return(ret);#endif}/***************************************************************************This function returns information of the next file in the directory. We jumpover the '.' and '..' entries in the directory. */intos_file_readdir_next_file(/*======================*/ /* out: 0 if ok, -1 if error, 1 if at the end of the directory */ const char* dirname,/* in: directory name or path */ os_file_dir_t dir, /* in: directory stream */ os_file_stat_t* info) /* in/out: buffer where the info is returned */{#ifdef __WIN__ LPWIN32_FIND_DATA lpFindFileData; BOOL ret; lpFindFileData = ut_malloc(sizeof(WIN32_FIND_DATA));next_file: ret = FindNextFile(dir, lpFindFileData); if (ret) { ut_a(strlen((char *) lpFindFileData->cFileName) < OS_FILE_MAX_PATH); if (strcmp((char *) lpFindFileData->cFileName, ".") == 0 || strcmp((char *) lpFindFileData->cFileName, "..") == 0) { goto next_file; } strcpy(info->name, (char *) lpFindFileData->cFileName); info->size = (ib_longlong)(lpFindFileData->nFileSizeLow) + (((ib_longlong)(lpFindFileData->nFileSizeHigh)) << 32); if (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {/* TODO: test Windows symlinks *//* TODO: MySQL has apparently its own symlink implementation in Windows,dbname.sym can redirect a database directory:http://www.mysql.com/doc/en/Windows_symbolic_links.html */ info->type = OS_FILE_TYPE_LINK; } else if (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { info->type = OS_FILE_TYPE_DIR; } else { /* It is probably safest to assume that all other file types are normal. Better to check them rather than blindly skip them. */ info->type = OS_FILE_TYPE_FILE; } } ut_free(lpFindFileData); if (ret) { return(0); } else if (GetLastError() == ERROR_NO_MORE_FILES) { return(1); } else { os_file_handle_error_no_exit(dirname, "readdir_next_file"); return(-1); }#else struct dirent* ent; char* full_path; int ret; struct stat statinfo;#ifdef HAVE_READDIR_R char dirent_buf[sizeof(struct dirent) + _POSIX_PATH_MAX + 100]; /* In /mysys/my_lib.c, _POSIX_PATH_MAX + 1 is used as the max file name len; but in most standards, the length is NAME_MAX; we add 100 to be even safer */#endifnext_file:#ifdef HAVE_READDIR_R ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent); if (ret != 0) { fprintf(stderr,"InnoDB: cannot read directory %s, error %lu\n", dirname, (ulong)ret); return(-1); } if (ent == NULL) { /* End of directory */ return(1); } ut_a(strlen(ent->d_name) < _POSIX_PATH_MAX + 100 - 1);#else ent = readdir(dir); if (ent == NULL) { return(1); }#endif ut_a(strlen(ent->d_name) < OS_FILE_MAX_PATH); if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { goto next_file; } strcpy(info->name, ent->d_name); full_path = ut_malloc(strlen(dirname) + strlen(ent->d_name) + 10); sprintf(full_path, "%s/%s", dirname, ent->d_name); ret = stat(full_path, &statinfo); if (ret) { os_file_handle_error_no_exit(full_path, "stat"); ut_free(full_path); return(-1); } info->size = (ib_longlong)statinfo.st_size; if (S_ISDIR(statinfo.st_mode)) { info->type = OS_FILE_TYPE_DIR; } else if (S_ISLNK(statinfo.st_mode)) { info->type = OS_FILE_TYPE_LINK; } else if (S_ISREG(statinfo.st_mode)) { info->type = OS_FILE_TYPE_FILE; } else { info->type = OS_FILE_TYPE_UNKNOWN; } ut_free(full_path); return(0);#endif}/*********************************************************************This function attempts to create a directory named pathname. The new directorygets default permissions. On Unix the permissions are (0770 & ~umask). If thedirectory exists already, nothing is done and the call succeeds, unless thefail_if_exists arguments is true. */iboolos_file_create_directory(/*=====================*/ /* out: TRUE if call succeeds, FALSE on error */ const char* pathname, /* in: directory name as null-terminated string */ ibool fail_if_exists) /* in: if TRUE, pre-existing directory is treated as an error. */{#ifdef __WIN__ BOOL rcode; rcode = CreateDirectory((LPCTSTR) pathname, NULL); if (!(rcode != 0 || (GetLastError() == ERROR_ALREADY_EXISTS && !fail_if_exists))) { /* failure */ os_file_handle_error(pathname, "CreateDirectory"); return(FALSE); } return (TRUE);#else int rcode; rcode = mkdir(pathname, 0770); if (!(rcode == 0 || (errno == EEXIST && !fail_if_exists))) { /* failure */ os_file_handle_error(pathname, "mkdir"); return(FALSE); } return (TRUE);#endif }/********************************************************************A simple function to open or create a file. */os_file_tos_file_create_simple(/*==================*/ /* out, own: handle to the file, not defined if error, error number can be retrieved with os_file_get_last_error */ const char* name, /* in: name of the file or path as a null-terminated string */ ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened (if does not exist, error), or OS_FILE_CREATE if a new file is created (if exists, error), or OS_FILE_CREATE_PATH if new file (if exists, error) and subdirectories along its path are created (if needed)*/ ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */ ibool* success)/* out: TRUE if succeed, FALSE if error */{#ifdef __WIN__ os_file_t file; DWORD create_flag; DWORD access; DWORD attributes = 0; ibool retry; try_again: ut_a(name); if (create_mode == OS_FILE_OPEN) { create_flag = OPEN_EXISTING; } else if (create_mode == OS_FILE_CREATE) { create_flag = CREATE_NEW; } else if (create_mode == OS_FILE_CREATE_PATH) { /* create subdirs along the path if needed */ *success = os_file_create_subdirs_if_needed(name); if (!*success) { ut_error; } create_flag = CREATE_NEW; create_mode = OS_FILE_CREATE; } else { create_flag = 0; ut_error; } if (access_type == OS_FILE_READ_ONLY) { access = GENERIC_READ; } else if (access_type == OS_FILE_READ_WRITE) { access = GENERIC_READ | GENERIC_WRITE; } else { access = 0; ut_error; } file = CreateFile((LPCTSTR) name, access, FILE_SHARE_READ | FILE_SHARE_WRITE, /* file can be read ansd written also by other processes */ NULL, /* default security attributes */ create_flag, attributes, NULL); /* no template file */ if (file == INVALID_HANDLE_VALUE) { *success = FALSE; retry = os_file_handle_error(name, create_mode == OS_FILE_OPEN ? "open" : "create"); if (retry) { goto try_again; } } else { *success = TRUE; } return(file);#else /* __WIN__ */ os_file_t file; int create_flag; ibool retry; try_again: ut_a(name); if (create_mode == OS_FILE_OPEN) { if (access_type == OS_FILE_READ_ONLY) { create_flag = O_RDONLY; } else { create_flag = O_RDWR; } } else if (create_mode == OS_FILE_CREATE) { create_flag = O_RDWR | O_CREAT | O_EXCL; } else if (create_mode == OS_FILE_CREATE_PATH) { /* create subdirs along the path if needed */ *success = os_file_create_subdirs_if_needed(name); if (!*success) { return (-1); } create_flag = O_RDWR | O_CREAT | O_EXCL; create_mode = OS_FILE_CREATE; } else { create_flag = 0; ut_error; } if (create_mode == OS_FILE_CREATE) { file = open(name, create_flag, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); } else { file = open(name, create_flag); } if (file == -1) { *success = FALSE; retry = os_file_handle_error(name, create_mode == OS_FILE_OPEN ? "open" : "create"); if (retry) { goto try_again; }#ifdef USE_FILE_LOCK } else if (access_type == OS_FILE_READ_WRITE && os_file_lock(file, name)) { *success = FALSE; close(file); file = -1;#endif } else { *success = TRUE; } return(file); #endif /* __WIN__ */}/********************************************************************A simple function to open or create a file. */os_file_tos_file_create_simple_no_error_handling(/*====================================*/ /* out, own: handle to the file, not defined if error, error number can be retrieved with os_file_get_last_error */ const char* name, /* in: name of the file or path as a null-terminated string */ ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened (if does not exist, error), or OS_FILE_CREATE if a new file is created (if exists, error) */ ulint access_type,/* in: OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or OS_FILE_READ_ALLOW_DELETE; the last option is used by a backup program reading the file */ ibool* success)/* out: TRUE if succeed, FALSE if error */{#ifdef __WIN__ os_file_t file; DWORD create_flag; DWORD access; DWORD attributes = 0; DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE; ut_a(name); if (create_mode == OS_FILE_OPEN) { create_flag = OPEN_EXISTING; } else if (create_mode == OS_FILE_CREATE) { create_flag = CREATE_NEW; } else { create_flag = 0; ut_error; } if (access_type == OS_FILE_READ_ONLY) { access = GENERIC_READ; } else if (access_type == OS_FILE_READ_WRITE) { access = GENERIC_READ | GENERIC_WRITE; } else if (access_type == OS_FILE_READ_ALLOW_DELETE) { access = GENERIC_READ; share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE; /* A backup program has to give mysqld the maximum freedom to do what it likes with the file */ } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -