1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

lib/replace: add renameat2() replacement

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15693

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Stefan Metzmacher 2024-08-07 13:01:48 +02:00
parent 7baeeece2d
commit f6550e804e
3 changed files with 90 additions and 1 deletions

View File

@ -1171,3 +1171,63 @@ long rep_openat2(int dirfd, const char *pathname,
#endif
}
#endif /* !HAVE_OPENAT2 */
#ifndef HAVE_RENAMEAT2
/* fallback to wellknown __NR_renameat2 values */
#ifndef __NR_renameat2
# if defined(LINUX) && defined(HAVE_SYS_SYSCALL_H)
# if defined(__i386__)
# define __NR_renameat2 353
# elif defined(__x86_64__) && defined(__LP64__)
# define __NR_renameat2 316 /* 316 0x13C */
# elif defined(__x86_64__) && defined(__ILP32__)
# define __NR_renameat2 1073742140 /* 1073742140 0x4000013C */
# elif defined(__aarch64__)
# define __NR_renameat2 276
# elif defined(__arm__)
# define __NR_renameat2 382
# elif defined(__sparc__)
# define __NR_renameat2 345
# endif
# endif /* defined(LINUX) && defined(HAVE_SYS_SYSCALL_H) */
#endif /* !__NR_renameat2 */
#ifdef DISABLE_OPATH
/*
* systems without O_PATH also don't have renameat2,
* so make sure we at a realistic combination.
*/
#undef __NR_renameat2
#endif /* DISABLE_OPATH */
int rep_renameat2(int __oldfd, const char *__old, int __newfd,
const char *__new, unsigned int __flags)
{
if (__flags != 0) {
#ifdef __NR_renameat2
int ret;
ret = syscall(__NR_renameat2,
__oldfd,
__old,
__newfd,
__new,
__flags);
if (ret != -1 || errno != ENOSYS) {
/*
* if it's ENOSYS, we fallback
* to EINVAL below, otherwise
* we return what the kernel
* did.
*/
return ret;
}
#endif
errno = EINVAL;
return -1;
}
return renameat(__oldfd, __old, __newfd, __new);
}
#endif /* ! HAVE_RENAMEAT2 */

View File

@ -278,4 +278,33 @@ long rep_openat2(int dirfd, const char *pathname,
rep_openat2(dirfd, pathname, how, size)
#endif /* !HAVE_OPENAT2 */
#ifdef DISABLE_OPATH
/*
* Without O_PATH, the kernel
* most likely doesn't have renameat2() too
* and we should test the fallback code
*/
#undef HAVE_RENAMEAT2
#endif
#ifndef HAVE_RENAMEAT2
#ifndef RENAME_NOREPLACE
# define RENAME_NOREPLACE (1 << 0)
#endif
#ifndef RENAME_EXCHANGE
# define RENAME_EXCHANGE (1 << 1)
#endif
#ifndef RENAME_WHITEOUT
# define RENAME_WHITEOUT (1 << 2)
#endif
int rep_renameat2(int __oldfd, const char *__old, int __newfd,
const char *__new, unsigned int __flags);
#define renameat2(__oldfd, __old, __newfd, __new, __flags) \
rep_renameat2(__oldfd, __old, __newfd, __new, __flags)
#endif /* !HAVE_RENAMEAT2 */
#endif

View File

@ -422,7 +422,7 @@ def configure(conf):
conf.CHECK_FUNCS('link readlink symlink realpath snprintf vsnprintf')
conf.CHECK_FUNCS('asprintf vasprintf setenv unsetenv strnlen strtoull __strtoull')
conf.CHECK_FUNCS('strtouq strtoll __strtoll strtoq memalign posix_memalign')
conf.CHECK_FUNCS('fmemopen')
conf.CHECK_FUNCS('fmemopen renameat2')
if conf.CONFIG_SET('HAVE_MEMALIGN'):
conf.CHECK_DECLS('memalign', headers='malloc.h')