Implemented POSIX.1-2008 functions unlinkat(), symlinkat(), mkdirat(),

utimensat(), and futimens().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34010 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-11-12 19:14:42 +00:00
parent 3f98707eb3
commit 6c00aabc9e
7 changed files with 114 additions and 29 deletions
+1
View File
@@ -70,6 +70,7 @@
#define AT_SYMLINK_NOFOLLOW 0x1 /* fstatat(), fchmodat(), fchownat(),
utimensat() */
#define AT_SYMLINK_FOLLOW 0x2 /* linkat() */
#define AT_REMOVEDIR 0x04 /* unlinkat() */
#endif
/* advisory file locking */
+13
View File
@@ -101,6 +101,10 @@ struct stat {
#define DEFFILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
/* default file mode, everyone can read/write */
/* special values for timespec::tv_nsec passed to utimensat(), futimens() */
#define UTIME_NOW 1000000000
#define UTIME_OMIT 1000000001
#ifdef __cplusplus
extern "C" {
#endif
@@ -114,9 +118,18 @@ extern int lstat(const char *path, struct stat *st);
extern int fstatat(int fd, const char *path, struct stat *st, int flag);
#endif
extern int mkdir(const char *path, mode_t mode);
#ifdef B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT
extern int mkdirat(int fd, const char *path, mode_t mode);
#endif
extern int mkfifo(const char *path, mode_t mode);
extern mode_t umask(mode_t cmask);
#ifdef B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT
extern int utimensat(int fd, const char *path,
const struct timespec times[2], int flag);
#endif
extern int futimens(int fd, const struct timespec times[2]);
#ifdef __cplusplus
}
#endif
+7 -1
View File
@@ -135,6 +135,9 @@ extern int dup2(int fd1, int fd2);
extern int close(int fd);
extern int link(const char *name, const char *new_name);
extern int unlink(const char *name);
#ifdef B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT
extern int unlinkat(int fd, const char *path, int flag);
#endif
extern int rmdir(const char *path);
extern ssize_t readlink(const char *path, char *buffer, size_t bufferSize);
@@ -142,7 +145,10 @@ extern ssize_t readlink(const char *path, char *buffer, size_t bufferSize);
extern ssize_t readlinkat(int fd, const char *path, char *buffer,
size_t bufferSize);
#endif
extern int symlink(const char *from, const char *to);
extern int symlink(const char *toPath, const char *symlinkPath);
#ifdef B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT
extern int symlinkat(const char *toPath, int fd, const char *symlinkPath);
#endif
extern int ftruncate(int fd, off_t newSize);
extern int truncate(const char *path, off_t newSize);
+12 -11
View File
@@ -4,25 +4,26 @@
*/
#define B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT 1
// make the *at() functions and AT_* macros visible
#include <sys/stat.h>
#include <errno.h>
#include <syscalls.h>
#include <syscall_utils.h>
#include <umask.h>
#define RETURN_AND_SET_ERRNO(err) \
if (err < 0) { \
errno = err; \
return -1; \
} \
return err;
int
mkdir(const char* path, mode_t mode)
{
status_t status = _kern_create_dir(-1, path, mode & ~__gUmask);
RETURN_AND_SET_ERRNO(status);
RETURN_AND_SET_ERRNO(_kern_create_dir(-1, path, mode & ~__gUmask));
}
int
mkdirat(int fd, const char *path, mode_t mode)
{
RETURN_AND_SET_ERRNO(_kern_create_dir(fd, path, mode & ~__gUmask));
}
+62 -8
View File
@@ -1,9 +1,13 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Copyright 2006-2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#define B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT 1
// make the *at() functions and AT_* macros visible
#include <sys/time.h>
#include <errno.h>
@@ -11,14 +15,7 @@
#include <NodeMonitor.h>
#include <syscalls.h>
#define RETURN_AND_SET_ERRNO(err) \
if (err < 0) { \
errno = err; \
return -1; \
} \
return err;
#include <syscall_utils.h>
int
@@ -45,3 +42,60 @@ utimes(const char* path, const struct timeval times[2])
RETURN_AND_SET_ERRNO(status);
}
int
utimensat(int fd, const char *path, const struct timespec times[2], int 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) {
bigtime_t now = real_time_clock_usecs();
stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 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];
}
}
// 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
futimens(int fd, const struct timespec times[2])
{
return utimensat(fd, NULL, times, 0);
}
+1 -1
View File
@@ -1,7 +1,7 @@
SubDir HAIKU_TOP src system libroot posix unistd ;
UsePrivateSystemHeaders ;
UsePrivateHeaders libroot runtime_loader ;
UsePrivateHeaders libroot runtime_loader shared ;
MergeObject posix_unistd.o :
access.c
+18 -8
View File
@@ -10,14 +10,7 @@
#include <unistd.h>
#include <errno.h>
#include <syscalls.h>
#define RETURN_AND_SET_ERRNO(err) \
if (err < 0) { \
errno = err; \
return -1; \
} \
return err;
#include <syscall_utils.h>
ssize_t
@@ -55,6 +48,13 @@ symlink(const char *toPath, const char *symlinkPath)
}
int
symlinkat(const char *toPath, int fd, const char *symlinkPath)
{
RETURN_AND_SET_ERRNO(_kern_create_symlink(fd, symlinkPath, toPath, 0));
}
int
unlink(const char *path)
{
@@ -64,6 +64,16 @@ unlink(const char *path)
}
int
unlinkat(int fd, const char *path, int flag)
{
if ((flag & AT_REMOVEDIR) != 0)
RETURN_AND_SET_ERRNO(_kern_remove_dir(fd, path));
else
RETURN_AND_SET_ERRNO(_kern_unlink(fd, path));
}
int
link(const char *toPath, const char *linkPath)
{