libc: warn on missing std*="" or <fd path=""> dirs

The libc kernel used to end up in an uncaught exception if one of the
directories in the paths given through stdin/stdout/stderr or <fd path=""> was
missing. The resulting error didn't point the user to the presumably simple
configuration issue of his scenario in any way and killed the affected
component.

With this commit, the libc kernel prints a descriptive warning instead and
simply continues to run the component with the corresponding file descriptor
missing. At least in case of stdin/stdout/stderr, the libc deals gracefully
with this approach.

Ref #4218
This commit is contained in:
Martin Stein 2022-09-02 13:37:08 +02:00 committed by Norman Feske
parent 5b25060730
commit 5e9e003bb0

View File

@ -176,43 +176,51 @@ void Libc::Kernel::_init_file_descriptors()
if (!node.has_attribute(attr))
return;
Absolute_path const path {
resolve_absolute_path(node.attribute_value(attr, Path())) };
Path const attr_value { node.attribute_value(attr, Path()) };
try {
Absolute_path const path { resolve_absolute_path(attr_value) };
struct stat out_stat { };
if (_vfs.stat_from_kernel(path.string(), &out_stat) != 0)
return;
struct stat out_stat { };
if (_vfs.stat_from_kernel(path.string(), &out_stat) != 0)
return;
File_descriptor *fd = _vfs.open_from_kernel(path.string(), flags, libc_fd);
if (!fd)
return;
File_descriptor *fd =
_vfs.open_from_kernel(path.string(), flags, libc_fd);
if (fd->libc_fd != libc_fd) {
error("could not allocate fd ",libc_fd," for ",path,", "
"got fd ",fd->libc_fd);
_vfs.close_from_kernel(fd);
if (!fd)
return;
if (fd->libc_fd != libc_fd) {
error("could not allocate fd ",libc_fd," for ",path,", "
"got fd ",fd->libc_fd);
_vfs.close_from_kernel(fd);
return;
}
fd->cloexec = node.attribute_value("cloexec", false);
/*
* We need to manually register the path. Normally this is done
* by '_open'. But we call the local 'open' function directly
* because we want to explicitly specify the libc fd ID.
*/
if (fd->fd_path)
warning("may leak former FD path memory");
{
char *dst = (char *)_heap.alloc(path.max_len());
copy_cstring(dst, path.string(), path.max_len());
fd->fd_path = dst;
}
::off_t const seek = node.attribute_value("seek", 0ULL);
if (seek)
_vfs.lseek_from_kernel(fd, seek);
} catch (Symlink_resolve_error) {
warning("failed to resolve ", attr_value);
return;
}
fd->cloexec = node.attribute_value("cloexec", false);
/*
* We need to manually register the path. Normally this is done
* by '_open'. But we call the local 'open' function directly
* because we want to explicitly specify the libc fd ID.
*/
if (fd->fd_path)
warning("may leak former FD path memory");
{
char *dst = (char *)_heap.alloc(path.max_len());
copy_cstring(dst, path.string(), path.max_len());
fd->fd_path = dst;
}
::off_t const seek = node.attribute_value("seek", 0ULL);
if (seek)
_vfs.lseek_from_kernel(fd, seek);
};
if (_vfs.root_dir_has_dirents()) {