}
if (syscall_no == SYSCALL_PREAD || syscall_no == SYSCALL_PWRITE ||
- syscall_no == SYSCALL_ACCESS) {
+ syscall_no == SYSCALL_ACCESS || syscall_no == SYSCALL_TRUNCATE ||
+ syscall_no == SYSCALL_FTRUNCATE) {
posix_ext_syscall_dispatch(regs, syscall_no);
return;
}
return;
}
+ if (syscall_no == SYSCALL_FTRUNCATE) {
+ int fd = (int)regs->ebx;
+ uint32_t length = regs->ecx;
+ struct file* f = fd_get(fd);
+ if (!f || !f->node) { regs->eax = (uint32_t)-EBADF; return; }
+ if (!(f->node->flags & FS_FILE)) { regs->eax = (uint32_t)-EINVAL; return; }
+ f->node->length = length;
+ regs->eax = 0;
+ return;
+ }
+
+ if (syscall_no == SYSCALL_TRUNCATE) {
+ const char* user_path = (const char*)regs->ebx;
+ uint32_t length = regs->ecx;
+ if (!user_path) { regs->eax = (uint32_t)-EFAULT; return; }
+ char path[128];
+ int prc = path_resolve_user(user_path, path, sizeof(path));
+ if (prc < 0) { regs->eax = (uint32_t)prc; return; }
+ fs_node_t* node = vfs_lookup(path);
+ if (!node) { regs->eax = (uint32_t)-ENOENT; return; }
+ if (!(node->flags & FS_FILE)) { regs->eax = (uint32_t)-EISDIR; return; }
+ node->length = length;
+ regs->eax = 0;
+ return;
+ }
+
regs->eax = (uint32_t)-ENOSYS;
}
int access(const char* path, int mode);
int setuid(int uid);
int setgid(int gid);
+int truncate(const char* path, int length);
+int ftruncate(int fd, int length);
void* brk(void* addr);
void _exit(int status) __attribute__((noreturn));
return __syscall_ret(_syscall1(SYS_SETGID, gid));
}
+int truncate(const char* path, int length) {
+ return __syscall_ret(_syscall2(SYS_TRUNCATE, (int)path, length));
+}
+
+int ftruncate(int fd, int length) {
+ return __syscall_ret(_syscall2(SYS_FTRUNCATE, fd, length));
+}
+
void* brk(void* addr) {
return (void*)_syscall1(SYS_BRK, (int)addr);
}