Wrap POSIX FD functions in libroot_build
This makes opening symlinks work universally in the build system tools. Two mechanisms have been implemented, both of which don't always work. The first is remapping via preprocessor macros. This fails where equally named methods are used (e.g. STL fstream::open()). The other is using hidden functions in the new libroot_build_function_remapper.a that is linked into everything that is linked against libroot_build.so. This one fails for functions that are defined inline in headers (Linux/glibc does that). Together they seem to cover our build system needs ATM.
This commit is contained in:
parent
0fbcad54be
commit
55bc371993
@ -773,7 +773,7 @@ if $(HOST_PLATFORM_BEOS_COMPATIBLE) {
|
||||
HOST_HAIKU_COMPATIBILITY_LIBS = libhaikucompat.a ;
|
||||
} else {
|
||||
HOST_LIBSTDC++ = stdc++ ;
|
||||
HOST_LIBROOT = libroot_build.so ;
|
||||
HOST_LIBROOT = libroot_build_function_remapper.a libroot_build.so ;
|
||||
HOST_STATIC_LIBROOT = libroot_build.a ;
|
||||
HOST_LIBBE = libbe_build.so ;
|
||||
if $(HOST_PLATFORM) = cygwin {
|
||||
|
@ -32,9 +32,12 @@ typedef unsigned long haiku_build_addr_t;
|
||||
#include <Errors.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -91,6 +94,90 @@ extern char* _haiku_build_strerror(int errnum);
|
||||
|
||||
#endif // BUILDING_HAIKU_ERROR_MAPPER
|
||||
|
||||
|
||||
// remap file descriptor functions
|
||||
int _haiku_build_fchmod(int fd, mode_t mode);
|
||||
int _haiku_build_fchmodat(int fd, const char* path, mode_t mode, int flag);
|
||||
int _haiku_build_fstat(int fd, struct stat* st);
|
||||
int _haiku_build_fstatat(int fd, const char* path, struct stat* st,
|
||||
int flag);
|
||||
int _haiku_build_mkdirat(int fd, const char* path, mode_t mode);
|
||||
int _haiku_build_mkfifoat(int fd, const char* path, mode_t mode);
|
||||
int _haiku_build_utimensat(int fd, const char* path,
|
||||
const struct timespec times[2], int flag);
|
||||
int _haiku_build_futimens(int fd, const struct timespec times[2]);
|
||||
int _haiku_build_faccessat(int fd, const char* path, int accessMode,
|
||||
int flag);
|
||||
int _haiku_build_fchdir(int fd);
|
||||
int _haiku_build_close(int fd);
|
||||
int _haiku_build_dup(int fd);
|
||||
int _haiku_build_dup2(int fd1, int fd2);
|
||||
int _haiku_build_linkat(int toFD, const char* toPath, int pathFD,
|
||||
const char* path, int flag);
|
||||
int _haiku_build_unlinkat(int fd, const char* path, int flag);
|
||||
ssize_t _haiku_build_readlinkat(int fd, const char* path, char* buffer,
|
||||
size_t bufferSize);
|
||||
int _haiku_build_symlinkat(const char* toPath, int fd,
|
||||
const char* symlinkPath);
|
||||
int _haiku_build_ftruncate(int fd, off_t newSize);
|
||||
int _haiku_build_fchown(int fd, uid_t owner, gid_t group);
|
||||
int _haiku_build_fchownat(int fd, const char* path, uid_t owner,
|
||||
gid_t group, int flag);
|
||||
int _haiku_build_mknodat(int fd, const char* name, mode_t mode, dev_t dev);
|
||||
int _haiku_build_creat(const char* path, mode_t mode);
|
||||
#ifndef _HAIKU_BUILD_DONT_REMAP_FD_FUNCTIONS
|
||||
int _haiku_build_open(const char* path, int openMode, ...);
|
||||
int _haiku_build_openat(int fd, const char* path, int openMode, ...);
|
||||
int _haiku_build_fcntl(int fd, int op, ...);
|
||||
#else
|
||||
int _haiku_build_open(const char* path, int openMode, mode_t permissions);
|
||||
int _haiku_build_openat(int fd, const char* path, int openMode,
|
||||
mode_t permissions);
|
||||
int _haiku_build_fcntl(int fd, int op, int argument);
|
||||
#endif
|
||||
int _haiku_build_renameat(int fromFD, const char* from, int toFD,
|
||||
const char* to);
|
||||
|
||||
#ifndef _HAIKU_BUILD_DONT_REMAP_FD_FUNCTIONS
|
||||
# define fchmod(fd, mode) _haiku_build_fchmod(fd, mode)
|
||||
# define fchmodat(fd, path, mode, flag) \
|
||||
_haiku_build_fchmodat(fd, path, mode, flag)
|
||||
# define fstat(fd, st) _haiku_build_fstat(fd, st)
|
||||
# define fstatat(fd, path, st, flag) _haiku_build_fstatat(fd, path, st, flag)
|
||||
# define mkdirat(fd, path, mode) _haiku_build_mkdirat(fd, path, mode)
|
||||
# define mkfifoat(fd, path, mode) _haiku_build_mkfifoat(fd, path, mode)
|
||||
# define utimensat(fd, path, times, flag) \
|
||||
_haiku_build_utimensat(fd, path, times, flag)
|
||||
# define futimens(fd, times) _haiku_build_futimens(fd, times)
|
||||
# define faccessat(fd, path, accessMode, flag) \
|
||||
_haiku_build_faccessat(fd, path, accessMode, flag)
|
||||
# define fchdir(fd) _haiku_build_fchdir(fd)
|
||||
# define close(fd) _haiku_build_close(fd)
|
||||
# define dup(fd) _haiku_build_dup(fd)
|
||||
# define dup2(fd1, fd2) _haiku_build_dup2(fd1, fd2)
|
||||
# define linkat(toFD, toPath, pathFD, path, flag) \
|
||||
_haiku_build_linkat(toFD, toPath, pathFD, path, flag)
|
||||
# define unlinkat(fd, path, flag) _haiku_build_unlinkat(fd, path, flag)
|
||||
# define readlinkat(fd, path, buffer, bufferSize) \
|
||||
_haiku_build_readlinkat(fd, path, buffer, bufferSize)
|
||||
# define symlinkat(toPath, fd, symlinkPath) \
|
||||
_haiku_build_symlinkat(toPath, fd, symlinkPath)
|
||||
# define ftruncate(fd, newSize) _haiku_build_ftruncate(fd, newSize)
|
||||
# define fchown(fd, owner, group) _haiku_build_fchown(fd, owner, group)
|
||||
# define fchownat(fd, path, owner, group, flag) \
|
||||
_haiku_build_fchownat(fd, path, owner, group, flag)
|
||||
# define mknodat(fd, name, mode, dev) \
|
||||
_haiku_build_mknodat(fd, name, mode, dev)
|
||||
# define creat(path, mode) _haiku_build_creat(path, mode)
|
||||
# define open(path, openMode...) _haiku_build_open(path, openMode)
|
||||
# define openat(fd, path, openMode...) \
|
||||
_haiku_build_openat(fd, path, openMode)
|
||||
# define fcntl(fd, op...) _haiku_build_fcntl(fd, op)
|
||||
# define renameat(fromFD, from, toFD, to) \
|
||||
_haiku_build_renameat(fromFD, from, toFD, to)
|
||||
#endif // _HAIKU_BUILD_DONT_REMAP_FD_FUNCTIONS
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@ UsePrivateBuildHeaders kernel libroot ;
|
||||
{
|
||||
local defines = [ FDefines
|
||||
HAIKU_BUILD_ATTRIBUTES_DIR="\\\"$(HAIKU_BUILD_ATTRIBUTES_DIR)\\\""
|
||||
_HAIKU_BUILD_DONT_REMAP_FD_FUNCTIONS=1
|
||||
] ;
|
||||
SubDirCcFlags $(defines) ;
|
||||
SubDirC++Flags $(defines) ;
|
||||
@ -79,9 +80,16 @@ BuildPlatformSharedLibrary libroot_build.so :
|
||||
$(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
|
||||
;
|
||||
|
||||
BuildPlatformStaticLibrary libroot_build.a :
|
||||
:
|
||||
[ FGristFiles $(librootSources:S=$(SUFOBJ)) ]
|
||||
# TODO: This doesn't work with the function remapping.
|
||||
#BuildPlatformStaticLibrary libroot_build.a :
|
||||
# :
|
||||
# [ FGristFiles $(librootSources:S=$(SUFOBJ)) ]
|
||||
#;
|
||||
|
||||
USES_BE_API on [ FGristFiles function_remapper$(SUFOBJ) ] = true ;
|
||||
|
||||
BuildPlatformStaticLibraryPIC libroot_build_function_remapper.a :
|
||||
function_remapper.cpp
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles driver_settings.cpp ]
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
@ -26,6 +27,7 @@
|
||||
|
||||
#include "fs_descriptors.h"
|
||||
#include "NodeRef.h"
|
||||
#include "remapped_functions.h"
|
||||
|
||||
#if defined(HAIKU_HOST_PLATFORM_FREEBSD)
|
||||
# include "fs_freebsd.h"
|
||||
@ -48,6 +50,16 @@ using namespace BPrivate;
|
||||
# define haiku_host_platform_writev writev
|
||||
#endif
|
||||
|
||||
#define RETURN_AND_SET_ERRNO(err) \
|
||||
do { \
|
||||
__typeof(err) __result = (err); \
|
||||
if (__result < 0) { \
|
||||
errno = __result; \
|
||||
return -1; \
|
||||
} \
|
||||
return __result; \
|
||||
} while (0)
|
||||
|
||||
|
||||
static status_t get_path(dev_t device, ino_t node, const char *name,
|
||||
string &path);
|
||||
@ -1033,3 +1045,367 @@ writev_pos(int fd, off_t pos, const struct iovec *vec, size_t count)
|
||||
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_fchmod(int fd, mode_t mode)
|
||||
{
|
||||
return _haiku_build_fchmodat(fd, NULL, mode, AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_fchmodat(int fd, const char* path, mode_t mode, int flag)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return fchmodat(fd, path, mode, flag);
|
||||
|
||||
struct stat st;
|
||||
st.st_mode = mode;
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_write_stat(fd, path,
|
||||
(flag & AT_SYMLINK_NOFOLLOW) == 0, &st, sizeof(st), B_STAT_MODE));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_fstat(int fd, struct stat* st)
|
||||
{
|
||||
return _haiku_build_fstatat(fd, NULL, st, AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_fstatat(int fd, const char* path, struct stat* st, int flag)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return fstatat(fd, path, st, flag);
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_read_stat(fd, path,
|
||||
(flag & AT_SYMLINK_NOFOLLOW) == 0, st, sizeof(*st)));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_mkdirat(int fd, const char* path, mode_t mode)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return mkdirat(fd, path, mode);
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_create_dir(fd, path, mode));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_mkfifoat(int fd, const char* path, mode_t mode)
|
||||
{
|
||||
return mkfifoat(fd, path, mode);
|
||||
|
||||
// TODO: Handle non-system FDs.
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_utimensat(int fd, const char* path, const struct timespec times[2],
|
||||
int flag)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return utimensat(fd, path, times, flag);
|
||||
|
||||
struct stat stat;
|
||||
status_t status;
|
||||
uint32 mask = 0;
|
||||
|
||||
// Init the stat time fields to the current time, if at least one time is
|
||||
// supposed to be set to it.
|
||||
if (times == NULL || times[0].tv_nsec == UTIME_NOW
|
||||
|| times[1].tv_nsec == UTIME_NOW) {
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now.tv_sec;
|
||||
stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = now.tv_usec * 1000;
|
||||
}
|
||||
|
||||
if (times != NULL) {
|
||||
// access time
|
||||
if (times[0].tv_nsec != UTIME_OMIT) {
|
||||
mask |= B_STAT_ACCESS_TIME;
|
||||
|
||||
if (times[0].tv_nsec != UTIME_NOW) {
|
||||
if (times[0].tv_nsec < 0 || times[0].tv_nsec > 999999999)
|
||||
RETURN_AND_SET_ERRNO(EINVAL);
|
||||
}
|
||||
|
||||
stat.st_atim = times[0];
|
||||
}
|
||||
|
||||
// modified time
|
||||
if (times[1].tv_nsec != UTIME_OMIT) {
|
||||
mask |= B_STAT_MODIFICATION_TIME;
|
||||
|
||||
if (times[1].tv_nsec != UTIME_NOW) {
|
||||
if (times[1].tv_nsec < 0 || times[1].tv_nsec > 999999999)
|
||||
RETURN_AND_SET_ERRNO(EINVAL);
|
||||
}
|
||||
|
||||
stat.st_mtim = times[1];
|
||||
}
|
||||
} else
|
||||
mask |= B_STAT_ACCESS_TIME | B_STAT_MODIFICATION_TIME;
|
||||
|
||||
// set the times -- as per spec we even need to do this, if both have
|
||||
// UTIME_OMIT set
|
||||
status = _kern_write_stat(fd, path, (flag & AT_SYMLINK_NOFOLLOW) == 0,
|
||||
&stat, sizeof(struct stat), mask);
|
||||
|
||||
RETURN_AND_SET_ERRNO(status);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_futimens(int fd, const struct timespec times[2])
|
||||
{
|
||||
return _haiku_build_utimensat(fd, NULL, times, AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_faccessat(int fd, const char* path, int accessMode, int flag)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return faccessat(fd, path, accessMode, flag);
|
||||
|
||||
// stat the file
|
||||
struct stat st;
|
||||
status_t error = _kern_read_stat(fd, path, false, &st, sizeof(st));
|
||||
if (error != B_OK)
|
||||
RETURN_AND_SET_ERRNO(error);
|
||||
|
||||
// get the current user
|
||||
uid_t uid = (flag & AT_EACCESS) != 0 ? geteuid() : getuid();
|
||||
|
||||
int fileMode = 0;
|
||||
|
||||
if (uid == 0) {
|
||||
// user is root
|
||||
// root has always read/write permission, but at least one of the
|
||||
// X bits must be set for execute permission
|
||||
fileMode = R_OK | W_OK;
|
||||
if ((st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)
|
||||
fileMode |= X_OK;
|
||||
} else if (st.st_uid == uid) {
|
||||
// user is node owner
|
||||
if ((st.st_mode & S_IRUSR) != 0)
|
||||
fileMode |= R_OK;
|
||||
if ((st.st_mode & S_IWUSR) != 0)
|
||||
fileMode |= W_OK;
|
||||
if ((st.st_mode & S_IXUSR) != 0)
|
||||
fileMode |= X_OK;
|
||||
} else if (st.st_gid == ((flag & AT_EACCESS) != 0 ? getegid() : getgid())) {
|
||||
// user is in owning group
|
||||
if ((st.st_mode & S_IRGRP) != 0)
|
||||
fileMode |= R_OK;
|
||||
if ((st.st_mode & S_IWGRP) != 0)
|
||||
fileMode |= W_OK;
|
||||
if ((st.st_mode & S_IXGRP) != 0)
|
||||
fileMode |= X_OK;
|
||||
} else {
|
||||
// user is one of the others
|
||||
if ((st.st_mode & S_IROTH) != 0)
|
||||
fileMode |= R_OK;
|
||||
if ((st.st_mode & S_IWOTH) != 0)
|
||||
fileMode |= W_OK;
|
||||
if ((st.st_mode & S_IXOTH) != 0)
|
||||
fileMode |= X_OK;
|
||||
}
|
||||
|
||||
if ((accessMode & ~fileMode) != 0)
|
||||
RETURN_AND_SET_ERRNO(EACCES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_fchdir(int fd)
|
||||
{
|
||||
if (is_unknown_or_system_descriptor(fd))
|
||||
return fchdir(fd);
|
||||
|
||||
RETURN_AND_SET_ERRNO(B_FILE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_close(int fd)
|
||||
{
|
||||
if (get_descriptor(fd) == NULL)
|
||||
return close(fd);
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_close(fd));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_dup(int fd)
|
||||
{
|
||||
if (get_descriptor(fd) == NULL)
|
||||
return close(fd);
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_dup(fd));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_dup2(int fd1, int fd2)
|
||||
{
|
||||
if (is_unknown_or_system_descriptor(fd1))
|
||||
return dup2(fd1, fd2);
|
||||
|
||||
// TODO: Handle non-system FDs.
|
||||
RETURN_AND_SET_ERRNO(B_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_linkat(int toFD, const char* toPath, int pathFD, const char* path,
|
||||
int flag)
|
||||
{
|
||||
return linkat(toFD, toPath, pathFD, path, flag);
|
||||
|
||||
// TODO: Handle non-system FDs.
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_unlinkat(int fd, const char* path, int flag)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return unlinkat(fd, path, flag);
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_unlink(fd, path));
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
_haiku_build_readlinkat(int fd, const char* path, char* buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return readlinkat(fd, path, buffer, bufferSize);
|
||||
|
||||
status_t error = _kern_read_link(fd, path, buffer, &bufferSize);
|
||||
if (error != B_OK)
|
||||
RETURN_AND_SET_ERRNO(error);
|
||||
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_symlinkat(const char* toPath, int fd, const char* symlinkPath)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return symlinkat(toPath, fd, symlinkPath);
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_create_symlink(fd, symlinkPath, toPath,
|
||||
S_IRWXU | S_IRWXG | S_IRWXO));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_ftruncate(int fd, off_t newSize)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return ftruncate(fd, newSize);
|
||||
|
||||
struct stat st;
|
||||
st.st_size = newSize;
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_write_stat(fd, NULL, false, &st, sizeof(st),
|
||||
B_STAT_SIZE));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_fchown(int fd, uid_t owner, gid_t group)
|
||||
{
|
||||
return _haiku_build_fchownat(fd, NULL, owner, group, AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_fchownat(int fd, const char* path, uid_t owner, gid_t group,
|
||||
int flag)
|
||||
{
|
||||
if (fd >= 0 && fd != AT_FDCWD && get_descriptor(fd) == NULL)
|
||||
return fchownat(fd, path, owner, group, flag);
|
||||
|
||||
struct stat st;
|
||||
st.st_uid = owner;
|
||||
st.st_gid = group;
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_write_stat(fd, path,
|
||||
(flag & AT_SYMLINK_NOFOLLOW) == 0, &st, sizeof(st),
|
||||
B_STAT_UID | B_STAT_GID));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_mknodat(int fd, const char* name, mode_t mode, dev_t dev)
|
||||
{
|
||||
return mknodat(fd, name, mode, dev);
|
||||
|
||||
// TODO: Handle non-system FDs.
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_creat(const char* path, mode_t mode)
|
||||
{
|
||||
return _haiku_build_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_open(const char* path, int openMode, mode_t permissions)
|
||||
{
|
||||
return _haiku_build_openat(AT_FDCWD, path, openMode, permissions);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_openat(int fd, const char* path, int openMode, mode_t permissions)
|
||||
{
|
||||
// adapt the permissions as required by POSIX
|
||||
mode_t mask = umask(0);
|
||||
umask(mask);
|
||||
permissions &= ~mask;
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_open(fd, path, openMode, permissions));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_fcntl(int fd, int op, int argument)
|
||||
{
|
||||
if (is_unknown_or_system_descriptor(fd))
|
||||
return fcntl(fd, op, argument);
|
||||
|
||||
RETURN_AND_SET_ERRNO(B_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_haiku_build_renameat(int fromFD, const char* from, int toFD, const char* to)
|
||||
{
|
||||
if ((fromFD >= 0 && fromFD != AT_FDCWD && get_descriptor(fromFD) == NULL)
|
||||
|| (toFD >= 0 && toFD != AT_FDCWD && get_descriptor(toFD) == NULL)) {
|
||||
return renameat(fromFD, from, toFD, to);
|
||||
}
|
||||
|
||||
RETURN_AND_SET_ERRNO(_kern_rename(fromFD, from, toFD, to));
|
||||
}
|
||||
|
277
src/build/libroot/function_remapper.cpp
Normal file
277
src/build/libroot/function_remapper.cpp
Normal file
@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "remapped_functions.h"
|
||||
|
||||
|
||||
#if __GNUC__ >= 4
|
||||
# define HIDDEN_FUNCTION(function) do {} while (0)
|
||||
# define HIDDEN_FUNCTION_ATTRIBUTE __attribute__((visibility("hidden")))
|
||||
#else
|
||||
# define HIDDEN_FUNCTION(function) asm volatile(".hidden " #function)
|
||||
# define HIDDEN_FUNCTION_ATTRIBUTE
|
||||
#endif
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
fchmod(int fd, mode_t mode)
|
||||
{
|
||||
HIDDEN_FUNCTION(fchmod);
|
||||
|
||||
return _haiku_build_fchmod(fd, mode);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
fchmodat(int fd, const char* path, mode_t mode, int flag)
|
||||
{
|
||||
HIDDEN_FUNCTION(fchmodat);
|
||||
|
||||
return _haiku_build_fchmodat(fd, path, mode, flag);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
fstat(int fd, struct stat* st)
|
||||
{
|
||||
HIDDEN_FUNCTION(fstat);
|
||||
|
||||
return _haiku_build_fstat(fd, st);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
fstatat(int fd, const char* path, struct stat* st, int flag)
|
||||
{
|
||||
HIDDEN_FUNCTION(fstatat);
|
||||
|
||||
return _haiku_build_fstatat(fd, path, st, flag);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
mkdirat(int fd, const char* path, mode_t mode)
|
||||
{
|
||||
HIDDEN_FUNCTION(mkdirat);
|
||||
|
||||
return _haiku_build_mkdirat(fd, path, mode);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
mkfifoat(int fd, const char* path, mode_t mode)
|
||||
{
|
||||
HIDDEN_FUNCTION(mkfifoat);
|
||||
|
||||
return _haiku_build_mkfifoat(fd, path, mode);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
utimensat(int fd, const char* path, const struct timespec times[2], int flag)
|
||||
{
|
||||
HIDDEN_FUNCTION(utimensat);
|
||||
|
||||
return _haiku_build_utimensat(fd, path, times, flag);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
futimens(int fd, const struct timespec times[2])
|
||||
{
|
||||
HIDDEN_FUNCTION(futimens);
|
||||
|
||||
return _haiku_build_futimens(fd, times);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
faccessat(int fd, const char* path, int accessMode, int flag)
|
||||
{
|
||||
HIDDEN_FUNCTION(faccessat);
|
||||
|
||||
return _haiku_build_faccessat(fd, path, accessMode, flag);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
fchdir(int fd)
|
||||
{
|
||||
HIDDEN_FUNCTION(fchdir);
|
||||
|
||||
return _haiku_build_fchdir(fd);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
close(int fd)
|
||||
{
|
||||
HIDDEN_FUNCTION(close);
|
||||
|
||||
return _haiku_build_close(fd);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
dup(int fd)
|
||||
{
|
||||
HIDDEN_FUNCTION(dup);
|
||||
|
||||
return _haiku_build_dup(fd);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
dup2(int fd1, int fd2)
|
||||
{
|
||||
HIDDEN_FUNCTION(dup2);
|
||||
|
||||
return _haiku_build_dup2(fd1, fd2);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
linkat(int toFD, const char* toPath, int pathFD, const char* path, int flag)
|
||||
{
|
||||
HIDDEN_FUNCTION(linkat);
|
||||
|
||||
return _haiku_build_linkat(toFD, toPath, pathFD, path, flag);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
unlinkat(int fd, const char* path, int flag)
|
||||
{
|
||||
HIDDEN_FUNCTION(unlinkat);
|
||||
|
||||
return _haiku_build_unlinkat(fd, path, flag);
|
||||
}
|
||||
|
||||
|
||||
extern "C" ssize_t HIDDEN_FUNCTION_ATTRIBUTE
|
||||
readlinkat(int fd, const char* path, char* buffer, size_t bufferSize)
|
||||
{
|
||||
HIDDEN_FUNCTION(readlinkat);
|
||||
|
||||
return _haiku_build_readlinkat(fd, path, buffer, bufferSize);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
symlinkat(const char* toPath, int fd, const char* symlinkPath)
|
||||
{
|
||||
HIDDEN_FUNCTION(symlinkat);
|
||||
|
||||
return _haiku_build_symlinkat(toPath, fd, symlinkPath);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
ftruncate(int fd, off_t newSize)
|
||||
{
|
||||
HIDDEN_FUNCTION(ftruncate);
|
||||
|
||||
return _haiku_build_ftruncate(fd, newSize);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
fchown(int fd, uid_t owner, gid_t group)
|
||||
{
|
||||
HIDDEN_FUNCTION(fchown);
|
||||
|
||||
return _haiku_build_fchown(fd, owner, group);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
fchownat(int fd, const char* path, uid_t owner, gid_t group, int flag)
|
||||
{
|
||||
HIDDEN_FUNCTION(fchownat);
|
||||
|
||||
return _haiku_build_fchownat(fd, path, owner, group, flag);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
mknodat(int fd, const char* name, mode_t mode, dev_t dev)
|
||||
{
|
||||
HIDDEN_FUNCTION(mknodat);
|
||||
|
||||
return _haiku_build_mknodat(fd, name, mode, dev);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
creat(const char* path, mode_t mode)
|
||||
{
|
||||
HIDDEN_FUNCTION(RESOLVE(creat));
|
||||
|
||||
return _haiku_build_creat(path, mode);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
open(const char* path, int openMode, ...)
|
||||
{
|
||||
HIDDEN_FUNCTION(open);
|
||||
|
||||
mode_t permissions = 0;
|
||||
if ((openMode & O_CREAT) != 0) {
|
||||
va_list args;
|
||||
va_start(args, openMode);
|
||||
mode_t mask = umask(0);
|
||||
umask(mask);
|
||||
permissions = va_arg(args, int);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
return _haiku_build_open(path, openMode, permissions);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
openat(int fd, const char* path, int openMode, ...)
|
||||
{
|
||||
HIDDEN_FUNCTION(openat);
|
||||
|
||||
mode_t permissions = 0;
|
||||
if ((openMode & O_CREAT) != 0) {
|
||||
va_list args;
|
||||
va_start(args, openMode);
|
||||
mode_t mask = umask(0);
|
||||
umask(mask);
|
||||
permissions = va_arg(args, int);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
return _haiku_build_openat(fd, path, openMode, permissions);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
fcntl(int fd, int op, ...)
|
||||
{
|
||||
HIDDEN_FUNCTION(fcntl);
|
||||
|
||||
va_list args;
|
||||
va_start(args, op);
|
||||
int argument = va_arg(args, int);
|
||||
va_end(args);
|
||||
|
||||
return _haiku_build_fcntl(fd, op, argument);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int HIDDEN_FUNCTION_ATTRIBUTE
|
||||
renameat(int fromFD, const char* from, int toFD, const char* to)
|
||||
{
|
||||
HIDDEN_FUNCTION(renameat);
|
||||
|
||||
return _haiku_build_renameat(fromFD, from, toFD, to);
|
||||
}
|
62
src/build/libroot/remapped_functions.h
Normal file
62
src/build/libroot/remapped_functions.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef REMAPPED_FUNCTIONS_H
|
||||
#define REMAPPED_FUNCTIONS_H
|
||||
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int _haiku_build_fchmod(int fd, mode_t mode);
|
||||
int _haiku_build_fchmodat(int fd, const char* path, mode_t mode, int flag);
|
||||
int _haiku_build_fstat(int fd, struct stat* st);
|
||||
int _haiku_build_fstatat(int fd, const char* path, struct stat* st,
|
||||
int flag);
|
||||
int _haiku_build_mkdirat(int fd, const char* path, mode_t mode);
|
||||
int _haiku_build_mkfifoat(int fd, const char* path, mode_t mode);
|
||||
int _haiku_build_utimensat(int fd, const char* path,
|
||||
const struct timespec times[2], int flag);
|
||||
int _haiku_build_futimens(int fd, const struct timespec times[2]);
|
||||
int _haiku_build_faccessat(int fd, const char* path, int accessMode,
|
||||
int flag);
|
||||
int _haiku_build_fchdir(int fd);
|
||||
int _haiku_build_close(int fd);
|
||||
int _haiku_build_dup(int fd);
|
||||
int _haiku_build_dup2(int fd1, int fd2);
|
||||
int _haiku_build_linkat(int toFD, const char* toPath, int pathFD,
|
||||
const char* path, int flag);
|
||||
int _haiku_build_unlinkat(int fd, const char* path, int flag);
|
||||
ssize_t _haiku_build_readlinkat(int fd, const char* path, char* buffer,
|
||||
size_t bufferSize);
|
||||
int _haiku_build_symlinkat(const char* toPath, int fd,
|
||||
const char* symlinkPath);
|
||||
int _haiku_build_ftruncate(int fd, off_t newSize);
|
||||
int _haiku_build_fchown(int fd, uid_t owner, gid_t group);
|
||||
int _haiku_build_fchownat(int fd, const char* path, uid_t owner,
|
||||
gid_t group, int flag);
|
||||
int _haiku_build_mknodat(int fd, const char* name, mode_t mode, dev_t dev);
|
||||
int _haiku_build_creat(const char* path, mode_t mode);
|
||||
int _haiku_build_open(const char* path, int openMode, mode_t permissions);
|
||||
int _haiku_build_openat(int fd, const char* path, int openMode,
|
||||
mode_t permissions);
|
||||
int _haiku_build_fcntl(int fd, int op, int argument);
|
||||
int _haiku_build_renameat(int fromFD, const char* from, int toFD,
|
||||
const char* to);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
#endif // REMAPPED_FUNCTIONS_H
|
Loading…
Reference in New Issue
Block a user