mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
support MY_NOSYMLINKS in my_delete()
This commit is contained in:
parent
f2d24ea68b
commit
6d50324558
4 changed files with 118 additions and 84 deletions
|
|
@ -21,6 +21,12 @@
|
|||
static int my_win_unlink(const char *name);
|
||||
#endif
|
||||
|
||||
CREATE_NOSYMLINK_FUNCTION(
|
||||
unlink_nosymlinks(const char *pathname),
|
||||
unlinkat(dfd, filename, 0),
|
||||
unlink(pathname)
|
||||
);
|
||||
|
||||
int my_delete(const char *name, myf MyFlags)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -30,7 +36,10 @@ int my_delete(const char *name, myf MyFlags)
|
|||
#ifdef _WIN32
|
||||
err = my_win_unlink(name);
|
||||
#else
|
||||
err = unlink(name);
|
||||
if (MyFlags & MY_NOSYMLINKS)
|
||||
err= unlink_nosymlinks(name);
|
||||
else
|
||||
err= unlink(name);
|
||||
#endif
|
||||
|
||||
if(err)
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@
|
|||
#include <m_string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if !defined(O_PATH) && defined(O_EXEC) /* FreeBSD */
|
||||
#define O_PATH O_EXEC
|
||||
#endif
|
||||
|
||||
static int open_nosymlinks(const char *pathname, int flags, int mode);
|
||||
CREATE_NOSYMLINK_FUNCTION(
|
||||
open_nosymlinks(const char *pathname, int flags, int mode),
|
||||
openat(dfd, filename, O_NOFOLLOW | flags, mode),
|
||||
open(pathname, O_NOFOLLOW | flags, mode)
|
||||
);
|
||||
|
||||
/*
|
||||
Open a file
|
||||
|
|
@ -182,81 +182,3 @@ void my_print_open_files(void)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
like open(), but with symlinks are not accepted anywhere in the path
|
||||
|
||||
This is used for opening 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
|
||||
*/
|
||||
static int open_nosymlinks(const char *pathname, int flags, int mode)
|
||||
{
|
||||
#ifndef O_PATH
|
||||
#ifdef HAVE_REALPATH
|
||||
char buf[PATH_MAX+1];
|
||||
if (realpath(pathname, buf) == NULL)
|
||||
return -1;
|
||||
if (strcmp(pathname, buf))
|
||||
{
|
||||
errno= ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return open(pathname, flags, mode | O_NOFOLLOW);
|
||||
#else
|
||||
|
||||
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 -1;
|
||||
}
|
||||
|
||||
if (*s != '/') /* not an absolute path */
|
||||
{
|
||||
errno= ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
fd = openat(dfd, s, O_NOFOLLOW | (e < end ? O_PATH : flags), mode);
|
||||
if (fd < 0)
|
||||
goto err;
|
||||
|
||||
if (dfd >= 0)
|
||||
close(dfd);
|
||||
|
||||
dfd= fd;
|
||||
s= ++e;
|
||||
|
||||
if (e >= end)
|
||||
return fd;
|
||||
}
|
||||
err:
|
||||
if (dfd >= 0)
|
||||
close(dfd);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -89,6 +89,34 @@ void sf_free(void *ptr);
|
|||
|
||||
void my_error_unregister_all(void);
|
||||
|
||||
#if !defined(O_PATH) && defined(O_EXEC) /* FreeBSD */
|
||||
#define O_PATH O_EXEC
|
||||
#endif
|
||||
|
||||
#ifdef O_PATH
|
||||
#define HAVE_OPEN_PARENT_DIR_NOSYMLINKS
|
||||
const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd);
|
||||
#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
|
||||
int dfd, res; \
|
||||
const char *filename= my_open_parent_dir_nosymlinks(pathname, &dfd); \
|
||||
if (filename == NULL) return -1; \
|
||||
res= AT; \
|
||||
if (dfd >= 0) close(dfd); \
|
||||
return res;
|
||||
#elif defined(HAVE_REALPATH)
|
||||
#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
|
||||
char buf[PATH_MAX+1]; \
|
||||
if (realpath(pathname, buf) == NULL) return -1; \
|
||||
if (strcmp(pathname, buf)) { errno= ENOTDIR; return -1; } \
|
||||
return NOAT;
|
||||
#else
|
||||
#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
|
||||
return NOAT;
|
||||
#endif
|
||||
|
||||
#define CREATE_NOSYMLINK_FUNCTION(PROTO,AT,NOAT) \
|
||||
static int PROTO { NOSYMLINK_FUNCTION_BODY(AT,NOAT) }
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <sys/stat.h>
|
||||
/* my_winfile.c exports, should not be used outside mysys */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue