truncate(2)/ftruncate(2)
This commit is contained in:
@@ -53,6 +53,8 @@ void *syscall_table[256] = {
|
||||
[SYSCALL_NR_SELECT] = sys_select,
|
||||
[SYSCALL_NR_DUP] = sys_dup,
|
||||
[SYSCALL_NR_DUP2] = sys_dup2,
|
||||
[SYSCALL_NR_TRUNCATE] = sys_truncate,
|
||||
[SYSCALL_NR_FTRUNCATE] = sys_ftruncate,
|
||||
[SYSCALL_NR_GETCWD] = sys_getcwd,
|
||||
[SYSCALL_NR_CHDIR] = sys_chdir,
|
||||
[SYSCALL_NR_MKDIRAT] = sys_mkdirat,
|
||||
|
||||
@@ -542,6 +542,22 @@ int vfs_fstatat(struct vfs_ioctx *ctx, struct vnode *at, const char *path, struc
|
||||
return node->op->stat(node, st);
|
||||
}
|
||||
|
||||
int vfs_ftruncate(struct vfs_ioctx *ctx, struct vnode *node, off_t length) {
|
||||
_assert(ctx);
|
||||
_assert(node);
|
||||
|
||||
if (node->type != VN_REG) {
|
||||
kwarn("truncate() on non-file\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (node->op && node->op->truncate) {
|
||||
return node->op->truncate(node, length);
|
||||
} else {
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t vfs_write(struct vfs_ioctx *ctx, struct ofile *fd, const void *buf, size_t count) {
|
||||
struct vnode *node;
|
||||
ssize_t b;
|
||||
|
||||
@@ -54,6 +54,7 @@ int vfs_mknod(struct vfs_ioctx *ctx, const char *path, mode_t mode, struct vnode
|
||||
int vfs_chmod(struct vfs_ioctx *ctx, const char *path, mode_t mode);
|
||||
int vfs_chown(struct vfs_ioctx *ctx, const char *path, uid_t uid, gid_t gid);
|
||||
int vfs_ioctl(struct vfs_ioctx *ctx, struct ofile *fd, unsigned int cmd, void *arg);
|
||||
int vfs_ftruncate(struct vfs_ioctx *ctx, struct vnode *node, off_t length);
|
||||
|
||||
int vfs_faccessat(struct vfs_ioctx *ctx, struct vnode *at, const char *path, int accmode, int flags);
|
||||
int vfs_fstatat(struct vfs_ioctx *ctx, struct vnode *at, const char *path, struct stat *st, int flags);
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
ssize_t sys_read(int fd, void *data, size_t lim);
|
||||
ssize_t sys_write(int fd, const void *data, size_t lim);
|
||||
int sys_ftruncate(int fd, off_t length);
|
||||
int sys_truncate(const char *filename, off_t length);
|
||||
int sys_creat(const char *pathname, int mode);
|
||||
int sys_mkdirat(int dfd, const char *pathname, int mode);
|
||||
int sys_unlinkat(int dfd, const char *pathname, int flags);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#define SYSCALL_NR_SELECT 23
|
||||
#define SYSCALL_NR_DUP 32
|
||||
#define SYSCALL_NR_DUP2 33
|
||||
#define SYSCALL_NR_TRUNCATE 76
|
||||
#define SYSCALL_NR_FTRUNCATE 77
|
||||
#define SYSCALL_NR_GETCWD 79
|
||||
#define SYSCALL_NR_CHDIR 80
|
||||
#define SYSCALL_NR_MKDIRAT 83
|
||||
|
||||
@@ -105,6 +105,31 @@ int sys_unlinkat(int dfd, const char *pathname, int flags) {
|
||||
return vfs_unlinkat(get_ioctx(), at, pathname, flags);
|
||||
}
|
||||
|
||||
int sys_truncate(const char *pathname, off_t length) {
|
||||
userptr_check(pathname);
|
||||
struct vnode *node;
|
||||
struct vfs_ioctx *ioctx = get_ioctx();
|
||||
int res;
|
||||
|
||||
if ((res = vfs_find(ioctx, ioctx->cwd_vnode, pathname, 0, &node)) != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
return vfs_ftruncate(ioctx, node, length);
|
||||
}
|
||||
|
||||
int sys_ftruncate(int fd, off_t length) {
|
||||
struct ofile *of = get_fd(fd);
|
||||
if (!of) {
|
||||
return -EBADF;
|
||||
}
|
||||
if (of->flags & OF_SOCKET) {
|
||||
kwarn("truncate() on socket\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return vfs_ftruncate(get_ioctx(), of->file.vnode, length);
|
||||
}
|
||||
|
||||
int sys_chdir(const char *filename) {
|
||||
userptr_check(filename);
|
||||
return vfs_setcwd(get_ioctx(), filename);
|
||||
|
||||
Reference in New Issue
Block a user