mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-13 22:23:45 +00:00
lib/vfs: new permissions errors
New errors STAT_ERR_NO_PERM, DIRENT_ERR_NO_PERM, and READLINK_NO_PERM to distinguish lookup errors from permissions or other errors. Issue #1751
This commit is contained in:
parent
14ca140135
commit
b8e52189d5
@ -385,6 +385,7 @@ int Libc::Vfs_plugin::stat(char const *path, struct stat *buf)
|
||||
|
||||
switch (_root_dir.stat(path, stat)) {
|
||||
case Result::STAT_ERR_NO_ENTRY: errno = ENOENT; return -1;
|
||||
case Result::STAT_ERR_NO_PERM: errno = EACCES; return -1;
|
||||
case Result::STAT_OK: break;
|
||||
}
|
||||
|
||||
@ -459,7 +460,8 @@ ssize_t Libc::Vfs_plugin::getdirentries(Libc::File_descriptor *fd, char *buf,
|
||||
unsigned const index = handle->seek() / sizeof(Vfs::Directory_service::Dirent);
|
||||
|
||||
switch (handle->ds().dirent(fd->fd_path, index, dirent_out)) {
|
||||
case Result::DIRENT_ERR_INVALID_PATH: /* XXX errno */ return -1;
|
||||
case Result::DIRENT_ERR_INVALID_PATH: errno = ENOENT; return -1;
|
||||
case Result::DIRENT_ERR_NO_PERM: errno = EACCES; return -1;
|
||||
case Result::DIRENT_OK: break;
|
||||
}
|
||||
|
||||
@ -745,6 +747,7 @@ ssize_t Libc::Vfs_plugin::readlink(const char *path, char *buf, size_t buf_size)
|
||||
|
||||
switch (_root_dir.readlink(path, buf, buf_size, out_len)) {
|
||||
case Result::READLINK_ERR_NO_ENTRY: errno = ENOENT; return -1;
|
||||
case Result::READLINK_ERR_NO_PERM: errno = EACCES; return -1;
|
||||
case Result::READLINK_OK: break;
|
||||
};
|
||||
|
||||
|
@ -94,7 +94,8 @@ struct Vfs::Directory_service
|
||||
unsigned device;
|
||||
};
|
||||
|
||||
enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS, STAT_OK };
|
||||
enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS,
|
||||
STAT_ERR_NO_PERM, STAT_OK };
|
||||
|
||||
virtual Stat_result stat(char const *path, Stat &) = 0;
|
||||
|
||||
@ -103,7 +104,7 @@ struct Vfs::Directory_service
|
||||
** Dirent **
|
||||
************/
|
||||
|
||||
enum Dirent_result { DIRENT_ERR_INVALID_PATH, DIRENT_OK };
|
||||
enum Dirent_result { DIRENT_ERR_INVALID_PATH, DIRENT_ERR_NO_PERM, DIRENT_OK };
|
||||
|
||||
enum { DIRENT_MAX_NAME_LEN = 128 };
|
||||
|
||||
@ -141,7 +142,7 @@ struct Vfs::Directory_service
|
||||
** Readlink **
|
||||
**************/
|
||||
|
||||
enum Readlink_result { READLINK_ERR_NO_ENTRY, READLINK_OK };
|
||||
enum Readlink_result { READLINK_ERR_NO_ENTRY, READLINK_ERR_NO_PERM, READLINK_OK };
|
||||
|
||||
virtual Readlink_result readlink(char const *path, char *buf,
|
||||
file_size buf_size, file_size &out_len) = 0;
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -1087,10 +1087,10 @@ namespace {
|
||||
if (verbose)
|
||||
PWRN("stat syscall failed for path \"%s\"", path);
|
||||
switch (sysio()->error.stat) {
|
||||
case Vfs::Directory_service::STAT_OK: /* never reached */
|
||||
case Vfs::Directory_service::STAT_ERR_NO_ENTRY: errno = ENOENT; break;
|
||||
case Vfs::Directory_service::STAT_ERR_NO_ENTRY: errno = ENOENT; return -1;
|
||||
case Vfs::Directory_service::STAT_ERR_NO_PERM: errno = EACCES; return -1;
|
||||
case Vfs::Directory_service::STAT_OK: break; /* never reached */
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
_sysio_to_stat_struct(sysio(), buf);
|
||||
@ -1165,9 +1165,16 @@ namespace {
|
||||
Genode::strncpy(sysio()->symlink_in.oldpath, oldpath, sizeof(sysio()->symlink_in.oldpath));
|
||||
Genode::strncpy(sysio()->symlink_in.newpath, newpath, sizeof(sysio()->symlink_in.newpath));
|
||||
if (!noux_syscall(Noux::Session::SYSCALL_SYMLINK)) {
|
||||
PERR("symlink error");
|
||||
/* XXX set errno */
|
||||
return -1;
|
||||
PWRN("symlink syscall failed for path \"%s\"", newpath);
|
||||
typedef Vfs::Directory_service::Symlink_result Result;
|
||||
switch (sysio()->error.symlink) {
|
||||
case Result::SYMLINK_ERR_NO_ENTRY: errno = ENOENT; return -1;
|
||||
case Result::SYMLINK_ERR_EXISTS: errno = EEXIST; return -1;
|
||||
case Result::SYMLINK_ERR_NO_SPACE: errno = ENOSPC; return -1;
|
||||
case Result::SYMLINK_ERR_NO_PERM: errno = EPERM; return -1;
|
||||
case Result::SYMLINK_ERR_NAME_TOO_LONG: errno = ENAMETOOLONG; return -1;
|
||||
case Result::SYMLINK_OK: break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1707,9 +1714,13 @@ namespace {
|
||||
sysio()->readlink_in.bufsiz = bufsiz;
|
||||
|
||||
if (!noux_syscall(Noux::Session::SYSCALL_READLINK)) {
|
||||
PWRN("readlink syscall failed for \"%s\"", path);
|
||||
/* XXX set errno */
|
||||
return -1;
|
||||
PWRN("readlink syscall failed for path \"%s\"", path);
|
||||
typedef Vfs::Directory_service::Readlink_result Result;
|
||||
switch (sysio()->error.readlink) {
|
||||
case Result::READLINK_ERR_NO_ENTRY: errno = ENOENT; return -1;
|
||||
case Result::READLINK_ERR_NO_PERM: errno = EPERM; return -1;
|
||||
case Result::READLINK_OK: break;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t size = Genode::min((size_t)sysio()->readlink_out.count, bufsiz);
|
||||
|
Loading…
x
Reference in New Issue
Block a user