Do not throw exceptions during with_libc
This commit is contained in:
parent
2c977bdc1e
commit
9bd6733f75
|
@ -11,6 +11,10 @@ const
|
|||
|
||||
const FsH = "<file_system_session/file_system_session.h>"
|
||||
|
||||
#[
|
||||
|
||||
# Cannot throw C++ exceptions from within Libc::with_libc
|
||||
|
||||
proc raiseInvalidHandle() {.noreturn, header: FsH,
|
||||
importcpp: "throw File_system::Invalid_handle()".}
|
||||
proc raiseInvalidName() {.noreturn, header: FsH,
|
||||
|
@ -20,17 +24,22 @@ proc raiseLookupFailed() {.noreturn, header: FsH,
|
|||
proc raisePermissionDenied() {.noreturn, header: FsH,
|
||||
importcpp: "throw File_system::Permission_denied()".}
|
||||
|
||||
template permissionsAssert(cond: bool) =
|
||||
if not cond: raisePermissionDenied()
|
||||
|
||||
template lookupAssert(cond: bool) =
|
||||
if not cond: raiseLookupFailed()
|
||||
]#
|
||||
|
||||
template assertInvalidHandle(cond: bool) =
|
||||
if not cond: return (not Handle(0))
|
||||
|
||||
template permissionsAssert(cond: bool) =
|
||||
if not cond: return (not Handle(0))
|
||||
|
||||
template validPathAssert(name: string) =
|
||||
if name[name.low] != '/' or name[name.high] == '/': raiseLookupFailed()
|
||||
if name[name.low] != '/' or name[name.high] == '/':
|
||||
return (not Handle(0))
|
||||
|
||||
template validNameAssert(name: string) =
|
||||
if name.contains '/': raiseInvalidName()
|
||||
if name.contains '/': return (not Handle(0))
|
||||
|
||||
type
|
||||
FsCapability {.
|
||||
|
@ -122,18 +131,17 @@ proc inode(node: Node): culong = node.path.toKey.culong
|
|||
|
||||
template fsRpc(session: SessionPtr; body: untyped) =
|
||||
try: body
|
||||
except KeyError:
|
||||
raiseLookupFailed()
|
||||
#except KeyError:
|
||||
# raiseLookupFailed()
|
||||
except:
|
||||
echo "failed, ", getCurrentExceptionMsg()
|
||||
raisePermissionDenied()
|
||||
|
||||
proc nodeProc(session: pointer; path: cstring): Handle {.exportc.} =
|
||||
let session = cast[SessionPtr](session)
|
||||
fsRpc session:
|
||||
result = session.nextId
|
||||
if path == "/":
|
||||
session.nodes[result] = Node(path: "", kind: dirNode)
|
||||
session.nodes[result] = Node(path: "/", kind: dirNode)
|
||||
else:
|
||||
var path = $path
|
||||
validPathAssert path
|
||||
|
@ -153,12 +161,13 @@ proc statusProc(state: pointer; handle: Handle): Status {.exportc.} =
|
|||
fsRpc session:
|
||||
var st: Status
|
||||
let node = session.nodes[handle]
|
||||
st.inode = node.inode
|
||||
st.inode = 0
|
||||
st.mode = DirMode
|
||||
if node.path != "":
|
||||
if node.path != "/":
|
||||
session.apply(node.path) do (id: BlobId; size: BiggestInt):
|
||||
st.size = (culonglong)size
|
||||
st.mode = FileMode
|
||||
st.inode = node.inode
|
||||
result = st
|
||||
|
||||
proc dirProc(state: pointer; path: cstring; create: cint): Handle {.exportc.} =
|
||||
|
@ -173,7 +182,7 @@ proc dirProc(state: pointer; path: cstring; create: cint): Handle {.exportc.} =
|
|||
validPathAssert path
|
||||
path = path.strip(chars={'/'})
|
||||
if session.fsSet.contains path:
|
||||
raiseLookupFailed()
|
||||
return (not Handle(0))
|
||||
n = Node(path: path, kind: dirNode)
|
||||
result = session.nextId
|
||||
session.nodes[result] = n
|
||||
|
@ -186,8 +195,7 @@ proc fileProc(state: pointer; dirH: Handle; name: cstring; mode: cuint; create:
|
|||
validNameAssert name
|
||||
var n: Node
|
||||
let dir = session.nodes[dirH]
|
||||
if dir.kind != dirNode:
|
||||
raiseInvalidHandle()
|
||||
assertInvalidHandle(dir.kind == dirNode)
|
||||
let path = if dir.path == "": name else: dir.path & "/" & name
|
||||
var success = false
|
||||
session.apply(path) do (id: BlobId; size: BiggestInt):
|
||||
|
@ -195,31 +203,31 @@ proc fileProc(state: pointer; dirH: Handle; name: cstring; mode: cuint; create:
|
|||
n = Node(path: path, kind: fileNode, id: id, size: size, stream: stream)
|
||||
success = true
|
||||
if not success:
|
||||
raiseLookupFailed()
|
||||
return (not Handle(0))
|
||||
result = session.nextId
|
||||
session.nodes[result] = n
|
||||
|
||||
proc closeProc(state: pointer; h: Handle) {.exportc.} =
|
||||
let session = cast[ptr SessionObj](state)
|
||||
fsRpc session:
|
||||
let n = session.nodes[h]
|
||||
session.nodes.del h
|
||||
case n.kind
|
||||
of fileNode:
|
||||
close n.stream
|
||||
else:
|
||||
discard
|
||||
var n: Node
|
||||
if session.nodes.take(h, n):
|
||||
case n.kind
|
||||
of fileNode:
|
||||
close n.stream
|
||||
else:
|
||||
discard
|
||||
|
||||
proc unlinkProc(state: pointer; dirH: Handle; name: cstring) {.exportc.} =
|
||||
raisePermissionDenied()
|
||||
discard
|
||||
|
||||
proc truncateProc(state: pointer; file: Handle, size: cuint) {.exportc.} =
|
||||
raisePermissionDenied()
|
||||
discard
|
||||
|
||||
proc moveProc(state: pointer;
|
||||
from_dir: Handle; from_name: cstring;
|
||||
to_dir: Handle; to_name: cstring) {.exportc.} =
|
||||
raisePermissionDenied()
|
||||
discard
|
||||
|
||||
proc processPacket(session: SessionRef; pkt: var FsPacket) =
|
||||
## Process a File_system packet from the client.
|
||||
|
@ -280,7 +288,7 @@ componentConstructHook = proc(env: GenodeEnv) =
|
|||
|
||||
proc createSession(env: GenodeEnv; store: BlobStore; id: ServerId; label: string; setId: SetId; txBufSize: int) =
|
||||
let
|
||||
fsSet = store.loadSet(setId)
|
||||
fsSet = store.load setId
|
||||
session = env.newSession(store, label, setId, fsSet, txBufSize)
|
||||
cap = env.ep.manage session
|
||||
sessions[id] = session
|
||||
|
@ -351,7 +359,7 @@ componentConstructHook = proc(env: GenodeEnv) =
|
|||
idStr = pAttrs["root"]
|
||||
policySetId = toSetId idStr
|
||||
if session.fsSetId != policySetId:
|
||||
let newSet = store.loadSet policySetId
|
||||
let newSet = store.load policySetId
|
||||
session.fsSet = newSet
|
||||
session.fsSetId = policySetId
|
||||
echo idStr, " is new root of ", session.label
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 Genode Labs GmbH
|
||||
* Copyright (C) 2017-2019 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
|
@ -52,23 +52,51 @@ struct File_system::SessionComponentBase : File_system::Session_rpc_object
|
|||
** File_system session interface **
|
||||
***********************************/
|
||||
|
||||
Node_handle node(File_system::Path const &path) override {
|
||||
return Node_handle{ nodeProc(state, path.string()) }; }
|
||||
Node_handle node(File_system::Path const &path) override
|
||||
{
|
||||
Node_handle handle { ~0 };
|
||||
Libc::with_libc([&] {
|
||||
handle = Node_handle{ nodeProc(state, path.string()) }; });
|
||||
return handle;
|
||||
}
|
||||
|
||||
Dir_handle dir(File_system::Path const &path, bool create) override {
|
||||
return Dir_handle{ dirProc(state, path.string(), create) }; }
|
||||
Dir_handle dir(File_system::Path const &path, bool create) override
|
||||
{
|
||||
Dir_handle handle { ~0 };
|
||||
Libc::with_libc([&] {
|
||||
handle = Dir_handle{ dirProc(state, path.string(), create) }; });
|
||||
if (handle.value == ~0)
|
||||
throw Lookup_failed();
|
||||
return handle;
|
||||
}
|
||||
|
||||
File_handle file(Dir_handle dir, Name const &name, Mode mode, bool create) override {
|
||||
return File_handle{ fileProc(state, dir.value, name.string(), unsigned(mode), create) }; }
|
||||
File_handle file(Dir_handle dir, Name const &name, Mode mode, bool create) override
|
||||
{
|
||||
File_handle handle { ~0 };
|
||||
Libc::with_libc([&] {
|
||||
handle = File_handle{ fileProc(state, dir.value, name.string(), unsigned(mode), create) }; });
|
||||
if (handle.value == ~0)
|
||||
throw Lookup_failed();
|
||||
return handle;
|
||||
}
|
||||
|
||||
Symlink_handle symlink(Dir_handle, Name const &name, bool create) override {
|
||||
throw Lookup_failed(); }
|
||||
|
||||
void close(Node_handle handle) override {
|
||||
closeProc(state, handle.value); }
|
||||
void close(Node_handle handle) override
|
||||
{
|
||||
Libc::with_libc([&] () { closeProc(state, handle.value); });
|
||||
}
|
||||
|
||||
Status status(Node_handle handle) override {
|
||||
return statusProc(state, handle.value); }
|
||||
Status status(Node_handle handle) override
|
||||
{
|
||||
Status stat { };
|
||||
Libc::with_libc([&] () {
|
||||
stat = statusProc(state, handle.value); });
|
||||
if (stat.inode == 0)
|
||||
throw Invalid_handle();
|
||||
return stat;
|
||||
}
|
||||
|
||||
void control(Node_handle h, Control) override { }
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user