- Added Linux-compatible file metadata syscalls (stat, lstat, fstat, newfstatat) - Implemented access control checks with faccessat and related flag definitions - Added file persistence operations (fsync, fdatasync, truncate, ftruncate) - Integrated clock syscalls (gettimeofday, clock_gettime, clock_getres) - Added process identity queries (getpid, getppid, gettid, getuid, getgid) - Changed exit mechanism from exit(60) to exit_group(231) for consistency - Updated crt0.S with Linux x86-64 exit_group ABI compatibility - Extended fcntl.h with AT_SYMLINK_NOFOLLOW and AT_EACCESS constants - Added complete syscalls implementation in user/libc.c and runtime/posix.c - Implemented kernel-side syscall handlers in process.c with proper validation - Added systest utility to verify file metadata, persistence and identity calls - Updated Makefile dependencies to track user header changes - Enhanced README documentation for newmaster
parent
2d052429ca
commit
ee69e75f4f
26 changed files with 667 additions and 66 deletions
@ -1,8 +1,40 @@ |
|||||||
#ifndef TYPEPHP_OS_USER_SYS_STAT_H |
#ifndef TYPEPHP_OS_USER_SYS_STAT_H |
||||||
#define TYPEPHP_OS_USER_SYS_STAT_H |
#define TYPEPHP_OS_USER_SYS_STAT_H |
||||||
|
|
||||||
typedef unsigned int mode_t; |
#include <sys/types.h> |
||||||
|
#include <time.h> |
||||||
|
|
||||||
|
struct stat { |
||||||
|
dev_t st_dev; |
||||||
|
ino_t st_ino; |
||||||
|
nlink_t st_nlink; |
||||||
|
mode_t st_mode; |
||||||
|
uid_t st_uid; |
||||||
|
gid_t st_gid; |
||||||
|
int __pad0; |
||||||
|
dev_t st_rdev; |
||||||
|
off_t st_size; |
||||||
|
blksize_t st_blksize; |
||||||
|
blkcnt_t st_blocks; |
||||||
|
struct timespec st_atim; |
||||||
|
struct timespec st_mtim; |
||||||
|
struct timespec st_ctim; |
||||||
|
long __reserved[3]; |
||||||
|
}; |
||||||
|
|
||||||
|
#define S_IFMT 0170000 |
||||||
|
#define S_IFREG 0100000 |
||||||
|
#define S_IFDIR 0040000 |
||||||
|
#define S_IFCHR 0020000 |
||||||
|
|
||||||
|
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) |
||||||
|
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) |
||||||
|
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) |
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode); |
int mkdir(const char *path, mode_t mode); |
||||||
|
int stat(const char *path, struct stat *value); |
||||||
|
int lstat(const char *path, struct stat *value); |
||||||
|
int fstat(int fd, struct stat *value); |
||||||
|
int fstatat(int directory_fd, const char *path, struct stat *value, int flags); |
||||||
|
|
||||||
#endif |
#endif |
||||||
|
|||||||
@ -0,0 +1,13 @@ |
|||||||
|
#ifndef TYPEPHP_OS_USER_SYS_TIME_H |
||||||
|
#define TYPEPHP_OS_USER_SYS_TIME_H |
||||||
|
|
||||||
|
#include <sys/types.h> |
||||||
|
|
||||||
|
struct timeval { |
||||||
|
time_t tv_sec; |
||||||
|
long tv_usec; |
||||||
|
}; |
||||||
|
|
||||||
|
int gettimeofday(struct timeval *value, void *timezone); |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
#ifndef TYPEPHP_OS_USER_SYS_TYPES_H |
||||||
|
#define TYPEPHP_OS_USER_SYS_TYPES_H |
||||||
|
|
||||||
|
/* Linux x86-64 ABI-compatible scalar types. Keeping this layout stable makes
|
||||||
|
* the userspace boundary suitable for a future glibc port. */ |
||||||
|
typedef unsigned long dev_t; |
||||||
|
typedef unsigned long ino_t; |
||||||
|
typedef unsigned long nlink_t; |
||||||
|
typedef unsigned int mode_t; |
||||||
|
typedef unsigned int uid_t; |
||||||
|
typedef unsigned int gid_t; |
||||||
|
typedef int pid_t; |
||||||
|
typedef long off_t; |
||||||
|
typedef long blksize_t; |
||||||
|
typedef long blkcnt_t; |
||||||
|
typedef long ssize_t; |
||||||
|
typedef long time_t; |
||||||
|
typedef int clockid_t; |
||||||
|
|
||||||
|
#endif |
||||||
@ -1,8 +1,18 @@ |
|||||||
#ifndef TYPEPHP_OS_USER_TIME_H |
#ifndef TYPEPHP_OS_USER_TIME_H |
||||||
#define TYPEPHP_OS_USER_TIME_H |
#define TYPEPHP_OS_USER_TIME_H |
||||||
|
|
||||||
typedef long time_t; |
#include <sys/types.h> |
||||||
|
|
||||||
|
#define CLOCK_REALTIME 0 |
||||||
|
#define CLOCK_MONOTONIC 1 |
||||||
|
|
||||||
|
struct timespec { |
||||||
|
time_t tv_sec; |
||||||
|
long tv_nsec; |
||||||
|
}; |
||||||
|
|
||||||
time_t time(time_t *result); |
time_t time(time_t *result); |
||||||
|
int clock_gettime(clockid_t clock_id, struct timespec *value); |
||||||
|
int clock_getres(clockid_t clock_id, struct timespec *value); |
||||||
|
|
||||||
#endif |
#endif |
||||||
|
|||||||
@ -0,0 +1,73 @@ |
|||||||
|
#include <fcntl.h> |
||||||
|
#include <stddef.h> |
||||||
|
#include <sys/stat.h> |
||||||
|
#include <sys/time.h> |
||||||
|
#include <time.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
_Static_assert(sizeof(struct stat) == 144, "Linux x86-64 stat ABI changed"); |
||||||
|
|
||||||
|
static int fail(const char *operation) |
||||||
|
{ |
||||||
|
size_t length = 0; |
||||||
|
while (operation[length] != '\0') { |
||||||
|
++length; |
||||||
|
} |
||||||
|
(void) write(STDERR_FILENO, "systest: ", sizeof("systest: ") - 1); |
||||||
|
(void) write(STDERR_FILENO, operation, length); |
||||||
|
(void) write(STDERR_FILENO, " failed\n", sizeof(" failed\n") - 1); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, char **argv) |
||||||
|
{ |
||||||
|
static const char path[] = "/SYS.TMP"; |
||||||
|
static const char payload[] = "abcdef"; |
||||||
|
struct stat info; |
||||||
|
struct timeval wall; |
||||||
|
struct timespec realtime; |
||||||
|
struct timespec monotonic; |
||||||
|
struct timespec resolution; |
||||||
|
int fd; |
||||||
|
(void) argc; |
||||||
|
(void) argv; |
||||||
|
|
||||||
|
if (stat("/HELLO.TXT", &info) != 0 || !S_ISREG(info.st_mode) |
||||||
|
|| info.st_size <= 0 || access("/HELLO.TXT", R_OK) != 0) { |
||||||
|
return fail("stat/access"); |
||||||
|
} |
||||||
|
if (fstatat(AT_FDCWD, "/HELLO.TXT", &info, AT_SYMLINK_NOFOLLOW) != 0 |
||||||
|
|| faccessat(AT_FDCWD, "/HELLO.TXT", R_OK, 0) != 0) { |
||||||
|
return fail("*at metadata"); |
||||||
|
} |
||||||
|
|
||||||
|
(void) unlink(path); |
||||||
|
fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0666); |
||||||
|
if (fd < 0 || write(fd, payload, sizeof(payload) - 1) != sizeof(payload) - 1 |
||||||
|
|| fsync(fd) != 0 || ftruncate(fd, 3) != 0 |
||||||
|
|| fstat(fd, &info) != 0 || info.st_size != 3 |
||||||
|
|| fdatasync(fd) != 0 || close(fd) != 0) { |
||||||
|
return fail("descriptor persistence"); |
||||||
|
} |
||||||
|
if (truncate(path, 1) != 0 || lstat(path, &info) != 0 |
||||||
|
|| info.st_size != 1 || unlink(path) != 0) { |
||||||
|
return fail("path truncate"); |
||||||
|
} |
||||||
|
|
||||||
|
if (getpid() != 2 || gettid() != 2 || getppid() != 1 |
||||||
|
|| getuid() != 0 || geteuid() != 0 || getgid() != 0 || getegid() != 0) { |
||||||
|
return fail("single-task identity"); |
||||||
|
} |
||||||
|
if (gettimeofday(&wall, NULL) != 0 || wall.tv_sec <= 0 |
||||||
|
|| clock_gettime(CLOCK_REALTIME, &realtime) != 0 |
||||||
|
|| clock_gettime(CLOCK_MONOTONIC, &monotonic) != 0 |
||||||
|
|| clock_getres(CLOCK_MONOTONIC, &resolution) != 0 |
||||||
|
|| realtime.tv_sec <= 0 || monotonic.tv_sec <= 0 |
||||||
|
|| resolution.tv_sec != 1 || resolution.tv_nsec != 0) { |
||||||
|
return fail("clock ABI"); |
||||||
|
} |
||||||
|
|
||||||
|
(void) write(STDOUT_FILENO, "basic syscalls: OK\n", |
||||||
|
sizeof("basic syscalls: OK\n") - 1); |
||||||
|
return 0; |
||||||
|
} |
||||||
Loading…
Reference in new issue