From 921deb6eeb104a1d2bd46781e7ebfa77076730b2 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Thu, 25 Oct 2012 15:43:53 +0200 Subject: [PATCH] Add linkat(2). --- libc/Makefile | 1 + libc/include/unistd.h | 2 +- libc/linkat.cpp | 37 ++++++++++++++++++++++++++++++ sortix/include/sortix/syscallnum.h | 3 ++- sortix/io.cpp | 19 ++++++++++++--- 5 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 libc/linkat.cpp diff --git a/libc/Makefile b/libc/Makefile index fc251f0d..fef266f7 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -167,6 +167,7 @@ ioleast.o \ isatty.o \ kernelinfo.o \ kill.o \ +linkat.o \ link.o \ localeconv.o \ lseek.o \ diff --git a/libc/include/unistd.h b/libc/include/unistd.h index d20b506e..f03ecb1f 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -110,7 +110,6 @@ pid_t getpgrp(void); pid_t getsid(pid_t); uid_t getuid(void); int lchown(const char*, uid_t, gid_t); -int linkat(int, const char*, int, const char*, int); int lockf(int, int, off_t); int nice(int); long pathconf(const char*, int); @@ -168,6 +167,7 @@ pid_t getpid(void); pid_t getppid(void); int isatty(int); int link(const char*, const char*); +int linkat(int, const char*, int, const char*, int); off_t lseek(int, off_t, int); int pipe(int [2]); ssize_t pread(int, void*, size_t, off_t); diff --git a/libc/linkat.cpp b/libc/linkat.cpp new file mode 100644 index 00000000..e55568b7 --- /dev/null +++ b/libc/linkat.cpp @@ -0,0 +1,37 @@ +/******************************************************************************* + + 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 . + + linkat.cpp + Give a new name to a file. + +*******************************************************************************/ + +#include + +#include +#include + +DEFN_SYSCALL5(int, sys_linkat, SYSCALL_LINKAT, int, const char*, int, const char*, int); + +extern "C" int linkat(int olddirfd, const char* oldpath, + int newdirfd, const char* newpath, + int flags) +{ + return sys_linkat(olddirfd, oldpath, newdirfd, newpath, flags); +} diff --git a/sortix/include/sortix/syscallnum.h b/sortix/include/sortix/syscallnum.h index 1a4da48a..23433514 100644 --- a/sortix/include/sortix/syscallnum.h +++ b/sortix/include/sortix/syscallnum.h @@ -91,6 +91,7 @@ #define SYSCALL_FCHOWN 67 #define SYSCALL_FCHMOD 68 #define SYSCALL_FCHMODAT 69 -#define SYSCALL_MAX_NUM 70 /* index of highest constant + 1 */ +#define SYSCALL_LINKAT 70 +#define SYSCALL_MAX_NUM 71 /* index of highest constant + 1 */ #endif diff --git a/sortix/io.cpp b/sortix/io.cpp index 04b3fe67..6da35eda 100644 --- a/sortix/io.cpp +++ b/sortix/io.cpp @@ -417,15 +417,21 @@ static int sys_chmod(const char* path, mode_t mode) return sys_fchmodat(AT_FDCWD, path, mode, 0); } -static int sys_link(const char* oldpath, const char* newpath) +static int sys_linkat(int olddirfd, const char* oldpath, + int newdirfd, const char* newpath, + int flags) { + if ( flags ) + return errno = ENOTSUP, -1; + ioctx_t ctx; SetupUserIOCtx(&ctx); char* newpathcopy = GetStringFromUser(newpath); if ( !newpathcopy ) return -1; const char* newrelpath = newpathcopy; - Ref newfrom(PrepareLookup(&newrelpath)); + Ref newfrom(PrepareLookup(&newrelpath, newdirfd)); + if ( !newfrom ) { delete[] newpathcopy; return -1; } char* final_elem; Ref dir = OpenDirContainingPath(&ctx, newfrom, newpathcopy, @@ -437,7 +443,8 @@ static int sys_link(const char* oldpath, const char* newpath) char* oldpathcopy = GetStringFromUser(oldpath); if ( !oldpathcopy ) { delete[] final_elem; return -1; } const char* oldrelpath = oldpathcopy; - Ref oldfrom(PrepareLookup(&oldrelpath)); + Ref oldfrom = PrepareLookup(&oldrelpath, olddirfd); + if ( !oldfrom ) { delete[] oldpathcopy; delete[] final_elem; return -1; } Ref file = oldfrom->open(&ctx, oldrelpath, O_RDONLY); delete[] oldpathcopy; @@ -448,6 +455,11 @@ static int sys_link(const char* oldpath, const char* newpath) return ret; } +static int sys_link(const char* oldpath, const char* newpath) +{ + return sys_linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0); +} + static int sys_settermmode(int fd, unsigned mode) { Ref desc = CurrentProcess()->GetDescriptor(fd); @@ -505,6 +517,7 @@ void Init() Syscall::Register(SYSCALL_FTRUNCATE, (void*) sys_ftruncate); Syscall::Register(SYSCALL_GETTERMMODE, (void*) sys_gettermmode); Syscall::Register(SYSCALL_ISATTY, (void*) sys_isatty); + Syscall::Register(SYSCALL_LINKAT, (void*) sys_linkat); Syscall::Register(SYSCALL_LINK, (void*) sys_link); Syscall::Register(SYSCALL_MKDIRAT, (void*) sys_mkdirat); Syscall::Register(SYSCALL_MKDIR, (void*) sys_mkdir);