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 | |
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')
-rw-r--r-- | innobase/include/os0file.h | 58 | ||||
-rw-r--r-- | innobase/include/ut0mem.h | 9 | ||||
-rw-r--r-- | innobase/os/os0file.c | 201 | ||||
-rw-r--r-- | innobase/ut/ut0mem.c | 24 |
4 files changed, 290 insertions, 2 deletions
diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 5f2d6e3ed21..b9bb8aafe2e 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -60,6 +60,7 @@ log. */ #define OS_FILE_CREATE 52 #define OS_FILE_OVERWRITE 53 #define OS_FILE_OPEN_RAW 54 +#define OS_FILE_CREATE_PATH 55 #define OS_FILE_READ_ONLY 333 #define OS_FILE_READ_WRITE 444 @@ -228,7 +229,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 */ /******************************************************************** @@ -421,6 +424,59 @@ os_file_write( ulint offset_high,/* in: most significant 32 bits of offset */ ulint n); /* in: number of bytes to write */ +/*********************************************************************** +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) */ +/******************************************************************** +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 */ +/******************************************************************** +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 */ /**************************************************************************** Initializes the asynchronous io system. Creates separate aio array for non-ibuf read and write, a third aio array for the ibuf i/o, with just one diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index ce8aabeca41..b7dfe77a08e 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -96,6 +96,15 @@ ut_str_catenate( char* str1, /* in: null-terminated string */ char* str2); /* in: null-terminated string */ /************************************************************************** +Return a copy of the given string. The returned string must be freed +using mem_free. */ + +char* +ut_strdup( +/*======*/ + /* out, own: cnull-terminated string */ + char* str); /* in: null-terminated string */ +/************************************************************************** Checks if a null-terminated string contains a certain character. */ ibool 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 diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index 65229335a09..f7c0e1be9bd 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -282,3 +282,27 @@ ut_str_contains( return(FALSE); } + +/************************************************************************** +Return a copy of the given string. The returned string must be freed +using mem_free. */ + +char* +ut_strdup( +/*======*/ + /* out, own: cnull-terminated string */ + char* str) /* in: null-terminated string */ +{ + ulint len; + char* copy; + + len = ut_strlen(str); + + copy = mem_alloc(len + 1); + + ut_memcpy(copy, str, len); + + copy[len] = 0; + + return(copy); +} |