From 835f0d5fbcc8de252a30f4f75de724a4877cf462 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 23 Oct 2012 13:50:33 +0200 Subject: [PATCH] Add unlinkat(2). --- libc/Makefile | 1 + libc/include/unistd.h | 2 +- libc/unlinkat.cpp | 33 ++++++++++++++++++++++++++++++ sortix/include/sortix/fcntl.h | 1 + sortix/include/sortix/syscallnum.h | 3 ++- sortix/io.cpp | 29 +++++++++++++------------- 6 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 libc/unlinkat.cpp diff --git a/libc/Makefile b/libc/Makefile index 55af2be9..5182a72f 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -196,6 +196,7 @@ tfork.o \ time.o \ truncate.o \ umask.o \ +unlinkat.o \ unlink.o \ uptime.o \ usleep.o \ diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 0640cda6..0a04daf7 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -138,7 +138,6 @@ pid_t tcgetpgrp(int); int tcsetpgrp(int, pid_t); char* ttyname(int); int ttyname_r(int, char*, size_t); -int unlinkat(int, const char*, int); #if __POSIX_OBSOLETE <= 200801 pid_t setpgrp(void); @@ -180,6 +179,7 @@ int truncate(const char*, off_t); #if __POSIX_OBSOLETE <= 200112 || defined(_SORTIX_SOURCE) int usleep(useconds_t useconds); #endif +int unlinkat(int, const char*, int); int unlink(const char*); ssize_t write(int, const void*, size_t); diff --git a/libc/unlinkat.cpp b/libc/unlinkat.cpp new file mode 100644 index 00000000..d0f76e80 --- /dev/null +++ b/libc/unlinkat.cpp @@ -0,0 +1,33 @@ +/******************************************************************************* + + 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 . + + unlinkat.cpp + Removes a directory entry relative to directory. + +*******************************************************************************/ + +#include +#include + +DEFN_SYSCALL3(int, sys_unlinkat, SYSCALL_UNLINKAT, int, const char*, int); + +extern "C" int unlinkat(int dirfd, const char* pathname, int flags) +{ + return sys_unlinkat(dirfd, pathname, flags); +} diff --git a/sortix/include/sortix/fcntl.h b/sortix/include/sortix/fcntl.h index b87f3a57..f86a93ec 100644 --- a/sortix/include/sortix/fcntl.h +++ b/sortix/include/sortix/fcntl.h @@ -55,6 +55,7 @@ __BEGIN_DECLS #define F_GETFL 3 #define AT_FDCWD (-100) +#define AT_REMOVEDIR (1<<0) __END_DECLS diff --git a/sortix/include/sortix/syscallnum.h b/sortix/include/sortix/syscallnum.h index 08fc24e1..11578284 100644 --- a/sortix/include/sortix/syscallnum.h +++ b/sortix/include/sortix/syscallnum.h @@ -82,6 +82,7 @@ #define SYSCALL_CHOWN 58 #define SYSCALL_LINK 59 #define SYSCALL_DUP2 60 -#define SYSCALL_MAX_NUM 61 /* index of highest constant + 1 */ +#define SYSCALL_UNLINKAT 61 +#define SYSCALL_MAX_NUM 62 /* index of highest constant + 1 */ #endif diff --git a/sortix/io.cpp b/sortix/io.cpp index 7a5ce2ab..3d32c2da 100644 --- a/sortix/io.cpp +++ b/sortix/io.cpp @@ -171,20 +171,28 @@ static int sys_access(const char* path, int /*mode*/) return desc ? 0 : -1; } -static int sys_unlink(const char* path) +static int sys_unlinkat(int dirfd, const char* path, int flags) { char* pathcopy = GetStringFromUser(path); if ( !pathcopy ) return -1; ioctx_t ctx; SetupUserIOCtx(&ctx); const char* relpath = pathcopy; - Ref from = PrepareLookup(&relpath); - int ret = from->unlink(&ctx, relpath); + Ref from = PrepareLookup(&relpath, dirfd); + if ( !from ) { delete[] pathcopy; return -1; } + int ret; + if ( flags & AT_REMOVEDIR ) + ret = from->rmdir(&ctx, relpath); + else + ret = from->unlink(&ctx, relpath); delete[] pathcopy; return ret; } -// TODO: unlinkat +static int sys_unlink(const char* path) +{ + return sys_unlinkat(AT_FDCWD, path, 0); +} static int sys_mkdir(const char* path, mode_t mode) { @@ -203,19 +211,9 @@ static int sys_mkdir(const char* path, mode_t mode) static int sys_rmdir(const char* path) { - char* pathcopy = GetStringFromUser(path); - if ( !pathcopy ) - return -1; - ioctx_t ctx; SetupUserIOCtx(&ctx); - const char* relpath = pathcopy; - Ref from = PrepareLookup(&relpath); - int ret = from->rmdir(&ctx, relpath); - delete[] pathcopy; - return ret; + return sys_unlinkat(AT_FDCWD, path, AT_REMOVEDIR); } -// TODO: unlinkat(AT_REMOVEDIR) - static int sys_truncate(const char* path, off_t length) { char* pathcopy = GetStringFromUser(path); @@ -451,6 +449,7 @@ void Init() Syscall::Register(SYSCALL_STAT, (void*) sys_stat); Syscall::Register(SYSCALL_TCGETWINSIZE, (void*) sys_tcgetwinsize); Syscall::Register(SYSCALL_TRUNCATE, (void*) sys_truncate); + Syscall::Register(SYSCALL_UNLINKAT, (void*) sys_unlinkat); Syscall::Register(SYSCALL_UNLINK, (void*) sys_unlink); Syscall::Register(SYSCALL_WRITE, (void*) sys_write); }