diff --git a/libc/Makefile b/libc/Makefile index 207d662b..ff9e2702 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -197,6 +197,7 @@ stat.o \ stdio.o \ tfork.o \ time.o \ +truncateat.o \ truncate.o \ umask.o \ unlinkat.o \ diff --git a/libc/include/unistd.h b/libc/include/unistd.h index db0e1a58..916a263d 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -176,6 +176,7 @@ ssize_t read(int, void*, size_t); int rmdir(const char*); unsigned sleep(unsigned); int truncate(const char*, off_t); +int truncateat(int dirfd, const char*, off_t); #if __POSIX_OBSOLETE <= 200112 || defined(_SORTIX_SOURCE) int usleep(useconds_t useconds); #endif diff --git a/libc/truncateat.cpp b/libc/truncateat.cpp new file mode 100644 index 00000000..c65b447e --- /dev/null +++ b/libc/truncateat.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2012. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + truncateat.cpp + Truncates a file to a specific size. + +*******************************************************************************/ + +#include +#include +#include + +DEFN_SYSCALL3(int, sys_truncateat, SYSCALL_TRUNCATEAT, int, const char*, off_t); + +extern "C" int truncateat(int dirfd, const char* pathname, off_t length) +{ + return sys_truncateat(dirfd, pathname, length); +} diff --git a/sortix/include/sortix/syscallnum.h b/sortix/include/sortix/syscallnum.h index c3a9d310..7707658a 100644 --- a/sortix/include/sortix/syscallnum.h +++ b/sortix/include/sortix/syscallnum.h @@ -86,6 +86,7 @@ #define SYSCALL_FACCESSAT 62 #define SYSCALL_MKDIRAT 63 #define SYSCALL_FCHDIR 64 -#define SYSCALL_MAX_NUM 65 /* index of highest constant + 1 */ +#define SYSCALL_TRUNCATEAT 65 +#define SYSCALL_MAX_NUM 66 /* index of highest constant + 1 */ #endif diff --git a/sortix/io.cpp b/sortix/io.cpp index d2b35ebd..d4034e3e 100644 --- a/sortix/io.cpp +++ b/sortix/io.cpp @@ -226,14 +226,15 @@ static int sys_rmdir(const char* path) return sys_unlinkat(AT_FDCWD, path, AT_REMOVEDIR); } -static int sys_truncate(const char* path, off_t length) +static int sys_truncateat(int dirfd, const char* path, off_t length) { char* pathcopy = GetStringFromUser(path); if ( !pathcopy ) return -1; ioctx_t ctx; SetupUserIOCtx(&ctx); const char* relpath = pathcopy; - Ref from = PrepareLookup(&relpath); + Ref from = PrepareLookup(&relpath, dirfd); + if ( !from ) { delete[] pathcopy; return -1; } Ref desc = from->open(&ctx, relpath, O_WRONLY); delete[] pathcopy; if ( !desc ) @@ -241,6 +242,11 @@ static int sys_truncate(const char* path, off_t length) return desc->truncate(&ctx, length); } +static int sys_truncate(const char* path, off_t length) +{ + return sys_truncateat(AT_FDCWD, path, length); +} + static int sys_ftruncate(int fd, off_t length) { Ref desc = CurrentProcess()->GetDescriptor(fd); @@ -475,6 +481,7 @@ void Init() Syscall::Register(SYSCALL_SETTERMMODE, (void*) sys_settermmode); Syscall::Register(SYSCALL_STAT, (void*) sys_stat); Syscall::Register(SYSCALL_TCGETWINSIZE, (void*) sys_tcgetwinsize); + Syscall::Register(SYSCALL_TRUNCATEAT, (void*) sys_truncateat); Syscall::Register(SYSCALL_TRUNCATE, (void*) sys_truncate); Syscall::Register(SYSCALL_UNLINKAT, (void*) sys_unlinkat); Syscall::Register(SYSCALL_UNLINK, (void*) sys_unlink);