This commit removes DeprecatedString's "null" state, and replaces all
its users with one of the following:
- A normal, empty DeprecatedString
- Optional<DeprecatedString>
Note that null states of DeprecatedFlyString/StringView/etc are *not*
affected by this commit. However, DeprecatedString::empty() is now
considered equal to a null StringView.
Without using PATH_MAX :^)
To read a symlink, we can just open its file with O_NOLINK and read its
contents. To get the executable path, we could read the /proc/self/exe
link like the Linux version does; but that relies on procfs being
mounted. Instead, we could do what procfs itself does to get the path:
ask the proc server about it.
On FreeBSD and GNU/Hurd, SHM_ANON is a nice way to create anonymous
files using the usual shm_open() API. This is a lot like the fallback
shm_open() branch that follows, except we don't have to fool around
with choosing a unique name (with retrying) and unlinking the file
afterwards; it just does the right thing. Isn't this nice?
This is based on Jakt::File::current_executable_path() and all the other
sources I looked at to figure out the per-platform way to do this. My
goodness, every platform has its own bespoke way.
This is a preparation before we can create a usable mechanism to use
filesystem-specific mount flags.
To keep some compatibility with userland code, LibC and LibCore mount
functions are kept being usable, but now instead of doing an "atomic"
syscall, they do multiple syscalls to perform the complete procedure of
mounting a filesystem.
The FileBackedFileSystem IntrusiveList in the VFS code is now changed to
be protected by a Mutex, because when we mount a new filesystem, we need
to check if a filesystem is already created for a given source_fd so we
do a scan for that OpenFileDescription in that list. If we fail to find
an already-created filesystem we create a new one and register it in the
list if we successfully mounted it. We use a Mutex because we might need
to initiate disk access during the filesystem creation, which will take
other mutexes in other parts of the kernel, therefore making it not
possible to take a spinlock while doing this.
Calling `from_utf8` with a DeprecatedString will hide the fact that we
have a DeprecatedString, while using `from_deprecated_string` with a
StringView will silently and needlessly allocate a DeprecatedString,
so let's forbid that.
When called with `SearchInPath::Yes`, calls to `Core::System::exec()`
would fail. The value returned from
`resolve_executable_from_environment()` was assigned to a StringView,
but the original reference was not kept, causing the StringView to
appear empty.
DeprecatedFile doesn't properly handle I/O or OOM errors, and only
provides a rudimentary interface to reasonably handle it. We have long
since learned how to do it "properly" with ErrorOr<> and similar
interfaces. See also d43a7eae54.
Note that this leaves behind an invocation to DeprecatedFile in
Ladybird/AndroidPlatform.cpp. However, that part of the system has
compilation errors since at least January, and will get removed or
rewritten as part of issue #19085. Let's not wait for this Android port
to remove this deprecated API.
`Core::System::fstatat()` is similar to our standard `Core::System`
wrappers.
`Core::Directory::stat(relative_path, flags)` is a convenience method if
you already have a Directory, to stat a file relative to it.
These 2 are an actual separate types of syscalls, so let's stop using
special flags for bind mounting or re-mounting and instead let userspace
calling directly for this kind of actions.
This is quite useful for userspace applications that can't cope with the
restriction, but it's still useful to impose other non-configurable
restrictions by using jails.
This was called from LibCore and passed raw StringView data that may
not be null terminated, then incorrectly passed those strings to
getenv() and also tried printing them with just the %s format
specifier.
`OwnPtrWithCustomDeleter` was a decorator which provided the ability
to add a custom deleter to `OwnPtr` by wrapping and taking the deleter
as a run-time argument to the constructor. This solution means that no
additional space is needed for the `OwnPtr` because it doesn't need to
store a pointer to the deleter, but comes at the cost of having an
extra type that stores a pointer for every instance.
This logic is moved directly into `OwnPtr` by adding a template
argument that is defaulted to the default deleter for the type. This
means that the type itself stores the pointer to the deleter instead
of every instance and adds some type safety by encoding the deleter in
the type itself instead of taking a run-time argument.
Rather than maintaining a list of #ifdef guards to check systems that do
not provide the reentrant version of getgrent, we can use C++ concepts
to let the compiler perform this check for us.
While we're at it, we can also provide this wrapper as fallible to let
the caller TRY calling it.
Rather than maintaining a list of #ifdef guards to check systems that do
not provide the reentrant version of getpwent, we can use C++ concepts
to let the compiler perform this check for us.
While we're at it, we can also provide this wrapper as fallible to let
the caller TRY calling it.