hrev43834 adds 1 changeset to branch 'master' old head: 89a2b4812c2efb6d269be70a970054a53095b4dd new head: 81b45e484a2f71f1235d48ab743c20357f070593 ---------------------------------------------------------------------------- 81b45e4: Fix build on Mac OS X 10.6 gcc2 and gcc4 and 10.7 gcc4 by adding some Mac OS X specific files that implement missing *at() functions. Mac OS X 10.7 generates a gcc2 cross-compiler that fails when assigning NULL to a static method pointer so is still broken. Added a weak attribute in driver_settings.cpp. Move futimesat() from fs.cpp to fs_darwin.cpp since it is implimented on FreeBSD. Implemented eaccess(), for the AT_EACCESS flag of faccessat() Fix configure script to correctly detect case-sensitive file system [ John Scipione <jscipione@xxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev43834 Commit: 81b45e484a2f71f1235d48ab743c20357f070593 URL: http://cgit.haiku-os.org/haiku/commit/?id=81b45e4 Author: John Scipione <jscipione@xxxxxxxxx> Date: Thu Mar 1 00:42:59 2012 UTC ---------------------------------------------------------------------------- 8 files changed, 869 insertions(+), 126 deletions(-) configure | 2 +- headers/build/host/darwin/sys/stat.h | 31 ++ src/build/libroot/Jamfile | 4 + src/build/libroot/fs.cpp | 132 +++++ src/build/libroot/fs_darwin.cpp | 659 +++++++++++++++++++++++++ src/build/libroot/fs_darwin.h | 41 ++ src/build/libroot/fs_freebsd.cpp | 124 ----- src/system/libroot/os/driver_settings.cpp | 2 +- ---------------------------------------------------------------------------- diff --git a/configure b/configure index 1edda47..9d6ca5a 100755 --- a/configure +++ b/configure @@ -473,7 +473,7 @@ done # check for case-sensitive filesystem if on darwin if [ $HOST_PLATFORM = "darwin" ]; then - diskutil info $(pwd) | grep -i "case-sensitive" > /dev/null + diskutil info $(pwd)/.. | grep -i "case-sensitive" > /dev/null if [ $? != 0 ]; then echo "You need a case-sensitive file-system to build Haiku." echo "Please see the following guide on how to set one up:" diff --git a/headers/build/host/darwin/sys/stat.h b/headers/build/host/darwin/sys/stat.h new file mode 100644 index 0000000..1a43b14 --- /dev/null +++ b/headers/build/host/darwin/sys/stat.h @@ -0,0 +1,31 @@ +#ifndef _HAIKU_BUILD_COMPATIBILITY_DARWIN_SYS_STAT +#define _HAIKU_BUILD_COMPATIBILITY_DARWIN_SYS_STAT + +#include_next <sys/stat.h> + +#include <sys/cdefs.h> + + +#ifndef UTIME_NOW +# define UTIME_NOW (-1) +# define UTIME_OMIT (-2) + + __BEGIN_DECLS + + /* assume that futimens() and utimensat() aren't available */ + int futimens(int fd, const struct timespec times[2]); + int utimensat(int fd, const char* path, const struct timespec times[2], + int flag); + + __END_DECLS + +# ifndef _HAIKU_BUILD_NO_FUTIMENS +# define _HAIKU_BUILD_NO_FUTIMENS 1 +# endif +# ifndef _HAIKU_BUILD_NO_UTIMENSAT +# define _HAIKU_BUILD_NO_UTIMENSAT 1 +# endif +#endif + + +#endif /* _HAIKU_BUILD_COMPATIBILITY_DARWIN_SYS_STAT */ \ No newline at end of file diff --git a/src/build/libroot/Jamfile b/src/build/libroot/Jamfile index 0104f25..f8cb92d 100644 --- a/src/build/libroot/Jamfile +++ b/src/build/libroot/Jamfile @@ -50,6 +50,10 @@ if $(HOST_PLATFORM) = freebsd { hostPlatformSources = fs_freebsd.cpp ; } +if $(HOST_PLATFORM) = darwin { + hostPlatformSources = fs_darwin.cpp ; +} + local librootSources = atomic.cpp byteorder.cpp diff --git a/src/build/libroot/fs.cpp b/src/build/libroot/fs.cpp index 5de5bfa..13a0fdd 100644 --- a/src/build/libroot/fs.cpp +++ b/src/build/libroot/fs.cpp @@ -31,6 +31,8 @@ #if defined(HAIKU_HOST_PLATFORM_FREEBSD) # include "fs_freebsd.h" +#elif defined(HAIKU_HOST_PLATFORM_DARWIN) +# include "fs_darwin.h" #endif @@ -45,6 +47,13 @@ using namespace BPrivate; # define haiku_host_platform_writev haiku_freebsd_writev # define HAIKU_HOST_STAT_ATIM(x) ((x).st_atimespec) # define HAIKU_HOST_STAT_MTIM(x) ((x).st_mtimespec) +#elif defined(HAIKU_HOST_PLATFORM_DARWIN) +# define haiku_host_platform_read read +# define haiku_host_platform_write write +# define haiku_host_platform_readv readv +# define haiku_host_platform_writev writev +# define HAIKU_HOST_STAT_ATIM(x) ((x).st_atimespec) +# define HAIKU_HOST_STAT_MTIM(x) ((x).st_mtimespec) #else # define haiku_host_platform_read read # define haiku_host_platform_write write @@ -65,6 +74,129 @@ using namespace BPrivate; } while (0) +#if defined(_HAIKU_BUILD_NO_FUTIMENS) || defined(_HAIKU_BUILD_NO_FUTIMENS) + +template<typename File> +static int +utimes_helper(File& file, const struct timespec times[2]) +{ + if (times == NULL) + return file.SetTimes(NULL); + + timeval timeBuffer[2]; + timeBuffer[0].tv_sec = times[0].tv_sec; + timeBuffer[0].tv_usec = times[0].tv_nsec / 1000; + timeBuffer[1].tv_sec = times[1].tv_sec; + timeBuffer[1].tv_usec = times[1].tv_nsec / 1000; + + if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) { + struct stat st; + if (file.GetStat(st) != 0) + return -1; + + if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) + return 0; + + if (times[0].tv_nsec == UTIME_OMIT) { + timeBuffer[0].tv_sec = st.st_atimespec.tv_sec; + timeBuffer[0].tv_usec = st.st_atimespec.tv_nsec / 1000; + } + + if (times[1].tv_nsec == UTIME_OMIT) { + timeBuffer[1].tv_sec = st.st_mtimespec.tv_sec; + timeBuffer[1].tv_usec = st.st_mtimespec.tv_nsec / 1000; + } + } + + if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) { + timeval now; + gettimeofday(&now, NULL); + + if (times[0].tv_nsec == UTIME_NOW) + timeBuffer[0] = now; + + if (times[1].tv_nsec == UTIME_NOW) + timeBuffer[1] = now; + } + + return file.SetTimes(timeBuffer); +} + +#endif // _HAIKU_BUILD_NO_FUTIMENS || _HAIKU_BUILD_NO_FUTIMENS + + +#ifdef _HAIKU_BUILD_NO_FUTIMENS + +struct FDFile { + FDFile(int fd) + : + fFD(fd) + { + } + + int GetStat(struct stat& _st) + { + return fstat(fFD, &_st); + } + + int SetTimes(const timeval times[2]) + { + return futimes(fFD, times); + } + +private: + int fFD; +}; + + +int +futimens(int fd, const struct timespec times[2]) +{ + FDFile file(fd); + return utimes_helper(file, times); +} + +#endif // _HAIKU_BUILD_NO_FUTIMENS + +#ifdef _HAIKU_BUILD_NO_UTIMENSAT + +struct FDPathFile { + FDPathFile(int fd, const char* path, int flag) + : + fFD(fd), + fPath(path), + fFlag(flag) + { + } + + int GetStat(struct stat& _st) + { + return fstatat(fFD, fPath, &_st, fFlag); + } + + int SetTimes(const timeval times[2]) + { + // TODO: fFlag (AT_SYMLINK_NOFOLLOW) is not supported here! + return futimesat(fFD, fPath, times); + } + +private: + int fFD; + const char* fPath; + int fFlag; +}; + + +int +utimensat(int fd, const char* path, const struct timespec times[2], int flag) +{ + FDPathFile file(fd, path, flag); + return utimes_helper(file, times); +} + +#endif // _HAIKU_BUILD_NO_UTIMENSAT + + static status_t get_path(dev_t device, ino_t node, const char *name, string &path); diff --git a/src/build/libroot/fs_darwin.cpp b/src/build/libroot/fs_darwin.cpp new file mode 100644 index 0000000..23f45e2 --- /dev/null +++ b/src/build/libroot/fs_darwin.cpp @@ -0,0 +1,659 @@ +/* + * Copyright 2011, John Scipione, jscipione@xxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + +#include "fs_darwin.h" + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <unistd.h> + + +int get_path(int fd, const char* path, char** fullPath); +int eaccess(const char* path, int accessMode); + + +int +get_path(int fd, const char* path, char** fullPath) +{ + struct stat dirst; + if (fstat(fd, &dirst) < 0) { + // failed to grab stat information, fstat() sets errno + return -1; + } + + if (!S_ISDIR(dirst.st_mode)) { + // fd does not point to a directory + errno = ENOTDIR; + return -1; + } + + if (fcntl(fd, F_GETPATH, *fullPath) < 0) { + // failed to get the path of fd, fcntl() sets errno + return -1; + } + + if (strlcat(*fullPath, "/", MAXPATHLEN) > MAXPATHLEN + || strlcat(*fullPath, path, MAXPATHLEN) > MAXPATHLEN) { + // full path is too long + errno = ENAMETOOLONG; + return -1; + } +} + +int +eaccess(const char* path, int accessMode) +{ + uid_t uid = geteuid(); + int fileMode = 0; + + struct stat st; + if (stat(path, &st) < 0) { + // failed to get stat information on path, stat() sets errno + return -1; + } + + 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 == getegid()) { + // 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) { + errno = EACCES; + return -1; + } + + return 0; +} + + +int +faccessat(int fd, const char* path, int accessMode, int flag) +{ + if (flag != AT_EACCESS && flag != 0) { + // invalid flag + errno = EINVAL; + return -1; + } + + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call access() ignoring fd + return (flag & AT_EACCESS) != 0 ? eaccess(path, accessMode) + : access(path, accessMode); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = (flag & AT_EACCESS) != 0 ? eaccess(fullPath, accessMode) + : access(fullPath, accessMode); + free(fullPath); + return status; +} + + +int +fchmodat(int fd, const char* path, mode_t mode, int flag) +{ + if ((flag & AT_SYMLINK_NOFOLLOW) == 0 && flag != 0) { + // invalid flag + errno = EINVAL; + return -1; + } + + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call chmod() ignoring fd + if ((flag & AT_SYMLINK_NOFOLLOW) != 0) { + // fake lchmod() with open() and fchmod() + int symlinkfd = open(path, O_RDONLY | O_SYMLINK); + int status = fchmod(symlinkfd, mode); + close(symlinkfd); + return status; + } else + return chmod(path, mode); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status; + + if ((flag & AT_SYMLINK_NOFOLLOW) != 0) { + // fake lchmod() with open() and fchmod() + int fullfd = open(fullPath, O_RDONLY | O_SYMLINK); + status = fchmod(fullfd, mode); + close(fullfd); + } else + status = chmod(fullPath, mode); + + free(fullPath); + return status; +} + + +int +fchownat(int fd, const char* path, uid_t owner, gid_t group, int flag) +{ + if ((flag & AT_SYMLINK_NOFOLLOW) == 0 && flag != 0) { + // invalid flag + errno = EINVAL; + return -1; + } + + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call chown() ignoring fd + return (flag & AT_SYMLINK_NOFOLLOW) != 0 ? lchown(path, owner, group) + : chown(path, owner, group); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = (flag & AT_SYMLINK_NOFOLLOW) != 0 + ? lchown(fullPath, owner, group) : chown(fullPath, owner, group); + free(fullPath); + return status; +} + + +int +fstatat(int fd, const char *path, struct stat *st, int flag) +{ + if ((flag & AT_SYMLINK_NOFOLLOW) == 0 && flag != 0) { + // invalid flag + errno = EINVAL; + return -1; + } + + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call stat() or lstat() ignoring fd + return (flag & AT_SYMLINK_NOFOLLOW) != 0 ? lstat(path, st) + : stat(path, st); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = (flag & AT_SYMLINK_NOFOLLOW) != 0 ? lstat(fullPath, st) + : stat(fullPath, st); + free(fullPath); + return status; +} + + +int +mkdirat(int fd, const char *path, mode_t mode) +{ + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call mkdir() ignoring fd + return mkdir(path, mode); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = mkdir(fullPath, mode); + free(fullPath); + return status; +} + + +int +mkfifoat(int fd, const char *path, mode_t mode) +{ + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call mkfifo() ignoring fd + return mkfifo(path, mode); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = mkfifo(fullPath, mode); + free(fullPath); + return status; +} + + +int +mknodat(int fd, const char *path, mode_t mode, dev_t dev) +{ + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call mknod() ignoring fd + return mknod(path, mode, dev); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = mknod(fullPath, mode, dev); + free(fullPath); + return status; +} + + +int +renameat(int oldFD, const char* oldPath, int newFD, const char* newPath) +{ + bool ignoreOldFD = false; + bool ignoreNewFD = false; + + if (oldFD == AT_FDCWD || oldPath != NULL && oldPath[0] == '/') + ignoreOldFD = true; + + if (newFD == AT_FDCWD || newPath != NULL && newPath[0] == '/') + ignoreNewFD = true; + + if (ignoreOldFD && ignoreNewFD) { + // call rename() ignoring the fd's + return rename(oldPath, newPath); + } + + char *oldFullPath; + char *newFullPath; + + if (!ignoreOldFD) { + if (oldFD < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + oldFullPath = (char *)malloc(MAXPATHLEN); + if (oldFullPath == NULL) { + // ran out of memory allocating oldFullPath + errno = ENOMEM; + return -1; + } + + if (get_path(oldFD, oldPath, &oldFullPath) < 0) { + free(oldFullPath); + return -1; + } + } + + if (!ignoreNewFD) { + if (newFD < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + newFullPath = (char *)malloc(MAXPATHLEN); + if (newFullPath == NULL) { + // ran out of memory allocating newFullPath + errno = ENOMEM; + return -1; + } + + if (get_path(newFD, newPath, &newFullPath) < 0) { + free(newFullPath); + return -1; + } + } + + int status = rename(ignoreOldFD ? oldPath : oldFullPath, + ignoreNewFD ? newPath : newFullPath); + if (!ignoreOldFD) + free(oldFullPath); + if (!ignoreNewFD) + free(newFullPath); + return status; +} + + +ssize_t +readlinkat(int fd, const char *path, char *buffer, size_t bufferSize) +{ + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call readlink() ignoring fd + return readlink(path, buffer, bufferSize); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = readlink(fullPath, buffer, bufferSize); + free(fullPath); + return status; +} + + +int +symlinkat(const char *oldPath, int fd, const char *newPath) +{ + if (fd == AT_FDCWD || newPath != NULL && newPath[0] == '/') { + // call symlink() ignoring fd + return symlink(oldPath, newPath); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *oldFullPath = (char *)malloc(MAXPATHLEN); + if (oldFullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, oldPath, &oldFullPath) < 0) { + free(oldFullPath); + return -1; + } + + int status = symlink(oldFullPath, newPath); + free(oldFullPath); + return status; +} + + +int +unlinkat(int fd, const char *path, int flag) +{ + if ((flag & AT_REMOVEDIR) == 0 && flag != 0) { + // invalid flag + errno = EINVAL; + return -1; + } + + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call rmdir() or unlink() ignoring fd + return (flag & AT_REMOVEDIR) != 0 ? rmdir(path) : unlink(path); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = (flag & AT_REMOVEDIR) != 0 ? rmdir(fullPath) + : unlink(fullPath); + free(fullPath); + return status; +} + + +int +linkat(int oldFD, const char *oldPath, int newFD, const char *newPath, + int flag) +{ + if ((flag & AT_SYMLINK_FOLLOW) != 0) { + // Dereference oldPath + // CURRENTLY UNSUPPORTED + errno = ENOTSUP; + return -1; + } else if (flag != 0) { + errno = EINVAL; + return -1; + } + + bool ignoreOldFD = false; + bool ignoreNewFD = false; + + if (oldFD == AT_FDCWD || oldPath != NULL && oldPath[0] == '/') + ignoreOldFD = true; + + if (newFD == AT_FDCWD || newPath != NULL && newPath[0] == '/') + ignoreNewFD = true; + + if (ignoreOldFD && ignoreNewFD) { + // call link() ignoring the fd's + return link(oldPath, newPath); + } + + char *oldFullPath; + char *newFullPath; + + if (!ignoreOldFD) { + if (oldFD < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + oldFullPath = (char *)malloc(MAXPATHLEN); + if (oldFullPath == NULL) { + // ran out of memory allocating oldFullPath + errno = ENOMEM; + return -1; + } + + if (get_path(oldFD, oldPath, &oldFullPath) < 0) { + free(oldFullPath); + return -1; + } + } + + if (!ignoreNewFD) { + if (newFD < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + newFullPath = (char *)malloc(MAXPATHLEN); + if (newFullPath == NULL) { + // ran out of memory allocating newFullPath + errno = ENOMEM; + return -1; + } + + if (get_path(newFD, newPath, &newFullPath) < 0) { + free(newFullPath); + return -1; + } + } + + int status = link(ignoreOldFD ? oldPath : oldFullPath, + ignoreNewFD ? newPath : newFullPath); + if (!ignoreOldFD) + free(oldFullPath); + if (!ignoreNewFD) + free(newFullPath); + return status; +} + + +int +futimesat(int fd, const char *path, const struct timeval times[2]) +{ + if (fd == AT_FDCWD || path != NULL && path[0] == '/') { + // call utimes() ignoring fd + return utimes(path, times); + } + + if (fd < 0) { + // Invalid file descriptor + errno = EBADF; + return -1; + } + + char *fullPath = (char *)malloc(MAXPATHLEN); + if (fullPath == NULL) { + // ran out of memory allocating dirpath + errno = ENOMEM; + return -1; + } + + if (get_path(fd, path, &fullPath) < 0) { + free(fullPath); + return -1; + } + + int status = utimes(fullPath, times); + free(fullPath); + return status; +} diff --git a/src/build/libroot/fs_darwin.h b/src/build/libroot/fs_darwin.h new file mode 100644 index 0000000..dbdd7c2 --- /dev/null +++ b/src/build/libroot/fs_darwin.h @@ -0,0 +1,41 @@ +/* + * Copyright 2011, John Scipione, jscipione@xxxxxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef FS_DARWIN_H +#define FS_DARWIN_H + +/* + * Magic value that specify the use of the current working directory + * to determine the target of relative file paths in the openat() and + * similar syscalls. + */ +#define AT_FDCWD -100 /* CWD FD for the *at() functions */ + +/* + * Miscellaneous flags for the *at() syscalls. + */ +#define AT_EACCESS 0x100 /* faccessat() */ +#define AT_SYMLINK_NOFOLLOW 0x200 /* fstatat(), fchmodat(), fchownat(), + utimensat() */ +#define AT_SYMLINK_FOLLOW 0x400 /* linkat() */ +#define AT_REMOVEDIR 0x800 /* unlinkat() */ + +int faccessat(int fd, const char* path, int accessMode, int flag); +int fchmodat(int fd, const char* path, mode_t mode, int flag); +int fchownat(int fd, const char* path, uid_t owner, gid_t group, int flag); +int fstatat(int fd, const char *path, struct stat *st, int flag); +int mkdirat(int fd, const char *path, mode_t mode); +int mkfifoat(int fd, const char *path, mode_t mode); +int mknodat(int fd, const char *name, mode_t mode, dev_t dev); +int renameat(int oldFD, const char* oldPath, int newFD, const char* newPath); + +ssize_t readlinkat(int fd, const char *path, char *buffer, size_t bufferSize); +int symlinkat(const char *oldPath, int fd, const char *newPath); +int unlinkat(int fd, const char *path, int flag); +int linkat(int oldFD, const char *oldPath, int newFD, const char *newPath, + int flag); + +int futimesat(int fd, const char *path, const struct timeval times[2]); + +#endif // FS_DARWIN_H diff --git a/src/build/libroot/fs_freebsd.cpp b/src/build/libroot/fs_freebsd.cpp index 339d8a5..648650e 100644 --- a/src/build/libroot/fs_freebsd.cpp +++ b/src/build/libroot/fs_freebsd.cpp @@ -254,127 +254,3 @@ haiku_freebsd_writev(int fd, const struct iovec *vecs, size_t count) return bytesWritten; } - - -#if defined(_HAIKU_BUILD_NO_FUTIMENS) || defined(_HAIKU_BUILD_NO_FUTIMENS) - -template<typename File> -static int -utimes_helper(File& file, const struct timespec times[2]) -{ - if (times == NULL) - return file.SetTimes(NULL); - - timeval timeBuffer[2]; - timeBuffer[0].tv_sec = times[0].tv_sec; - timeBuffer[0].tv_usec = times[0].tv_nsec / 1000; - timeBuffer[1].tv_sec = times[1].tv_sec; - timeBuffer[1].tv_usec = times[1].tv_nsec / 1000; - - if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) { - struct stat st; - if (file.GetStat(st) != 0) - return -1; - - if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) - return 0; - - if (times[0].tv_nsec == UTIME_OMIT) { - timeBuffer[0].tv_sec = st.st_atimespec.tv_sec; - timeBuffer[0].tv_usec = st.st_atimespec.tv_nsec / 1000; - } - - if (times[1].tv_nsec == UTIME_OMIT) { - timeBuffer[1].tv_sec = st.st_mtimespec.tv_sec; - timeBuffer[1].tv_usec = st.st_mtimespec.tv_nsec / 1000; - } - } - - if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) { - timeval now; - gettimeofday(&now, NULL); - - if (times[0].tv_nsec == UTIME_NOW) - timeBuffer[0] = now; - - if (times[1].tv_nsec == UTIME_NOW) - timeBuffer[1] = now; - } - - return file.SetTimes(timeBuffer); -} - -#endif // _HAIKU_BUILD_NO_FUTIMENS || _HAIKU_BUILD_NO_FUTIMENS - - -#ifdef _HAIKU_BUILD_NO_FUTIMENS - -struct FDFile { - FDFile(int fd) - : - fFD(fd) - { - } - - int GetStat(struct stat& _st) - { - return fstat(fFD, &_st); - } - - int SetTimes(const timeval times[2]) - { - return futimes(fFD, times); - } - -private: - int fFD; -}; - - -int -futimens(int fd, const struct timespec times[2]) -{ - FDFile file(fd); - return utimes_helper(file, times); -} - -#endif // _HAIKU_BUILD_NO_FUTIMENS - - -#ifdef _HAIKU_BUILD_NO_UTIMENSAT - -struct FDPathFile { - FDPathFile(int fd, const char* path, int flag) - : - fFD(fd), - fPath(path), - fFlag(flag) - { - } - - int GetStat(struct stat& _st) - { - return fstatat(fFD, fPath, &_st, fFlag); - } - - int SetTimes(const timeval times[2]) - { - // TODO: fFlag (AT_SYMLINK_NOFOLLOW) is not supported here! - return futimesat(fFD, fPath, times); - } - -private: - int fFD; - const char* fPath; - int fFlag; -}; - - -int -utimensat(int fd, const char* path, const struct timespec times[2], int flag) -{ - FDPathFile file(fd, path, flag); - return utimes_helper(file, times); -} - -#endif // _HAIKU_BUILD_NO_UTIMENSAT diff --git a/src/system/libroot/os/driver_settings.cpp b/src/system/libroot/os/driver_settings.cpp index b62bea0..8abe187 100644 --- a/src/system/libroot/os/driver_settings.cpp +++ b/src/system/libroot/os/driver_settings.cpp @@ -977,5 +977,5 @@ get_driver_settings(void *handle) // this creates an alias of the above function // unload_driver_settings() is the same as delete_driver_settings() extern "C" __typeof(unload_driver_settings) delete_driver_settings - __attribute__((alias ("unload_driver_settings"))); + __attribute__((weak, alias ("unload_driver_settings")));