From 5915e2cd1479e4fcd87ef618bee78dc67b2801f7 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Wed, 13 May 2015 17:48:53 +0200 Subject: [PATCH] Add closefrom(2). --- kernel/dtable.cpp | 31 ++++++++++++++++++++--- kernel/include/sortix/kernel/dtable.h | 4 ++- kernel/include/sortix/kernel/syscall.h | 1 + kernel/include/sortix/syscall.h | 5 ++-- kernel/io.cpp | 9 +++++++ kernel/syscall.cpp | 3 ++- libc/Makefile | 1 + libc/include/unistd.h | 3 ++- libc/unistd/closefrom.cpp | 34 ++++++++++++++++++++++++++ 9 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 libc/unistd/closefrom.cpp diff --git a/kernel/dtable.cpp b/kernel/dtable.cpp index f707426d..4eeb6037 100644 --- a/kernel/dtable.cpp +++ b/kernel/dtable.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015. This file is part of Sortix. @@ -181,9 +181,8 @@ int DescriptorTable::Copy(int from, int to, int flags) return to; } -Ref DescriptorTable::FreeKeep(int index) +Ref DescriptorTable::FreeKeepInternal(int index) { - ScopedLock lock(&dtablelock); if ( !IsGoodEntry(index) ) { errno = EBADF; return Ref(NULL); } Ref ret = entries[index].desc; entries[index].desc.Reset(); @@ -192,6 +191,12 @@ Ref DescriptorTable::FreeKeep(int index) return ret; } +Ref DescriptorTable::FreeKeep(int index) +{ + ScopedLock lock(&dtablelock); + return FreeKeepInternal(index); +} + void DescriptorTable::Free(int index) { FreeKeep(index); @@ -273,4 +278,24 @@ int DescriptorTable::Next(int index) return index; } +int DescriptorTable::CloseFrom(int index) +{ + if ( index < 0 ) + return errno = EBADF, -1; + + ScopedLock lock(&dtablelock); + + bool any = false; + + while ( index < numentries ) + { + if ( !IsGoodEntry(index) ) + continue; + FreeKeepInternal(index); + any = true; + } + + return any ? 0 : (errno = EBADF, -1); +} + } // namespace Sortix diff --git a/kernel/include/sortix/kernel/dtable.h b/kernel/include/sortix/kernel/dtable.h index 70d3be40..b0868832 100644 --- a/kernel/include/sortix/kernel/dtable.h +++ b/kernel/include/sortix/kernel/dtable.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015. This file is part of Sortix. @@ -54,12 +54,14 @@ public: int GetFlags(int index); int Previous(int index); int Next(int index); + int CloseFrom(int index); private: void Reset(); // Hey, reference counted. Don't call this. bool IsGoodEntry(int i); bool Enlargen(int atleast); int AllocateInternal(Ref desc, int flags, int min_index); + Ref FreeKeepInternal(int index); private: kthread_mutex_t dtablelock; diff --git a/kernel/include/sortix/kernel/syscall.h b/kernel/include/sortix/kernel/syscall.h index 1b846e3d..799a7bf1 100644 --- a/kernel/include/sortix/kernel/syscall.h +++ b/kernel/include/sortix/kernel/syscall.h @@ -60,6 +60,7 @@ int sys_clock_gettimeres(clockid_t, struct timespec*, struct timespec*); int sys_clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*); int sys_clock_settimeres(clockid_t, const struct timespec*, const struct timespec*); int sys_close(int); +int sys_closefrom(int); int sys_connect(int, const void*, size_t); int sys_dispmsg_issue(void*, size_t); int sys_dup(int); diff --git a/kernel/include/sortix/syscall.h b/kernel/include/sortix/syscall.h index 7832700b..234fcc98 100644 --- a/kernel/include/sortix/syscall.h +++ b/kernel/include/sortix/syscall.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015. This file is part of Sortix. @@ -177,6 +177,7 @@ #define SYSCALL_SETHOSTNAME 149 #define SYSCALL_UNMOUNTAT 150 #define SYSCALL_FSM_MOUNTAT 151 -#define SYSCALL_MAX_NUM 152 /* index of highest constant + 1 */ +#define SYSCALL_CLOSEFROM 152 +#define SYSCALL_MAX_NUM 153 /* index of highest constant + 1 */ #endif diff --git a/kernel/io.cpp b/kernel/io.cpp index 29337a41..d07c3ca6 100644 --- a/kernel/io.cpp +++ b/kernel/io.cpp @@ -126,6 +126,15 @@ int sys_close(int fd) return desc->sync(&ctx); } +int sys_closefrom(int fd) +{ + ioctx_t ctx; SetupUserIOCtx(&ctx); + Ref dtable = CurrentProcess()->GetDTable(); + int ret = dtable->CloseFrom(fd); + dtable.Reset(); + return ret; +} + int sys_dup(int fd) { Ref dtable = CurrentProcess()->GetDTable(); diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp index 5085bdae..2895cd54 100644 --- a/kernel/syscall.cpp +++ b/kernel/syscall.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015. This file is part of Sortix. @@ -187,6 +187,7 @@ void* syscall_list[SYSCALL_MAX_NUM + 1] = [SYSCALL_SETHOSTNAME] = (void*) sys_sethostname, [SYSCALL_UNMOUNTAT] = (void*) sys_unmountat, [SYSCALL_FSM_MOUNTAT] = (void*) sys_fsm_mountat, + [SYSCALL_CLOSEFROM] = (void*) sys_closefrom, [SYSCALL_MAX_NUM] = (void*) sys_bad_syscall, }; } // extern "C" diff --git a/libc/Makefile b/libc/Makefile index 5e33918e..13078da9 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -553,6 +553,7 @@ unistd/alarm.o \ unistd/chdir.o \ unistd/chown.o \ unistd/chroot.o \ +unistd/closefrom.o \ unistd/close.o \ unistd/confstr.o \ unistd/dup2.o \ diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 6aa4b586..7d62398d 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015. This file is part of the Sortix C Library. @@ -545,6 +545,7 @@ size_t getpagesize(void); /* Functions copied from elsewhere. */ #if __USE_SORTIX int chroot(const char*); +int closefrom(int); int dup3(int, int, int); int execvpe(const char*, char* const [], char* const []); char* get_current_dir_name(void); diff --git a/libc/unistd/closefrom.cpp b/libc/unistd/closefrom.cpp new file mode 100644 index 00000000..9c31716f --- /dev/null +++ b/libc/unistd/closefrom.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2015. + + 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 . + + unistd/closefrom.cpp + Closes all file descriptors from a value and upwards. + +*******************************************************************************/ + +#include + +#include + +DEFN_SYSCALL1(int, sys_closefrom, SYSCALL_CLOSEFROM, int); + +extern "C" int closefrom(int fd) +{ + return sys_closefrom(fd); +}