Add readlink{,at}(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2013-03-19 20:18:15 +01:00
parent 9d3937fe9e
commit 729bfa3c32
7 changed files with 97 additions and 3 deletions

View File

@ -212,6 +212,8 @@ putc.o \
raise.o \
rand.o \
readdirents.o \
readlinkat.o \
readlink.o \
read.o \
realpath.o \
removeat.o \

View File

@ -111,8 +111,6 @@ int lockf(int, int, off_t);
int nice(int);
long pathconf(const char*, int);
int pause(void);
ssize_t readlink(const char* restrict, char* restrict, size_t);
ssize_t readlinkat(int, const char* restrict, char* restrict, size_t);
int setegid(gid_t);
int seteuid(uid_t);
int setgid(gid_t);
@ -170,6 +168,8 @@ off_t lseek(int, off_t, int);
int pipe(int [2]);
ssize_t pread(int, void*, size_t, off_t);
ssize_t pwrite(int, const void*, size_t, off_t);
ssize_t readlink(const char* restrict, char* restrict, size_t);
ssize_t readlinkat(int, const char* restrict, char* restrict, size_t);
ssize_t read(int, void*, size_t);
int rmdir(const char*);
unsigned sleep(unsigned);

32
libc/readlink.cpp Normal file
View File

@ -0,0 +1,32 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013.
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 <http://www.gnu.org/licenses/>.
readlink.cpp
Read contents of symbolic link.
*******************************************************************************/
#include <fcntl.h>
#include <unistd.h>
extern "C" ssize_t readlink(const char* restrict path, char* restrict buf,
size_t size)
{
return readlinkat(AT_FDCWD, path, buf, size);
}

37
libc/readlinkat.cpp Normal file
View File

@ -0,0 +1,37 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013.
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 <http://www.gnu.org/licenses/>.
readlinkat.cpp
Read contents of symbolic link.
*******************************************************************************/
#include <sys/syscall.h>
#include <fcntl.h>
#include <unistd.h>
DEFN_SYSCALL4(ssize_t, sys_readlinkat, SYSCALL_READLINKAT, int,
const char* restrict, char* restrict, size_t);
extern "C" ssize_t readlinkat(int dirfd, const char* restrict path,
char* restrict buf, size_t size)
{
return sys_readlinkat(dirfd, path, buf, size);
}

View File

@ -420,6 +420,8 @@ int Descriptor::rename_here(ioctx_t* ctx, Ref<Descriptor> from,
ssize_t Descriptor::readlink(ioctx_t* ctx, char* buf, size_t bufsize)
{
if ( (size_t) SSIZE_MAX < bufsize )
bufsize = (size_t) SSIZE_MAX;
return vnode->readlink(ctx, buf, bufsize);
}

View File

@ -95,6 +95,7 @@
#define SYSCALL_FSM_FSBIND 71
#define SYSCALL_PPOLL 72
#define SYSCALL_RENAMEAT 73
#define SYSCALL_MAX_NUM 74 /* index of highest constant + 1 */
#define SYSCALL_READLINKAT 74
#define SYSCALL_MAX_NUM 75 /* index of highest constant + 1 */
#endif

View File

@ -540,6 +540,25 @@ static int sys_renameat(int olddirfd, const char* oldpath,
return ret;
}
// TODO: This should probably be moved into user-space. It'd be nice if
// user-space could just open the symlink and read/write it like a regular file.
static ssize_t sys_readlinkat(int dirfd, const char* path, char* buf, size_t size)
{
char* pathcopy = GetStringFromUser(path);
if ( !pathcopy )
return -1;
ioctx_t ctx; SetupUserIOCtx(&ctx);
const char* relpath = pathcopy;
Ref<Descriptor> from = PrepareLookup(&relpath, dirfd);
if ( !from ) { delete[] pathcopy; return -1; }
// TODO: Open the symbolic link, instead of what it points to!
Ref<Descriptor> desc = from->open(&ctx, relpath, O_RDONLY);
delete[] pathcopy;
if ( !desc )
return -1;
return (int) desc->readlink(&ctx, buf, size);
}
void Init()
{
Syscall::Register(SYSCALL_ACCESS, (void*) sys_access);
@ -570,6 +589,7 @@ void Init()
Syscall::Register(SYSCALL_PREAD, (void*) sys_pread);
Syscall::Register(SYSCALL_PWRITE, (void*) sys_pwrite);
Syscall::Register(SYSCALL_READDIRENTS, (void*) sys_readdirents);
Syscall::Register(SYSCALL_READLINKAT, (void*) sys_readlinkat);
Syscall::Register(SYSCALL_READ, (void*) sys_read);
Syscall::Register(SYSCALL_RENAMEAT, (void*) sys_renameat);
Syscall::Register(SYSCALL_RMDIR, (void*) sys_rmdir);