diff options
author | Sergei Golubchik <serg@mariadb.org> | 2017-02-20 22:41:17 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-02-27 12:35:10 +0100 |
commit | 6d50324558e79d6e90848059bf7cd918685b02ba (patch) | |
tree | c120ea5c18468c2947b0af18a4c79980e3f57f6f /mysys/my_symlink.c | |
parent | f2d24ea68b9fde45d9a221f2c2a5d75fd10ef650 (diff) | |
download | mariadb-git-6d50324558e79d6e90848059bf7cd918685b02ba.tar.gz |
support MY_NOSYMLINKS in my_delete()
Diffstat (limited to 'mysys/my_symlink.c')
-rw-r--r-- | mysys/my_symlink.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index bc01a68263d..ed35fff41e9 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -177,3 +177,78 @@ int my_realpath(char *to, const char *filename, myf MyFlags) #endif return 0; } + +#ifdef HAVE_OPEN_PARENT_DIR_NOSYMLINKS +/** opens the parent dir. walks the path, and does not resolve symlinks + + returns the pointer to the file name (basename) within the pathname + or NULL in case of an error + + stores the parent dir (dirname) file descriptor in pdfd. + It can be -1 even if there was no error! + + This is used for symlinked tables for DATA/INDEX DIRECTORY. + The paths there have been realpath()-ed. So, we can assume here that + + * `pathname` is an absolute path + * no '.', '..', and '//' in the path + * file exists +*/ + +const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd) +{ + char buf[PATH_MAX+1]; + char *s= buf, *e= buf+1, *end= strnmov(buf, pathname, sizeof(buf)); + int fd, dfd= -1; + + if (*end) + { + errno= ENAMETOOLONG; + return NULL; + } + + if (*s != '/') /* not an absolute path */ + { + errno= ENOENT; + return NULL; + } + + for (;;) + { + if (*e == '/') /* '//' in the path */ + { + errno= ENOENT; + goto err; + } + while (*e && *e != '/') + e++; + *e= 0; + + if (!memcmp(s, ".", 2) || !memcmp(s, "..", 3)) + { + errno= ENOENT; + goto err; + } + + if (++e >= end) + { + *pdfd= dfd; + return pathname + (s - buf); + } + + fd = openat(dfd, s, O_NOFOLLOW | O_PATH); + if (fd < 0) + goto err; + + if (dfd >= 0) + close(dfd); + + dfd= fd; + s= e; + } +err: + if (dfd >= 0) + close(dfd); + return NULL; +} +#endif |