From 5e9e003bb0a34dcaf63af5c79e3622af54882c18 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Fri, 2 Sep 2022 13:37:08 +0200 Subject: [PATCH] libc: warn on missing std*="" or 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 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 --- repos/libports/src/lib/libc/kernel.cc | 72 +++++++++++++++------------ 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/repos/libports/src/lib/libc/kernel.cc b/repos/libports/src/lib/libc/kernel.cc index 20e370c026..9c76ef8768 100644 --- a/repos/libports/src/lib/libc/kernel.cc +++ b/repos/libports/src/lib/libc/kernel.cc @@ -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()) {