diff options
author | unknown <heikki@hundin.mysql.fi> | 2004-03-16 20:55:49 +0200 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2004-03-16 20:55:49 +0200 |
commit | 217a102fa82d9f0831b16655ce28fe1cc5df41f6 (patch) | |
tree | f1556d71c0e45f7e6d5093e9acbc4c8aac4ea930 /innobase/os | |
parent | d626b52f7fb603e27c10fa976e9998b868f1543e (diff) | |
download | mariadb-git-217a102fa82d9f0831b16655ce28fe1cc5df41f6.tar.gz |
ut0mem.h, ut0mem.c:
Add ut_strdup
os0file.h, os0file.c:
Add creation of directories
innobase/os/os0file.c:
Add creation of directories
innobase/ut/ut0mem.c:
Add ut_strdup
innobase/include/os0file.h:
Add creation of directories
innobase/include/ut0mem.h:
Add ut_strdup
Diffstat (limited to 'innobase/os')
-rw-r--r-- | innobase/os/os0file.c | 201 |
1 files changed, 200 insertions, 1 deletions
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index a87ab974b83..048fd29b318 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -6,6 +6,8 @@ The interface to the operating system file i/o primitives Created 10/21/1995 Heikki Tuuri *******************************************************/ +#include <sys/stat.h> + #include "os0file.h" #include "os0sync.h" #include "os0thread.h" @@ -716,7 +718,9 @@ os_file_create_simple( 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) */ + 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 */ { @@ -734,6 +738,14 @@ try_again: 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; @@ -787,6 +799,14 @@ try_again: } } 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; @@ -2114,6 +2134,185 @@ retry: #endif } +/*********************************************************************** +Check the existence and type of the given file. */ + +ibool +os_file_status( +/*===========*/ + /* out: TRUE if call succeeded */ + 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(0, 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(0, 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 +} + +/* 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 a +null-terminated pathname string. In the usual case, dirname returns +the string up to, but not including, the final '/', and basename +is the component following the final '/'. Trailing '/' charac +ters are not counted as part of the pathname. + +If path does not contain a slash, dirname returns the string ".". + +Concatenating the string returned by dirname, a "/", and the basename +yields a complete pathname. + +The return value is a copy of the directory component of the pathname. +The copy is allocated from heap. It is the caller responsibility +to free it after it is no longer needed. + +The following list of examples (taken from SUSv2) shows the strings +returned by dirname and basename for different paths: + + path dirname basename + "/usr/lib" "/usr" "lib" + "/usr/" "/" "usr" + "usr" "." "usr" + "/" "/" "/" + "." "." "." + ".." "." ".." +*/ + +char* +os_file_dirname( +/*============*/ + /* out, own: directory component of the + pathname */ + char* path) /* in: pathname */ +{ + char* dir; + int i, length, last_slash; + + /* find the offset of the last slash */ + length = ut_strlen(path); + for (i = length - 1; i >= 0 && path[i] != OS_FILE_PATH_SEPARATOR; i++); + last_slash = i; + + if (last_slash < 0) { + /* no slash in the path, return "." */ + return(ut_strdup((char*)".")); + } + + /* ok, there is a slash */ + + if (last_slash == 0) { + /* last slash is the first char of the path */ + return(ut_strdup((char*)"/")); + } + + /* non-trivial directory component */ + dir = ut_strdup(path); + dir[last_slash] = 0; + + return(dir); +} + +/******************************************************************** +Creates all missing subdirectories along the given path. */ + +ibool +os_file_create_subdirs_if_needed( +/*=============================*/ + /* out: TRUE if call succeeded + FALSE otherwise */ + char* path) /* in: path name */ +{ + char* subdir; + static char rootdir[2] = { OS_FILE_PATH_SEPARATOR, 0 }; + ibool success, subdir_exists; + os_file_type_t type; + + subdir = os_file_dirname(path); + if (0 == strcmp(subdir, rootdir) || 0 == strcmp(subdir, ".")) { + /* subdir is root or cwd, nothing to do */ + ut_free(subdir); + return(TRUE); + } + + /* test if subdir exists */ + success = os_file_status(subdir, &subdir_exists, &type); + if (success && !subdir_exists) { + /* subdir does not exist, create it */ + success = os_file_create_subdirs_if_needed(subdir); + if (!success) { + ut_free(subdir); + return(FALSE); + } + success = os_file_create_directory(subdir, FALSE); + } + + ut_free(subdir); + return(success); +} + /******************************************************************** Returns a pointer to the nth slot in the aio array. */ static |