If it is default-initialized to 0, mktime will assume that DST is not in
effect for the specified time. Setting it to a negative value instructs
mktime to determine for itself whether DST is in effect.
- We were using primitive versions of mkstemp and mkdtemp, they have
been converted to use LibCore::System.
- If an error occurred whilst creating a temporary directory or file, it
was thrown and the program would crash. Now, we use ErrorOr<T> so that
the caller can handle the error accordingly
- The `Type` enumeration has been made private, and `create_temp` has
been "split" (although rewritten) into create_temp_directory and
create_temp_file. The old pattern of TempFile::create_temp(Type::File)
felt a bit awkward, and TempFile::create_temp_file() feels a bit nicer
to use! :^)
Once the Core::Filesystem PR is merged (#17789), it would be better for
this helper to be merged in with that. But until then, this is a nice
improvement.
Similar to POSIX read, the basic read and write functions of AK::Stream
do not have a lower limit of how much data they read or write (apart
from "none at all").
Rename the functions to "read some [data]" and "write some [data]" (with
"data" being omitted, since everything here is reading and writing data)
to make them sufficiently distinct from the functions that ensure to
use the entire buffer (which should be the go-to function for most
usages).
No functional changes, just a lot of new FIXMEs.
In this context, the promises are considered "jobs", and such jobs
depend in some way on the event loop. Therefore, they can be added to
the event loop, and the event loop will cancel all of its pending jobs
when it ends.
This class had slightly confusing semantics and the added weirdness
doesn't seem worth it just so we can say "." instead of "->" when
iterating over a vector of NNRPs.
This patch replaces NonnullRefPtrVector<T> with Vector<NNRP<T>>.
`Core::Directory::for_each_entry()` takes a callback which is passed the
DirectoryEntry and the parent Directory. It returns any error from
creating the iterator, iterating the entries, or returned from the
callback.
As a simple example, this:
```c++
Core::DirIterator piece_set_iterator { "/res/icons/chess/sets/",
Core::DirIterator::SkipParentAndBaseDir };
while (piece_set_iterator.has_next())
m_piece_sets.append(piece_set_iterator.next_path());
```
becomes this:
```c++
TRY(Core::Directory::for_each_entry("/res/icons/chess/sets/"sv,
Core::DirIterator::SkipParentAndBaseDir,
[&](auto const& entry, auto&) -> ErrorOr<IterationDecision> {
TRY(m_piece_sets.try_append(entry.name));
return IterationDecision::Continue;
}));
```
`Directory::path()` returning `ErrorOr` makes it awkward to use, and all
current users create a Directory with a path. If we find we need
pathless directories later, we can come up with a clever solution
then. :^)
This also removes DirIterator::error_string(), since the same strerror()
string will be included when you print the Error itself. Except in `ls`
which is still using fprintf() for now.
Our `find` utility makes use of the `dirent::d_type` field for filtering
results, which `Core::DirIterator` didn't expose. So, now it does. :^)
We now store the name and type of the entry as the "next" value instead
of just the name. The type is exposed as a `DirectoryEntry::Type`
instead of a `DT_FOO` constant, so that we're not tied to posixy
systems, and because proper enums are nice. :^)
This is not guaranteed to always work correctly as ArgsParser deals in
StringViews and might have a non-properly-null-terminated string as a
value. As a bonus, using StringView (and DeprecatedString where
necessary) leads to nicer looking code too :^)
This commit moves the implementation of getopt into AK, and converts its
API to understand and use StringView instead of char*.
Everything else is caught in the crossfire of making
Option::accept_value() take a StringView instead of a char const*.
With this, we must now pass a Span<StringView> to ArgsParser::parse(),
applications using LibMain are unaffected, but anything not using that
or taking its own argc/argv has to construct a Vector<StringView> for
this method.
This currently allocates in .parse(), but that's better than making the
caller do the exact same before passing us the values.
Note that this is only temporary to aid in conversion, a future commit
will remove this and switch to requiring the users to allocate the
vector instead.
At the moment, this processes the RIFF chunk structure and extracts
the ICCP chunk, so that `icc` can now print ICC profiles embedded
in webp files. (And are image files really more than containers
of icc profiles?)
It doesn't even decode image dimensions yet.
The lossy format is a VP8 video frame. Once we get to that, we
might want to move all the image decoders into a new LibImageDecoders
that depends on both LibGfx and LibVideo. (Other newer image formats
like heic and av1f also use video frames for image data.)
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.
Similar to the return values earlier, a signed value doesn't really make
sense here. Relying on the much more standard `size_t` makes it easier
to use Stream in all contexts.
`Stream` will be qualified as `AK::Stream` until we remove the
`Core::Stream` namespace. `IODevice` now reuses the `SeekMode` that is
defined by `SeekableStream`, since defining its own would require us to
qualify it with `AK::SeekMode` everywhere.
Having an alias function that only wraps another one is silly, and
keeping the more obvious name should flush out more uses of deprecated
strings.
No behavior change.
`Process::get_name()` and `Process::set_name()` are basically the same
as `get_process_name()` and `set_process_name()`, except making use of
convenient Serenity standard types and returning ErrorOr, instead of
char* and errno shenanigans.
`Process::set_name()` has an optional `SetThreadName` parameter, for
when you also want to set the thread's name to the same thing. That's
true for the two places that use `set_process_name()`.
Besides from a general check if a file's directory has write
permissions, this also checks if the directory has set a sticky bit,
meaning that only file owners and the directory owner can remove or move
files in such directory. It's being used in /tmp for example.
At the moment, there is no immediate advantage compared to just calling
the underlying functions directly, but having a common interface feels
more ergonomic (users don't have to care about how a type serializes)
and maybe we'll find a way to hide the actual implementation from direct
access some time in the future.
The macOS FileWatcher depends on macOS dispatch queues, which run on a
different thread than the Core::EventLoop. This implementation handles
filesystem events on its dispatch queue, then forwards the event back to
the main Core::EventLoop for notifying the FileWatcher owner.
This will be handy for platforms which need to be able to store extra
OS-specific members. For example, macOS needs to store a dispatch queue,
and event stream, etc.
A negative return value doesn't make sense for any of those functions.
The return types were inherited from POSIX, where they also need to have
an indicator for an error (negative values).
InodeWatcherFlags is an enumeration from the Kernel. To avoid using it
outside of Serenity, add a FileWatcherFlags for FileWatcher, much like
we already have FileWatcherEvent::Type.
This is currently being implicitly including by InodeWatcherEvent.h by
way of FileWatcher.h. The former will soon be removed from the latter,
which would otherwise cause a compile error in these files.
This implements FileWatcher using inotify filesystem events. Serenity's
InodeWatcher is remarkably similar to inotify, so this is almost an
identical implementation.
The existing TestLibCoreFileWatcher test is added to Lagom (currently
just for Linux).
This does not implement BlockingFileWatcher as that is currently not
used anywhere but on Serenity.
This saves us an actual seek and rereading already stored buffer data in
cases where the seek is entirely covered by the currently buffered data.
This is especially important since we implement `discard` using `seek`
for seekable streams.
While at it, rename the `read_trivial_value` and `write_trivial_value`
functions to `read_value` and `write_value` respectively, since we'll
add compatibility for non-trivial types down the line.
We don't need to call `can_read_line()` as the buffer will be populated
by `find_and_populate_until_any_of()`. The change is also beneficial as
the buffer will be populated until a candidate is found and not
necessarily a new line.
The search used to go through the buffer from the start, even if we just
appended a small number of bytes at the end. It now remembers the last
stop and resume the search from it.
This parameter allows to start searching after an offset. For example,
to resume a search.
It is unfortunately a breaking change in API so this patch also modifies
one user and one test.
Ladybird currently doesn't render any webpages on FreeBSD and throws
hundreds of errors,beginning with this:
IPC::ConnectionBase (0x0000000805bf2b00) had an error (File descriptor
passing not supported on this platform), disconnecting.
WebContent process crashed!
There is no particular reason why we shouldn't allow zero-sized reads or
writes here, and this actually might cause issues with our common
stream-to-stream copy pattern if we end up at an unfortunate offset
where the next read would be zero-sized and trigger EOF only after that.
This was unintuitive, and only useful in a few cases. In the majority,
users had to immediately call `stop()`, and several who did want the
timer started would call `start()` on it immediately anyway. Case in
point: There are only two places I had to add a manual `start()`.
Before this patch, Core::SessionManagement::parse_path_with_sid() would
figure out the root session ID by sifting through /sys/kernel/processes.
That file can take quite a while to generate (sometimes up to 40ms on my
machine, which is a problem on its own!) and with no caching, many of
our programs were effectively doing this multiple times on startup when
unveiling something in /tmp/session/%sid/
While we should find ways to make generating /sys/kernel/processes fast
again, this patch addresses the specific problem by introducing a new
syscall: sys$get_root_session_id(). This extracts the root session ID
by looking directly at the process table and takes <1ms instead of 40ms.
This cuts WebContent process startup time by ~100ms on my machine. :^)
Also add some tests that ensure that the input and output streams match
each other, because I can't wrap my head around what the internal
representation looks like.
This removes the direct dependency on sys/time.h from ElapsedTimer, and
makes the code a lot cleaner by using the helpers from AK::Time for
time math and getting the current timestamp.
In doing so, this removes all uses of the Encoder's stream operator,
except for where it is currently still used in the generated IPC code.
So the stream operator currently discards any errors, which is the
existing behavior. A subsequent commit will propagate the errors.
These instances were detected by searching for files that include
stdlib.h, but don't match the regex:
\\b(_abort|abort|abs|aligned_alloc|arc4random|arc4random_buf|arc4random_
uniform|atexit|atof|atoi|atol|atoll|bsearch|calloc|clearenv|div|div_t|ex
it|_Exit|EXIT_FAILURE|EXIT_SUCCESS|free|getenv|getprogname|grantpt|labs|
ldiv|ldiv_t|llabs|lldiv|lldiv_t|malloc|malloc_good_size|malloc_size|mble
n|mbstowcs|mbtowc|mkdtemp|mkstemp|mkstemps|mktemp|posix_memalign|posix_o
penpt|ptsname|ptsname_r|putenv|qsort|qsort_r|rand|RAND_MAX|random|reallo
c|realpath|secure_getenv|serenity_dump_malloc_stats|serenity_setenv|sete
nv|setprogname|srand|srandom|strtod|strtof|strtol|strtold|strtoll|strtou
l|strtoull|system|unlockpt|unsetenv|wcstombs|wctomb)\\b
(Without the linebreaks.)
This regex is pessimistic, so there might be more files that don't
actually use anything from the stdlib.
In theory, one might use LibCPP to detect things like this
automatically, but let's do this one step after another.
These instances were detected by searching for files that include
MemMem.h, but don't match the regex:
\\b(MemMem(?!\.h>)|bitap_bitwise|memmem|memmem_optional)\\b
These are the only symbols defined by MemMem.h.
In theory, one might use LibCPP to detect things like this
automatically, but let's do this one step after another.
In 7c5e30daaa, the focus was "only" on
Userland/Libraries/, whereas this commit cleans up the remaining
headers in the repo, and any new badly-formatted include.
The existing `load_from_gml()` methods look the same as before from the
outside. Inside though, they now forward to `try_load_from_gml()` which
returns Error when things go wrong. It also now calls the `try_create()`
factory method for Objects instead of the `construct()` one.
Currently, the generated IPC decoders will default-construct the type to
be decoded, then pass that value by reference to the concrete decoder.
This, of course, requires that the type is default-constructible. This
was an issue for decoding Variants, which had to require the first type
in the Variant list is Empty, to ensure it is default constructible.
Further, this made it possible for values to become uninitialized in
user-defined decoders.
This patch makes the decoder interface such that the concrete decoders
themselves contruct the decoded type upon return from the decoder. To do
so, the default decoders in IPC::Decoder had to be moved to the IPC
namespace scope, as these decoders are now specializations instead of
overloaded methods (C++ requires specializations to be in a namespace
scope).
About half of the usages were not using `force` anyways, and the other
half presumably just got confused about what "force" really means in
this context (which is "ignore nonexistent files").
The only 'legitimate' user, which is `rm`, instead now handles this
completely internally instead.
This is a first step towards handling OOM errors instead of just
crashing the program.
Now UDPServer's method `receive()` return memory allocation
errors explicitly with help of ErrorOr.
This removes one FIXME and make a bunch of new ones. :(
When we encounter an explicit timezone, we shift the time to UTC.
Because we rely on `mktime`, we need to shift it to the local time
before proceeding. If no explicit timezone is provided, local timezone
is assumed.
This fixes the "timezone-offset extension" LibJS test running on
machines with a non-UTC timezone offset.
Co-authored-by: Timothy Flynn <trflynn89@pm.me>
`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.
This is to differentiate between the upcoming `AllocatingMemoryStream`,
which automatically allocates memory as needed instead of operating on a
static memory area.
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.
Note that this still keeps the old behaviour of putting things in std by
default on serenity so the tools can be happy, but if USING_AK_GLOBALLY
is unset, AK behaves like a good citizen and doesn't try to put things
in the ::std namespace.
std::nothrow_t and its friends get to stay because I'm being told that
compilers assume things about them and I can't yeet them into a
different namespace...for now.
The previous approach could leave behind uninitialized fields on
platforms which have additional fields in this structure (e.g. padding
fields on musl libc).
This allows us to either pass a reference, which keeps compatibility
with old code, or to pass a NonnullOwnPtr, which allows us to
comfortably chain streams as usual.
This essentially wraps a `NonnullOwnPtr` or a reference, allowing us to
either have a stream own a dependent stream that it uses or to just hold
a reference if a stream is already owned by somebody else and we just
want to use it temporarily.
This generally seems like a better name, especially if we somehow also
need a better name for "read the entire buffer, but not the entire file"
somewhere down the line.
Next to functions like `is_eof` these were really confusing to use, and
the `read`/`write` functions should fail anyways if a stream is not
readable/writable.
`Core::Stream::File` shouldn't hold any utility methods that are
unrelated to constructing a `Core::Stream`, so let's just replace the
existing `Core::File::exists` with the nicer looking implementation.
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.
One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
Make LocalServer connections not terminate their process from SIGPIPE,
which fixes the issue where closing DisplaySettings with the[OK] button
would often crash WindowServer.
When creating a `Core::Stream::Socket`, you can now choose to prevent
SIGPIPE signals from firing and terminating your process. This is done
by passing MSG_NOSIGNAL to the `System::recv()` or `System::send()`
calls when you `read()` or `write()` to that Socket.
This could be used in a scenario when it is expected that a user program
will be invoked with a specific option multiple times, for example:
"program --a-option=example --a-option=anotherexample ..."
To accomplish this, we add another VeilState which is called
LockedInherited. The idea is to apply exec unveil data, similar to
execpromises of the pledge syscall, on the current exec'ed program
during the execve sequence. When applying the forced unveil data, the
veil state is set to be locked but the special state of LockedInherited
ensures that if the new program tries to unveil paths, the request will
silently be ignored, so the program will continue running without
receiving an error, but is still can only use the paths that were
unveiled before the exec syscall. This in turn, allows us to use the
unveil syscall with a special utility to sandbox other userland programs
in terms of what is visible to them on the filesystem, and is usable on
both programs that use or don't use the unveil syscall in their code.
This allows rectangle specifications in the form [x, y, width, height],
which mirrors margin properties and is much more convenient than the
JSON object specifications that were allowed before. Those are still
allowed, of course.