/* * SYS_FSTAT.C */ #include "defs.h" #include /* * FStatStor */ typedef struct FStatStor { runeino_t ino; int64_t nlink; runeuid_t uid; runegid_t gid; runedev_t dev; uint32_t gen; int error; runemode_t mode; runemode_t filler02; runetime_t atime; runetime_t mtime; runetime_t ctime; runeoff_t size; } FStatStor; struct stat_path_args { LValueStor lvs; PointerStor path; }; struct stat_fd_args { LValueStor lvs; int32_t fd; #if LONG_BITS == 64 int32_t filler01; #endif }; static __inline void rstfixup(struct stat *st, FStatStor *rst) { /* * Portability fixup - signextend if machine target * uses smaller types. */ if (sizeof(st->st_ino) < sizeof(int64_t)) rst->ino = (int64_t)(int)st->st_ino; else rst->ino = st->st_ino; if (sizeof(st->st_nlink) < sizeof(int64_t)) rst->nlink = (int64_t)(int)st->st_nlink; else rst->nlink = st->st_nlink; if (sizeof(st->st_uid) < sizeof(int64_t)) rst->uid = (int64_t)(int)st->st_uid; else rst->uid = st->st_uid; if (sizeof(st->st_gid) < sizeof(int64_t)) rst->gid = (int64_t)(int)st->st_gid; else rst->gid = st->st_gid; rst->dev = st->st_dev; rst->gen = st->st_gen; rst->mode = st->st_mode; if (sizeof(st->st_atime) < sizeof(int64_t)) { rst->atime = (int64_t)(uint32_t)st->st_atime; rst->mtime = (int64_t)(uint32_t)st->st_mtime; rst->ctime = (int64_t)(uint32_t)st->st_ctime; } else { rst->atime = st->st_atime; rst->mtime = st->st_mtime; rst->ctime = st->st_ctime; } if (sizeof(st->st_size) < sizeof(int64_t)) rst->size = (int64_t)(int)st->st_size; else rst->size = st->st_size; } void RuneSysCall_stat(struct stat_path_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; const char *path = args->path.s_Addr; struct stat st; STRBOUNDSCHECK(&args->path, PATH_MAX); if (stat(path, &st) == 0) { rstfixup(&st, rst); rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_lstat(struct stat_path_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; const char *path = args->path.s_Addr; struct stat st; STRBOUNDSCHECK(&args->path, PATH_MAX); if (lstat(path, &st) == 0) { rstfixup(&st, rst); rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_fstat(struct stat_fd_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; struct stat st; if (fstat(args->fd, &st) == 0) { rstfixup(&st, rst); rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_chmod(struct stat_path_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; const char *path = args->path.s_Addr; STRBOUNDSCHECK(&args->path, PATH_MAX); if (chmod(path, rst->mode) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_lchmod(struct stat_path_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; const char *path = args->path.s_Addr; STRBOUNDSCHECK(&args->path, PATH_MAX); if (lchmod(path, rst->mode) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_fchmod(struct stat_fd_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; if (fchmod(args->fd, rst->mode) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_chown(struct stat_path_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; const char *path = args->path.s_Addr; STRBOUNDSCHECK(&args->path, PATH_MAX); if (chown(path, rst->uid, rst->gid) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_lchown(struct stat_path_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; const char *path = args->path.s_Addr; STRBOUNDSCHECK(&args->path, PATH_MAX); if (lchown(path, rst->uid, rst->gid) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_fchown(struct stat_fd_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; if (fchown(args->fd, rst->uid, rst->gid) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_utimes(struct stat_path_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; const char *path = args->path.s_Addr; struct timeval times[2]; STRBOUNDSCHECK(&args->path, PATH_MAX); times[0].tv_sec = rst->atime; times[0].tv_usec = (rst->atime == (runetime_t)-1 ? -1 : 0); times[1].tv_sec = rst->mtime; times[1].tv_usec = (rst->mtime == (runetime_t)-1 ? -1 : 0); if (utimes(path, times) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_lutimes(struct stat_path_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; const char *path = args->path.s_Addr; struct timeval times[2]; STRBOUNDSCHECK(&args->path, PATH_MAX); times[0].tv_sec = rst->atime; times[0].tv_usec = (rst->atime == (runetime_t)-1 ? -1 : 0); times[1].tv_sec = rst->mtime; times[1].tv_usec = (rst->mtime == (runetime_t)-1 ? -1 : 0); if (lutimes(path, times) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } } void RuneSysCall_futimes(struct stat_fd_args *args, int *resp) { FStatStor *rst = args->lvs.s_Addr; struct timeval times[2]; times[0].tv_sec = rst->atime; times[0].tv_usec = (rst->atime == (runetime_t)-1 ? -1 : 0); times[1].tv_sec = rst->mtime; times[1].tv_usec = (rst->mtime == (runetime_t)-1 ? -1 : 0); if (futimes(args->fd, times) == 0) { rst->error = 0; *resp = 0; } else { rst->error = errno; *resp = -1; } }