mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-29 15:44:02 +00:00
parent
7f1adbea46
commit
2eae70d3cd
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 Genode Labs GmbH
|
||||
* Copyright (C) 2017-2024 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.
|
||||
@ -259,6 +259,16 @@ struct Genode::Directory : Noncopyable, Interface
|
||||
return stat.type == Vfs::Node_type::DIRECTORY;
|
||||
}
|
||||
|
||||
bool symlink_exists(Path const &rel_path) const
|
||||
{
|
||||
Vfs::Directory_service::Stat stat { };
|
||||
|
||||
if (_stat(rel_path, stat) != Vfs::Directory_service::STAT_OK)
|
||||
return false;
|
||||
|
||||
return stat.type == Vfs::Node_type::SYMLINK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return size of file at specified directory-relative path
|
||||
*
|
||||
@ -328,6 +338,65 @@ struct Genode::Directory : Noncopyable, Interface
|
||||
return Path(Genode::Cstring(buf, (size_t)out_count));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to create symlink
|
||||
*
|
||||
* This operation may fail. Its success can be checked by calling
|
||||
* 'symlink_exists'.
|
||||
*/
|
||||
void create_symlink(Path const &rel_path, Path const &target)
|
||||
{
|
||||
using namespace Vfs;
|
||||
Vfs_handle *link_handle;
|
||||
|
||||
auto openlink_result = _nonconst_fs().openlink(
|
||||
join(_path, rel_path).string(),
|
||||
true, &link_handle, _alloc);
|
||||
|
||||
using Openlink_result = Directory_service::Openlink_result;
|
||||
|
||||
if (openlink_result == Openlink_result::OPENLINK_ERR_NODE_ALREADY_EXISTS)
|
||||
openlink_result = _fs.openlink(
|
||||
join(_path, rel_path).string(),
|
||||
false, &link_handle, _alloc);
|
||||
|
||||
if (openlink_result != Openlink_result::OPENLINK_OK)
|
||||
return;
|
||||
|
||||
Vfs_handle::Guard guard(link_handle);
|
||||
|
||||
Const_byte_range_ptr const src { target.string(), target.length() };
|
||||
|
||||
size_t out_count = 0;
|
||||
link_handle->fs().write(link_handle, src, out_count);
|
||||
|
||||
if (out_count < src.num_bytes) {
|
||||
unlink(rel_path);
|
||||
return;
|
||||
}
|
||||
|
||||
/* sync before the handle gets closed */
|
||||
|
||||
while (!link_handle->fs().queue_sync(link_handle))
|
||||
_io.commit_and_wait();
|
||||
|
||||
File_io_service::Sync_result result;
|
||||
|
||||
for (;;) {
|
||||
result = link_handle->fs().complete_sync(link_handle);
|
||||
|
||||
if (result != File_io_service::SYNC_QUEUED)
|
||||
break;
|
||||
|
||||
_io.commit_and_wait();
|
||||
};
|
||||
|
||||
if (result != File_io_service::SYNC_OK) {
|
||||
unlink(rel_path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void unlink(Path const &rel_path)
|
||||
{
|
||||
_fs.unlink(join(_path, rel_path).string());
|
||||
|
Loading…
x
Reference in New Issue
Block a user