summaryrefslogtreecommitdiff
path: root/Libraries/LibCore
diff options
context:
space:
mode:
Diffstat (limited to 'Libraries/LibCore')
-rw-r--r--Libraries/LibCore/Account.cpp316
-rw-r--r--Libraries/LibCore/Account.h109
-rw-r--r--Libraries/LibCore/ArgsParser.cpp392
-rw-r--r--Libraries/LibCore/ArgsParser.h94
-rw-r--r--Libraries/LibCore/CMakeLists.txt37
-rw-r--r--Libraries/LibCore/Command.cpp127
-rw-r--r--Libraries/LibCore/Command.h40
-rw-r--r--Libraries/LibCore/ConfigFile.cpp242
-rw-r--r--Libraries/LibCore/ConfigFile.h82
-rw-r--r--Libraries/LibCore/DateTime.cpp263
-rw-r--r--Libraries/LibCore/DateTime.h74
-rw-r--r--Libraries/LibCore/DirIterator.cpp121
-rw-r--r--Libraries/LibCore/DirIterator.h65
-rw-r--r--Libraries/LibCore/DirectoryWatcher.cpp98
-rw-r--r--Libraries/LibCore/DirectoryWatcher.h61
-rw-r--r--Libraries/LibCore/ElapsedTimer.cpp57
-rw-r--r--Libraries/LibCore/ElapsedTimer.h54
-rw-r--r--Libraries/LibCore/Event.cpp72
-rw-r--r--Libraries/LibCore/Event.h159
-rw-r--r--Libraries/LibCore/EventLoop.cpp835
-rw-r--r--Libraries/LibCore/EventLoop.h122
-rw-r--r--Libraries/LibCore/File.cpp270
-rw-r--r--Libraries/LibCore/File.h78
-rw-r--r--Libraries/LibCore/FileStream.h171
-rw-r--r--Libraries/LibCore/Forward.h61
-rw-r--r--Libraries/LibCore/GetPassword.cpp70
-rw-r--r--Libraries/LibCore/GetPassword.h37
-rw-r--r--Libraries/LibCore/Gzip.cpp165
-rw-r--r--Libraries/LibCore/Gzip.h41
-rw-r--r--Libraries/LibCore/IODevice.cpp336
-rw-r--r--Libraries/LibCore/IODevice.h133
-rw-r--r--Libraries/LibCore/IODeviceStreamReader.h61
-rw-r--r--Libraries/LibCore/LocalServer.cpp161
-rw-r--r--Libraries/LibCore/LocalServer.h57
-rw-r--r--Libraries/LibCore/LocalSocket.cpp107
-rw-r--r--Libraries/LibCore/LocalSocket.h45
-rw-r--r--Libraries/LibCore/MimeData.cpp102
-rw-r--r--Libraries/LibCore/MimeData.h72
-rw-r--r--Libraries/LibCore/NetworkJob.cpp108
-rw-r--r--Libraries/LibCore/NetworkJob.h83
-rw-r--r--Libraries/LibCore/NetworkResponse.cpp39
-rw-r--r--Libraries/LibCore/NetworkResponse.h46
-rw-r--r--Libraries/LibCore/Notifier.cpp76
-rw-r--r--Libraries/LibCore/Notifier.h66
-rw-r--r--Libraries/LibCore/Object.cpp270
-rw-r--r--Libraries/LibCore/Object.h346
-rw-r--r--Libraries/LibCore/ProcessStatisticsReader.cpp142
-rw-r--r--Libraries/LibCore/ProcessStatisticsReader.h98
-rw-r--r--Libraries/LibCore/Property.cpp42
-rw-r--r--Libraries/LibCore/Property.h59
-rw-r--r--Libraries/LibCore/Socket.cpp236
-rw-r--r--Libraries/LibCore/Socket.h89
-rw-r--r--Libraries/LibCore/SocketAddress.cpp36
-rw-r--r--Libraries/LibCore/SocketAddress.h115
-rw-r--r--Libraries/LibCore/StandardPaths.cpp77
-rw-r--r--Libraries/LibCore/StandardPaths.h42
-rw-r--r--Libraries/LibCore/SyscallUtils.h56
-rw-r--r--Libraries/LibCore/TCPServer.cpp125
-rw-r--r--Libraries/LibCore/TCPServer.h58
-rw-r--r--Libraries/LibCore/TCPSocket.cpp70
-rw-r--r--Libraries/LibCore/TCPSocket.h44
-rw-r--r--Libraries/LibCore/Timer.cpp96
-rw-r--r--Libraries/LibCore/Timer.h81
-rw-r--r--Libraries/LibCore/UDPServer.cpp123
-rw-r--r--Libraries/LibCore/UDPServer.h66
-rw-r--r--Libraries/LibCore/UDPSocket.cpp61
-rw-r--r--Libraries/LibCore/UDPSocket.h42
-rw-r--r--Libraries/LibCore/puff.cpp840
-rw-r--r--Libraries/LibCore/puff.h44
69 files changed, 0 insertions, 9063 deletions
diff --git a/Libraries/LibCore/Account.cpp b/Libraries/LibCore/Account.cpp
deleted file mode 100644
index 7e4d40669a..0000000000
--- a/Libraries/LibCore/Account.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (c) 2020, Peter Elliott <pelliott@ualberta.ca>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/Base64.h>
-#include <AK/Random.h>
-#include <LibCore/Account.h>
-#include <LibCore/File.h>
-#include <grp.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-namespace Core {
-
-static String get_salt()
-{
- char random_data[12];
- AK::fill_with_random(random_data, sizeof(random_data));
-
- StringBuilder builder;
- builder.append("$5$");
- builder.append(encode_base64(ReadonlyBytes(random_data, sizeof(random_data))));
-
- return builder.build();
-}
-
-static Vector<gid_t> get_gids(const StringView& username)
-{
- Vector<gid_t> extra_gids;
- for (auto* group = getgrent(); group; group = getgrent()) {
- for (size_t i = 0; group->gr_mem[i]; ++i) {
- if (username == group->gr_mem[i]) {
- extra_gids.append(group->gr_gid);
- break;
- }
- }
- }
- endgrent();
- return extra_gids;
-}
-
-Result<Account, String> Account::from_passwd(const passwd& pwd, Core::Account::OpenPasswdFile open_passwd_file, Core::Account::OpenShadowFile open_shadow_file)
-{
- RefPtr<Core::File> passwd_file;
- if (open_passwd_file != Core::Account::OpenPasswdFile::No) {
- auto open_mode = open_passwd_file == Core::Account::OpenPasswdFile::ReadOnly
- ? Core::File::OpenMode::ReadOnly
- : Core::File::OpenMode::ReadWrite;
- auto file_or_error = Core::File::open("/etc/passwd", open_mode);
- if (file_or_error.is_error())
- return file_or_error.error();
- passwd_file = file_or_error.value();
- }
-
- RefPtr<Core::File> shadow_file;
- if (open_shadow_file != Core::Account::OpenShadowFile::No) {
- auto open_mode = open_shadow_file == Core::Account::OpenShadowFile::ReadOnly
- ? Core::File::OpenMode::ReadOnly
- : Core::File::OpenMode::ReadWrite;
- auto file_or_error = Core::File::open("/etc/shadow", open_mode);
- if (file_or_error.is_error())
- return file_or_error.error();
- shadow_file = file_or_error.value();
- }
-
- Account account(pwd, get_gids(pwd.pw_name), move(passwd_file), move(shadow_file));
- endpwent();
- return account;
-}
-
-Result<Account, String> Account::from_name(const char* username, Core::Account::OpenPasswdFile open_passwd_file, Core::Account::OpenShadowFile open_shadow_file)
-{
- struct passwd* pwd = nullptr;
- errno = 0;
- pwd = getpwnam(username);
- if (!pwd) {
- if (errno == 0)
- return String("No such user");
-
- return String(strerror(errno));
- }
- return from_passwd(*pwd, open_passwd_file, open_shadow_file);
-}
-
-Result<Account, String> Account::from_uid(uid_t uid, Core::Account::OpenPasswdFile open_passwd_file, Core::Account::OpenShadowFile open_shadow_file)
-{
- struct passwd* pwd = nullptr;
- errno = 0;
- pwd = getpwuid(uid);
- if (!pwd) {
- if (errno == 0)
- return String("No such user");
-
- return String(strerror(errno));
- }
- return from_passwd(*pwd, open_passwd_file, open_shadow_file);
-}
-
-bool Account::authenticate(const char* password) const
-{
- // An empty passwd field indicates that no password is required to log in.
- if (m_password_hash.is_empty())
- return true;
-
- // FIXME: Use crypt_r if it can be built in lagom.
- char* hash = crypt(password, m_password_hash.characters());
- return hash != nullptr && strcmp(hash, m_password_hash.characters()) == 0;
-}
-
-bool Account::login() const
-{
- if (setgroups(m_extra_gids.size(), m_extra_gids.data()) < 0)
- return false;
-
- if (setgid(m_gid) < 0)
- return false;
-
- if (setuid(m_uid) < 0)
- return false;
-
- return true;
-}
-
-void Account::set_password(const char* password)
-{
- m_password_hash = crypt(password, get_salt().characters());
-}
-
-void Account::set_password_enabled(bool enabled)
-{
- if (enabled && m_password_hash != "" && m_password_hash[0] == '!') {
- m_password_hash = m_password_hash.substring(1, m_password_hash.length() - 1);
- } else if (!enabled && (m_password_hash == "" || m_password_hash[0] != '!')) {
- StringBuilder builder;
- builder.append('!');
- builder.append(m_password_hash);
- m_password_hash = builder.build();
- }
-}
-
-void Account::delete_password()
-{
- m_password_hash = "";
-}
-
-Account::Account(const passwd& pwd, Vector<gid_t> extra_gids, RefPtr<Core::File> passwd_file, RefPtr<Core::File> shadow_file)
- : m_passwd_file(move(passwd_file))
- , m_shadow_file(move(shadow_file))
- , m_username(pwd.pw_name)
- , m_uid(pwd.pw_uid)
- , m_gid(pwd.pw_gid)
- , m_gecos(pwd.pw_gecos)
- , m_home_directory(pwd.pw_dir)
- , m_shell(pwd.pw_shell)
- , m_extra_gids(extra_gids)
-{
- if (m_shadow_file) {
- load_shadow_file();
- }
-}
-
-String Account::generate_passwd_file() const
-{
- StringBuilder builder;
-
- setpwent();
-
- struct passwd* p;
- errno = 0;
- while ((p = getpwent())) {
- if (p->pw_uid == m_uid) {
- builder.appendff("{}:!:{}:{}:{}:{}:{}\n",
- m_username,
- m_uid, m_gid,
- m_gecos,
- m_home_directory,
- m_shell);
-
- } else {
- builder.appendff("{}:!:{}:{}:{}:{}:{}\n",
- p->pw_name, p->pw_uid,
- p->pw_gid, p->pw_gecos, p->pw_dir,
- p->pw_shell);
- }
- }
- endpwent();
-
- if (errno) {
- dbgln("errno was non-zero after generating new passwd file.");
- return {};
- }
-
- return builder.to_string();
-}
-
-void Account::load_shadow_file()
-{
- ASSERT(m_shadow_file);
- ASSERT(m_shadow_file->is_open());
-
- if (!m_shadow_file->seek(0)) {
- ASSERT_NOT_REACHED();
- }
-
- Vector<ShadowEntry> entries;
-
- for (;;) {
- auto line = m_shadow_file->read_line();
- if (line.is_null())
- break;
- auto parts = line.split(':');
- if (parts.size() != 2) {
- dbgln("Malformed shadow entry, ignoring.");
- continue;
- }
- const auto& username = parts[0];
- const auto& password_hash = parts[1];
- entries.append({ username, password_hash });
-
- if (username == m_username) {
- m_password_hash = password_hash;
- }
- }
-
- m_shadow_entries = move(entries);
-}
-
-String Account::generate_shadow_file() const
-{
- StringBuilder builder;
- bool updated_entry_in_place = false;
- for (auto& entry : m_shadow_entries) {
- if (entry.username == m_username) {
- updated_entry_in_place = true;
- builder.appendff("{}:{}\n", m_username, m_password_hash);
- } else {
- builder.appendff("{}:{}\n", entry.username, entry.password_hash);
- }
- }
- if (!updated_entry_in_place)
- builder.appendff("{}:{}\n", m_username, m_password_hash);
- return builder.to_string();
-}
-
-bool Account::sync()
-{
- ASSERT(m_passwd_file);
- ASSERT(m_passwd_file->mode() == Core::File::OpenMode::ReadWrite);
- ASSERT(m_shadow_file);
- ASSERT(m_shadow_file->mode() == Core::File::OpenMode::ReadWrite);
-
- // FIXME: Maybe reorganize this to create temporary files and finish it completely before renaming them to /etc/{passwd,shadow}
- // If truncation succeeds but write fails, we'll have an empty file :(
-
- auto new_passwd_file = generate_passwd_file();
- auto new_shadow_file = generate_shadow_file();
-
- if (new_passwd_file.is_null() || new_shadow_file.is_null()) {
- ASSERT_NOT_REACHED();
- }
-
- if (!m_passwd_file->seek(0) || !m_shadow_file->seek(0)) {
- ASSERT_NOT_REACHED();
- }
-
- if (!m_passwd_file->truncate(0)) {
- dbgln("Truncating passwd file failed.");
- return false;
- }
-
- if (!m_passwd_file->write(new_passwd_file)) {
- // FIXME: Improve Core::File::write() error reporting.
- dbgln("Writing to passwd file failed.");
- return false;
- }
-
- if (!m_shadow_file->truncate(0)) {
- dbgln("Truncating shadow file failed.");
- return false;
- }
-
- if (!m_shadow_file->write(new_shadow_file)) {
- // FIXME: Improve Core::File::write() error reporting.
- dbgln("Writing to shadow file failed.");
- return false;
- }
-
- return true;
- // FIXME: Sync extra groups.
-}
-
-}
diff --git a/Libraries/LibCore/Account.h b/Libraries/LibCore/Account.h
deleted file mode 100644
index fdd7d9bea9..0000000000
--- a/Libraries/LibCore/Account.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2020, Peter Elliott <pelliott@ualberta.ca>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Result.h>
-#include <AK/String.h>
-#include <AK/Types.h>
-#include <AK/Vector.h>
-#include <LibCore/File.h>
-#include <pwd.h>
-#include <sys/types.h>
-
-namespace Core {
-
-class Account {
-public:
- enum class OpenPasswdFile {
- No,
- ReadOnly,
- ReadWrite,
- };
-
- enum class OpenShadowFile {
- No,
- ReadOnly,
- ReadWrite,
- };
-
- static Result<Account, String> from_name(const char* username, OpenPasswdFile = OpenPasswdFile::No, OpenShadowFile = OpenShadowFile::No);
- static Result<Account, String> from_uid(uid_t uid, OpenPasswdFile = OpenPasswdFile::No, OpenShadowFile = OpenShadowFile::No);
-
- bool authenticate(const char* password) const;
- bool login() const;
-
- String username() const { return m_username; }
- String password_hash() const { return m_password_hash; }
-
- // Setters only affect in-memory copy of password.
- // You must call sync to apply changes.
- void set_password(const char* password);
- void set_password_enabled(bool enabled);
- void delete_password();
- bool has_password() const { return !m_password_hash.is_empty(); }
-
- uid_t uid() const { return m_uid; }
- gid_t gid() const { return m_gid; }
- const String& gecos() const { return m_gecos; }
- const String& home_directory() const { return m_home_directory; }
- const String& shell() const { return m_shell; }
- const Vector<gid_t>& extra_gids() const { return m_extra_gids; }
-
- bool sync();
-
-private:
- static Result<Account, String> from_passwd(const passwd&, OpenPasswdFile, OpenShadowFile);
-
- Account(const passwd& pwd, Vector<gid_t> extra_gids, RefPtr<Core::File> passwd_file, RefPtr<Core::File> shadow_file);
- void load_shadow_file();
-
- String generate_passwd_file() const;
- String generate_shadow_file() const;
-
- RefPtr<Core::File> m_passwd_file;
- RefPtr<Core::File> m_shadow_file;
-
- String m_username;
-
- // Contents of passwd field in passwd entry.
- // Can be empty, "x", or contain a leading '!'
- String m_password_hash;
- uid_t m_uid { 0 };
- gid_t m_gid { 0 };
- String m_gecos;
- String m_home_directory;
- String m_shell;
- Vector<gid_t> m_extra_gids;
-
- struct ShadowEntry {
- String username;
- String password_hash;
- };
- Vector<ShadowEntry> m_shadow_entries;
-};
-
-}
diff --git a/Libraries/LibCore/ArgsParser.cpp b/Libraries/LibCore/ArgsParser.cpp
deleted file mode 100644
index 121272e38b..0000000000
--- a/Libraries/LibCore/ArgsParser.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/Format.h>
-#include <AK/StringBuilder.h>
-#include <LibCore/ArgsParser.h>
-#include <getopt.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-static constexpr bool isnan(double __x) { return __builtin_isnan(__x); }
-
-static Optional<double> convert_to_double(const char* s)
-{
- char* p;
- double v = strtod(s, &p);
- if (isnan(v) || p == s)
- return {};
- return v;
-}
-
-namespace Core {
-
-ArgsParser::ArgsParser()
-{
- add_option(m_show_help, "Display this message", "help", 0);
-}
-
-bool ArgsParser::parse(int argc, char** argv, bool exit_on_failure)
-{
- auto print_usage_and_exit = [this, argv, exit_on_failure] {
- print_usage(stderr, argv[0]);
- if (exit_on_failure)
- exit(1);
- };
-
- Vector<option> long_options;
- StringBuilder short_options_builder;
-
- int index_of_found_long_option = -1;
-
- // Tell getopt() to reset its internal state, and start scanning from optind = 1.
- // We could also set optreset = 1, but the host platform may not support that.
- optind = 0;
-
- for (size_t i = 0; i < m_options.size(); i++) {
- auto& opt = m_options[i];
- if (opt.long_name) {
- option long_opt {
- opt.long_name,
- opt.requires_argument ? required_argument : no_argument,
- &index_of_found_long_option,
- static_cast<int>(i)
- };
- long_options.append(long_opt);
- }
- if (opt.short_name) {
- short_options_builder.append(opt.short_name);
- if (opt.requires_argument)
- short_options_builder.append(':');
- }
- }
- long_options.append({ 0, 0, 0, 0 });
-
- String short_options = short_options_builder.build();
-
- while (true) {
- int c = getopt_long(argc, argv, short_options.characters(), long_options.data(), nullptr);
- if (c == -1) {
- // We have reached the end.
- break;
- } else if (c == '?') {
- // There was an error, and getopt() has already
- // printed its error message.
- print_usage_and_exit();
- return false;
- }
-
- // Let's see what option we just found.
- Option* found_option = nullptr;
- if (c == 0) {
- // It was a long option.
- ASSERT(index_of_found_long_option >= 0);
- found_option = &m_options[index_of_found_long_option];
- index_of_found_long_option = -1;
- } else {
- // It was a short option, look it up.
- auto it = m_options.find_if([c](auto& opt) { return c == opt.short_name; });
- ASSERT(!it.is_end());
- found_option = &*it;
- }
- ASSERT(found_option);
-
- const char* arg = found_option->requires_argument ? optarg : nullptr;
- if (!found_option->accept_value(arg)) {
- warnln("\033[31mInvalid value for option \033[1m{}\033[22m, dude\033[0m", found_option->name_for_display());
- print_usage_and_exit();
- return false;
- }
- }
-
- // We're done processing options, now let's parse positional arguments.
-
- int values_left = argc - optind;
- int num_values_for_arg[m_positional_args.size()];
- int total_values_required = 0;
- for (size_t i = 0; i < m_positional_args.size(); i++) {
- auto& arg = m_positional_args[i];
- num_values_for_arg[i] = arg.min_values;
- total_values_required += arg.min_values;
- }
-
- if (total_values_required > values_left) {
- print_usage_and_exit();
- return false;
- }
- int extra_values_to_distribute = values_left - total_values_required;
-
- for (size_t i = 0; i < m_positional_args.size(); i++) {
- auto& arg = m_positional_args[i];
- int extra_values_to_this_arg = min(arg.max_values - arg.min_values, extra_values_to_distribute);
- num_values_for_arg[i] += extra_values_to_this_arg;
- extra_values_to_distribute -= extra_values_to_this_arg;
- if (extra_values_to_distribute == 0)
- break;
- }
-
- if (extra_values_to_distribute > 0) {
- // We still have too many values :(
- print_usage_and_exit();
- return false;
- }
-
- for (size_t i = 0; i < m_positional_args.size(); i++) {
- auto& arg = m_positional_args[i];
- for (int j = 0; j < num_values_for_arg[i]; j++) {
- const char* value = argv[optind++];
- if (!arg.accept_value(value)) {
- warnln("Invalid value for argument {}", arg.name);
- print_usage_and_exit();
- return false;
- }
- }
- }
-
- // We're done parsing! :)
- // Now let's show help if requested.
- if (m_show_help) {
- print_usage(stdout, argv[0]);
- if (exit_on_failure)
- exit(0);
- return false;
- }
-
- return true;
-}
-
-void ArgsParser::print_usage(FILE* file, const char* argv0)
-{
- out(file, "Usage:\n\t\033[1m{}\033[0m", argv0);
-
- for (auto& opt : m_options) {
- if (opt.long_name && !strcmp(opt.long_name, "help"))
- continue;
- if (opt.requires_argument)
- out(file, " [{} {}]", opt.name_for_display(), opt.value_name);
- else
- out(file, " [{}]", opt.name_for_display());
- }
- for (auto& arg : m_positional_args) {
- bool required = arg.min_values > 0;
- bool repeated = arg.max_values > 1;
-
- if (required && repeated)
- out(file, " <{}...>", arg.name);
- else if (required && !repeated)
- out(file, " <{}>", arg.name);
- else if (!required && repeated)
- out(file, " [{}...]", arg.name);
- else if (!required && !repeated)
- out(file, " [{}]", arg.name);
- }
- outln(file);
-
- if (m_general_help != nullptr && m_general_help[0] != '\0') {
- outln(file, "\nDescription:");
- outln(file, m_general_help);
- }
-
- if (!m_options.is_empty())
- outln(file, "\nOptions:");
- for (auto& opt : m_options) {
- auto print_argument = [&]() {
- if (opt.value_name) {
- if (opt.requires_argument)
- out(file, " {}", opt.value_name);
- else
- out(file, " [{}]", opt.value_name);
- }
- };
- out(file, "\t");
- if (opt.short_name) {
- out(file, "\033[1m-{}\033[0m", opt.short_name);
- print_argument();
- }
- if (opt.short_name && opt.long_name)
- out(file, ", ");
- if (opt.long_name) {
- out(file, "\033[1m--{}\033[0m", opt.long_name);
- print_argument();
- }
-
- if (opt.help_string)
- out(file, "\t{}", opt.help_string);
- outln(file);
- }
-
- if (!m_positional_args.is_empty())
- outln(file, "\nArguments:");
-
- for (auto& arg : m_positional_args) {
- out(file, "\t\033[1m{}\033[0m", arg.name);
- if (arg.help_string)
- out(file, "\t{}", arg.help_string);
- outln(file);
- }
-}
-
-void ArgsParser::add_option(Option&& option)
-{
- m_options.append(move(option));
-}
-
-void ArgsParser::add_option(bool& value, const char* help_string, const char* long_name, char short_name)
-{
- Option option {
- false,
- help_string,
- long_name,
- short_name,
- nullptr,
- [&value](const char* s) {
- ASSERT(s == nullptr);
- value = true;
- return true;
- }
- };
- add_option(move(option));
-}
-
-void ArgsParser::add_option(const char*& value, const char* help_string, const char* long_name, char short_name, const char* value_name)
-{
- Option option {
- true,
- help_string,
- long_name,
- short_name,
- value_name,
- [&value](const char* s) {
- value = s;
- return true;
- }
- };
- add_option(move(option));
-}
-
-void ArgsParser::add_option(int& value, const char* help_string, const char* long_name, char short_name, const char* value_name)
-{
- Option option {
- true,
- help_string,
- long_name,
- short_name,
- value_name,
- [&value](const char* s) {
- auto opt = StringView(s).to_int();
- value = opt.value_or(0);
- return opt.has_value();
- }
- };
- add_option(move(option));
-}
-
-void ArgsParser::add_option(double& value, const char* help_string, const char* long_name, char short_name, const char* value_name)
-{
- Option option {
- true,
- help_string,
- long_name,
- short_name,
- value_name,
- [&value](const char* s) {
- auto opt = convert_to_double(s);
- value = opt.value_or(0.0);
- return opt.has_value();
- }
- };
- add_option(move(option));
-}
-
-void ArgsParser::add_positional_argument(Arg&& arg)
-{
- m_positional_args.append(move(arg));
-}
-
-void ArgsParser::add_positional_argument(const char*& value, const char* help_string, const char* name, Required required)
-{
- Arg arg {
- help_string,
- name,
- required == Required::Yes ? 1 : 0,
- 1,
- [&value](const char* s) {
- value = s;
- return true;
- }
- };
- add_positional_argument(move(arg));
-}
-
-void ArgsParser::add_positional_argument(int& value, const char* help_string, const char* name, Required required)
-{
- Arg arg {
- help_string,
- name,
- required == Required::Yes ? 1 : 0,
- 1,
- [&value](const char* s) {
- auto opt = StringView(s).to_int();
- value = opt.value_or(0);
- return opt.has_value();
- }
- };
- add_positional_argument(move(arg));
-}
-
-void ArgsParser::add_positional_argument(double& value, const char* help_string, const char* name, Required required)
-{
- Arg arg {
- help_string,
- name,
- required == Required::Yes ? 1 : 0,
- 1,
- [&value](const char* s) {
- auto opt = convert_to_double(s);
- value = opt.value_or(0.0);
- return opt.has_value();
- }
- };
- add_positional_argument(move(arg));
-}
-
-void ArgsParser::add_positional_argument(Vector<const char*>& values, const char* help_string, const char* name, Required required)
-{
- Arg arg {
- help_string,
- name,
- required == Required::Yes ? 1 : 0,
- INT_MAX,
- [&values](const char* s) {
- values.append(s);
- return true;
- }
- };
- add_positional_argument(move(arg));
-}
-
-}
diff --git a/Libraries/LibCore/ArgsParser.h b/Libraries/LibCore/ArgsParser.h
deleted file mode 100644
index 2f7b923a9d..0000000000
--- a/Libraries/LibCore/ArgsParser.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Function.h>
-#include <AK/String.h>
-#include <AK/Vector.h>
-#include <stdio.h>
-
-namespace Core {
-
-class ArgsParser {
-public:
- ArgsParser();
-
- enum class Required {
- Yes,
- No
- };
-
- struct Option {
- bool requires_argument { true };
- const char* help_string { nullptr };
- const char* long_name { nullptr };
- char short_name { 0 };
- const char* value_name { nullptr };
- Function<bool(const char*)> accept_value;
-
- String name_for_display() const
- {
- if (long_name)
- return String::format("--%s", long_name);
- return String::format("-%c", short_name);
- }
- };
-
- struct Arg {
- const char* help_string { nullptr };
- const char* name { nullptr };
- int min_values { 0 };
- int max_values { 1 };
- Function<bool(const char*)> accept_value;
- };
-
- bool parse(int argc, char** argv, bool exit_on_failure = true);
- // *Without* trailing newline!
- void set_general_help(const char* help_string) { m_general_help = help_string; };
- void print_usage(FILE*, const char* argv0);
-
- void add_option(Option&&);
- void add_option(bool& value, const char* help_string, const char* long_name, char short_name);
- void add_option(const char*& value, const char* help_string, const char* long_name, char short_name, const char* value_name);
- void add_option(int& value, const char* help_string, const char* long_name, char short_name, const char* value_name);
- void add_option(double& value, const char* help_string, const char* long_name, char short_name, const char* value_name);
-
- void add_positional_argument(Arg&&);
- void add_positional_argument(const char*& value, const char* help_string, const char* name, Required required = Required::Yes);
- void add_positional_argument(int& value, const char* help_string, const char* name, Required required = Required::Yes);
- void add_positional_argument(double& value, const char* help_string, const char* name, Required required = Required::Yes);
- void add_positional_argument(Vector<const char*>& value, const char* help_string, const char* name, Required required = Required::Yes);
-
-private:
- Vector<Option> m_options;
- Vector<Arg> m_positional_args;
-
- bool m_show_help { false };
- const char* m_general_help { nullptr };
-};
-
-}
diff --git a/Libraries/LibCore/CMakeLists.txt b/Libraries/LibCore/CMakeLists.txt
deleted file mode 100644
index de16c64990..0000000000
--- a/Libraries/LibCore/CMakeLists.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-set(SOURCES
- Account.cpp
- ArgsParser.cpp
- ConfigFile.cpp
- Command.cpp
- DateTime.cpp
- DirectoryWatcher.cpp
- DirIterator.cpp
- ElapsedTimer.cpp
- Event.cpp
- EventLoop.cpp
- File.cpp
- GetPassword.cpp
- Gzip.cpp
- IODevice.cpp
- LocalServer.cpp
- LocalSocket.cpp
- MimeData.cpp
- NetworkJob.cpp
- NetworkResponse.cpp
- Notifier.cpp
- Object.cpp
- ProcessStatisticsReader.cpp
- Property.cpp
- puff.cpp
- SocketAddress.cpp
- Socket.cpp
- StandardPaths.cpp
- TCPServer.cpp
- TCPSocket.cpp
- Timer.cpp
- UDPServer.cpp
- UDPSocket.cpp
-)
-
-serenity_lib(LibCore core)
-target_link_libraries(LibCore LibC LibCrypt)
diff --git a/Libraries/LibCore/Command.cpp b/Libraries/LibCore/Command.cpp
deleted file mode 100644
index e4fb717473..0000000000
--- a/Libraries/LibCore/Command.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "Command.h"
-#include <AK/ByteBuffer.h>
-#include <AK/LogStream.h>
-#include <AK/ScopeGuard.h>
-#include <LibCore/File.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-// #define DBG_FAILED_COMMANDS
-
-namespace Core {
-
-// Only supported in serenity mode because we use `posix_spawn_file_actions_addchdir`
-#ifdef __serenity__
-
-String command(const String& command_string, Optional<LexicalPath> chdir)
-{
- auto parts = command_string.split(' ');
- if (parts.is_empty())
- return {};
- auto program = parts[0];
- parts.remove(0);
- return command(program, parts, chdir);
-}
-
-String command(const String& program, const Vector<String>& arguments, Optional<LexicalPath> chdir)
-{
- int stdout_pipe[2] = {};
- int stderr_pipe[2] = {};
- if (pipe2(stdout_pipe, O_CLOEXEC)) {
- perror("pipe2");
- ASSERT_NOT_REACHED();
- }
- if (pipe2(stderr_pipe, O_CLOEXEC)) {
- perror("pipe2");
- ASSERT_NOT_REACHED();
- }
-
- auto close_pipes = ScopeGuard([stderr_pipe, stdout_pipe] {
- // The write-ends of these pipes are closed manually
- close(stdout_pipe[0]);
- close(stderr_pipe[0]);
- });
-
- Vector<const char*> parts = { program.characters() };
- for (const auto& part : arguments) {
- parts.append(part.characters());
- }
- parts.append(nullptr);
-
- const char** argv = parts.data();
-
- posix_spawn_file_actions_t action;
- posix_spawn_file_actions_init(&action);
- if (chdir.has_value()) {
- posix_spawn_file_actions_addchdir(&action, chdir.value().string().characters());
- }
- posix_spawn_file_actions_adddup2(&action, stdout_pipe[1], STDOUT_FILENO);
- posix_spawn_file_actions_adddup2(&action, stderr_pipe[1], STDERR_FILENO);
-
- pid_t pid;
- if ((errno = posix_spawnp(&pid, program.characters(), &action, nullptr, const_cast<char**>(argv), environ))) {
- perror("posix_spawn");
- ASSERT_NOT_REACHED();
- }
- int wstatus;
- waitpid(pid, &wstatus, 0);
- posix_spawn_file_actions_destroy(&action);
-
- // close the write-ends so reading wouldn't block
- close(stdout_pipe[1]);
- close(stderr_pipe[1]);
-
- auto read_all_from_pipe = [](int pipe[2]) {
- auto result_file = Core::File::construct();
- if (!result_file->open(pipe[0], Core::IODevice::ReadOnly, Core::File::ShouldCloseFileDescriptor::Yes)) {
- perror("open");
- ASSERT_NOT_REACHED();
- }
- return String::copy(result_file->read_all());
- };
-
- if (WEXITSTATUS(wstatus) != 0) {
-# ifdef DBG_FAILED_COMMANDS
- dbgln("command failed. stderr: {}", read_all_from_pipe(stderr_pipe));
-# endif
- return {};
- }
-
- auto result = read_all_from_pipe(stdout_pipe);
- if (result.is_null())
- return "";
- return result;
-}
-
-#endif
-
-}
diff --git a/Libraries/LibCore/Command.h b/Libraries/LibCore/Command.h
deleted file mode 100644
index 725c6b55a2..0000000000
--- a/Libraries/LibCore/Command.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/LexicalPath.h>
-#include <AK/Optional.h>
-#include <AK/String.h>
-#include <spawn.h>
-
-namespace Core {
-
-// If the executed command fails, the returned String will be in the null state.
-String command(const String& program, const Vector<String>& arguments, Optional<LexicalPath> chdir);
-String command(const String& command_string, Optional<LexicalPath> chdir);
-
-}
diff --git a/Libraries/LibCore/ConfigFile.cpp b/Libraries/LibCore/ConfigFile.cpp
deleted file mode 100644
index cb7e68576c..0000000000
--- a/Libraries/LibCore/ConfigFile.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/ByteBuffer.h>
-#include <AK/StringBuilder.h>
-#include <LibCore/ConfigFile.h>
-#include <LibCore/File.h>
-#include <LibCore/StandardPaths.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <unistd.h>
-
-namespace Core {
-
-NonnullRefPtr<ConfigFile> ConfigFile::get_for_lib(const String& lib_name)
-{
- String directory = StandardPaths::config_directory();
- auto path = String::formatted("{}/lib/{}.ini", directory, lib_name);
-
- return adopt(*new ConfigFile(path));
-}
-
-NonnullRefPtr<ConfigFile> ConfigFile::get_for_app(const String& app_name)
-{
- String directory = StandardPaths::config_directory();
- auto path = String::formatted("{}/{}.ini", directory, app_name);
- return adopt(*new ConfigFile(path));
-}
-
-NonnullRefPtr<ConfigFile> ConfigFile::get_for_system(const String& app_name)
-{
- auto path = String::formatted("/etc/{}.ini", app_name);
- return adopt(*new ConfigFile(path));
-}
-
-NonnullRefPtr<ConfigFile> ConfigFile::open(const String& path)
-{
- return adopt(*new ConfigFile(path));
-}
-
-ConfigFile::ConfigFile(const String& file_name)
- : m_file_name(file_name)
-{
- reparse();
-}
-
-ConfigFile::~ConfigFile()
-{
- sync();
-}
-
-void ConfigFile::reparse()
-{
- m_groups.clear();
-
- auto file = File::construct(m_file_name);
- if (!file->open(IODevice::OpenMode::ReadOnly))
- return;
-
- HashMap<String, String>* current_group = nullptr;
-
- while (file->can_read_line()) {
- auto line = file->read_line();
- auto* cp = line.characters();
-
- while (*cp && (*cp == ' ' || *cp == '\t' || *cp == '\n'))
- ++cp;
-
- switch (*cp) {
- case '\0': // EOL...
- case '#': // Comment, skip entire line.
- case ';': // -||-
- continue;
- case '[': { // Start of new group.
- StringBuilder builder;
- ++cp; // Skip the '['
- while (*cp && (*cp != ']'))
- builder.append(*(cp++));
- current_group = &m_groups.ensure(builder.to_string());
- break;
- }
- default: { // Start of key{
- StringBuilder key_builder;
- StringBuilder value_builder;
- while (*cp && (*cp != '='))
- key_builder.append(*(cp++));
- ++cp; // Skip the '='
- while (*cp && (*cp != '\n'))
- value_builder.append(*(cp++));
- if (!current_group) {
- // We're not in a group yet, create one with the name ""...
- current_group = &m_groups.ensure("");
- }
- current_group->set(key_builder.to_string(), value_builder.to_string());
- }
- }
- }
-}
-
-String ConfigFile::read_entry(const String& group, const String& key, const String& default_value) const
-{
- if (!has_key(group, key)) {
- return default_value;
- }
- auto it = m_groups.find(group);
- auto jt = it->value.find(key);
- return jt->value;
-}
-
-int ConfigFile::read_num_entry(const String& group, const String& key, int default_value) const
-{
- if (!has_key(group, key)) {
- return default_value;
- }
-
- return read_entry(group, key).to_int().value_or(default_value);
-}
-
-bool ConfigFile::read_bool_entry(const String& group, const String& key, bool default_value) const
-{
- auto value = read_entry(group, key, default_value ? "1" : "0");
- if (value == "1" || value.to_lowercase() == "true")
- return 1;
- return 0;
-}
-
-void ConfigFile::write_entry(const String& group, const String& key, const String& value)
-{
- m_groups.ensure(group).ensure(key) = value;
- m_dirty = true;
-}
-
-void ConfigFile::write_num_entry(const String& group, const String& key, int value)
-{
- write_entry(group, key, String::number(value));
-}
-void ConfigFile::write_bool_entry(const String& group, const String& key, bool value)
-{
- write_entry(group, key, value ? "1" : "0");
-}
-void ConfigFile::write_color_entry(const String& group, const String& key, Color value)
-{
- write_entry(group, key, String::formatted("{},{},{},{}", value.red(), value.green(), value.blue(), value.alpha()));
-}
-
-bool ConfigFile::sync()
-{
- if (!m_dirty)
- return true;
-
- FILE* fp = fopen(m_file_name.characters(), "wb");
- if (!fp)
- return false;
-
- for (auto& it : m_groups) {
- outln(fp, "[{}]", it.key);
- for (auto& jt : it.value)
- outln(fp, "{}={}", jt.key, jt.value);
- outln(fp);
- }
-
- fclose(fp);
-
- m_dirty = false;
- return true;
-}
-
-void ConfigFile::dump() const
-{
- for (auto& it : m_groups) {
- outln("[{}]", it.key);
- for (auto& jt : it.value)
- outln("{}={}", jt.key, jt.value);
- outln();
- }
-}
-
-Vector<String> ConfigFile::groups() const
-{
- return m_groups.keys();
-}
-
-Vector<String> ConfigFile::keys(const String& group) const
-{
- auto it = m_groups.find(group);
- if (it == m_groups.end())
- return {};
- return it->value.keys();
-}
-
-bool ConfigFile::has_key(const String& group, const String& key) const
-{
- auto it = m_groups.find(group);
- if (it == m_groups.end())
- return {};
- return it->value.contains(key);
-}
-
-bool ConfigFile::has_group(const String& group) const
-{
- return m_groups.contains(group);
-}
-
-void ConfigFile::remove_group(const String& group)
-{
- m_groups.remove(group);
- m_dirty = true;
-}
-
-void ConfigFile::remove_entry(const String& group, const String& key)
-{
- auto it = m_groups.find(group);
- if (it == m_groups.end())
- return;
- it->value.remove(key);
- m_dirty = true;
-}
-
-}
diff --git a/Libraries/LibCore/ConfigFile.h b/Libraries/LibCore/ConfigFile.h
deleted file mode 100644
index 24865a0e48..0000000000
--- a/Libraries/LibCore/ConfigFile.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/HashMap.h>
-#include <AK/RefCounted.h>
-#include <AK/RefPtr.h>
-#include <AK/String.h>
-#include <AK/Vector.h>
-#include <LibGfx/Color.h>
-
-namespace Core {
-
-class ConfigFile : public RefCounted<ConfigFile> {
-public:
- static NonnullRefPtr<ConfigFile> get_for_lib(const String& lib_name);
- static NonnullRefPtr<ConfigFile> get_for_app(const String& app_name);
- static NonnullRefPtr<ConfigFile> get_for_system(const String& app_name);
- static NonnullRefPtr<ConfigFile> open(const String& path);
- ~ConfigFile();
-
- bool has_group(const String&) const;
- bool has_key(const String& group, const String& key) const;
-
- Vector<String> groups() const;
- Vector<String> keys(const String& group) const;
-
- String read_entry(const String& group, const String& key, const String& default_value = String()) const;
- int read_num_entry(const String& group, const String& key, int default_value = 0) const;
- bool read_bool_entry(const String& group, const String& key, bool default_value = false) const;
-
- void write_entry(const String& group, const String& key, const String& value);
- void write_num_entry(const String& group, const String& key, int value);
- void write_bool_entry(const String& group, const String& key, bool value);
- void write_color_entry(const String& group, const String& key, Color value);
-
- void dump() const;
-
- bool is_dirty() const { return m_dirty; }
-
- bool sync();
-
- void remove_group(const String& group);
- void remove_entry(const String& group, const String& key);
-
- String file_name() const { return m_file_name; }
-
-private:
- explicit ConfigFile(const String& file_name);
-
- void reparse();
-
- String m_file_name;
- HashMap<String, HashMap<String, String>> m_groups;
- bool m_dirty { false };
-};
-
-}
diff --git a/Libraries/LibCore/DateTime.cpp b/Libraries/LibCore/DateTime.cpp
deleted file mode 100644
index 804abac3de..0000000000
--- a/Libraries/LibCore/DateTime.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/StringBuilder.h>
-#include <AK/Time.h>
-#include <LibCore/DateTime.h>
-#include <sys/time.h>
-#include <time.h>
-
-namespace Core {
-
-DateTime DateTime::now()
-{
- return from_timestamp(time(nullptr));
-}
-
-DateTime DateTime::create(unsigned year, unsigned month, unsigned day, unsigned hour, unsigned minute, unsigned second)
-{
- DateTime dt;
- dt.set_time(year, month, day, hour, minute, second);
- return dt;
-}
-
-DateTime DateTime::from_timestamp(time_t timestamp)
-{
- struct tm tm;
- localtime_r(&timestamp, &tm);
- DateTime dt;
- dt.m_year = tm.tm_year + 1900;
- dt.m_month = tm.tm_mon + 1;
- dt.m_day = tm.tm_mday;
- dt.m_hour = tm.tm_hour;
- dt.m_minute = tm.tm_min;
- dt.m_second = tm.tm_sec;
- dt.m_timestamp = timestamp;
- return dt;
-}
-
-unsigned DateTime::weekday() const
-{
- return ::day_of_week(m_year, m_month, m_day);
-}
-
-unsigned DateTime::days_in_month() const
-{
- return ::days_in_month(m_year, m_month);
-}
-
-unsigned DateTime::day_of_year() const
-{
- return ::day_of_year(m_year, m_month, m_day);
-}
-
-bool DateTime::is_leap_year() const
-{
- return ::is_leap_year(m_year);
-}
-
-void DateTime::set_time(unsigned year, unsigned month, unsigned day, unsigned hour, unsigned minute, unsigned second)
-{
- struct tm tm = {};
- tm.tm_sec = (int)second;
- tm.tm_min = (int)minute;
- tm.tm_hour = (int)hour;
- tm.tm_mday = (int)day;
- tm.tm_mon = (int)month - 1;
- tm.tm_year = (int)year - 1900;
- tm.tm_isdst = -1;
- // mktime() doesn't read tm.tm_wday and tm.tm_yday, no need to fill them in.
-
- m_timestamp = mktime(&tm);
-
- // mktime() normalizes the components to the right ranges (Jan 32 -> Feb 1 etc), so read fields back out from tm.
- m_year = tm.tm_year + 1900;
- m_month = tm.tm_mon + 1;
- m_day = tm.tm_mday;
- m_hour = tm.tm_hour;
- m_minute = tm.tm_min;
- m_second = tm.tm_sec;
-}
-
-String DateTime::to_string(const String& format) const
-{
-
- const char wday_short_names[7][4] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- };
- const char wday_long_names[7][10] = {
- "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
- };
- const char mon_short_names[12][4] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- const char mon_long_names[12][10] = {
- "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"
- };
-
- struct tm tm;
- localtime_r(&m_timestamp, &tm);
- StringBuilder builder;
- const int format_len = format.length();
-
- for (int i = 0; i < format_len; ++i) {
- if (format[i] != '%') {
- builder.append(format[i]);
- } else {
- if (++i == format_len)
- return String();
-
- switch (format[i]) {
- case 'a':
- builder.append(wday_short_names[tm.tm_wday]);
- break;
- case 'A':
- builder.append(wday_long_names[tm.tm_wday]);
- break;
- case 'b':
- builder.append(mon_short_names[tm.tm_mon]);
- break;
- case 'B':
- builder.append(mon_long_names[tm.tm_mon]);
- break;
- case 'C':
- builder.appendf("%02d", (tm.tm_year + 1900) / 100);
- break;
- case 'd':
- builder.appendf("%02d", tm.tm_mday);
- break;
- case 'D':
- builder.appendf("%02d/%02d/%02d", tm.tm_mon + 1, tm.tm_mday, (tm.tm_year + 1900) % 100);
- break;
- case 'e':
- builder.appendf("%2d", tm.tm_mday);
- break;
- case 'h':
- builder.append(mon_short_names[tm.tm_mon]);
- break;
- case 'H':
- builder.appendf("%02d", tm.tm_hour);
- break;
- case 'I':
- builder.appendf("%02d", tm.tm_hour % 12);
- break;
- case 'j':
- builder.appendf("%03d", tm.tm_yday + 1);
- break;
- case 'm':
- builder.appendf("%02d", tm.tm_mon + 1);
- break;
- case 'M':
- builder.appendf("%02d", tm.tm_min);
- break;
- case 'n':
- builder.append('\n');
- break;
- case 'p':
- builder.append(tm.tm_hour < 12 ? "a.m." : "p.m.");
- break;
- case 'r':
- builder.appendf("%02d:%02d:%02d %s", tm.tm_hour % 12, tm.tm_min, tm.tm_sec, tm.tm_hour < 12 ? "a.m." : "p.m.");
- break;
- case 'R':
- builder.appendf("%02d:%02d", tm.tm_hour, tm.tm_min);
- break;
- case 'S':
- builder.appendf("%02d", tm.tm_sec);
- break;
- case 't':
- builder.append('\t');
- break;
- case 'T':
- builder.appendf("%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
- break;
- case 'u':
- builder.appendf("%d", tm.tm_wday ? tm.tm_wday : 7);
- break;
- case 'U': {
- const int wday_of_year_beginning = (tm.tm_wday + 6 * tm.tm_yday) % 7;
- const int week_number = (tm.tm_yday + wday_of_year_beginning) / 7;
- builder.appendf("%02d", week_number);
- break;
- }
- case 'V': {
- const int wday_of_year_beginning = (tm.tm_wday + 6 + 6 * tm.tm_yday) % 7;
- int week_number = (tm.tm_yday + wday_of_year_beginning) / 7 + 1;
- if (wday_of_year_beginning > 3) {
- if (tm.tm_yday >= 7 - wday_of_year_beginning)
- --week_number;
- else {
- const int days_of_last_year = days_in_year(tm.tm_year + 1900 - 1);
- const int wday_of_last_year_beginning = (wday_of_year_beginning + 6 * days_of_last_year) % 7;
- week_number = (days_of_last_year + wday_of_last_year_beginning) / 7 + 1;
- if (wday_of_last_year_beginning > 3)
- --week_number;
- }
- }
- builder.appendf("%02d", week_number);
- break;
- }
- case 'w':
- builder.appendf("%d", tm.tm_wday);
- break;
- case 'W': {
- const int wday_of_year_beginning = (tm.tm_wday + 6 + 6 * tm.tm_yday) % 7;
- const int week_number = (tm.tm_yday + wday_of_year_beginning) / 7;
- builder.appendf("%02d", week_number);
- break;
- }
- case 'y':
- builder.appendf("%02d", (tm.tm_year + 1900) % 100);
- break;
- case 'Y':
- builder.appendf("%d", tm.tm_year + 1900);
- break;
- case '%':
- builder.append('%');
- break;
- default:
- return String();
- }
- }
- }
-
- return builder.build();
-}
-
-bool DateTime::is_before(const String& other) const
-{
- auto now_string = String::formatted("{:04}{:02}{:02}{:02}{:02}{:02}Z", year(), month(), weekday(), hour(), minute(), second());
- return __builtin_strcasecmp(now_string.characters(), other.characters()) < 0;
-}
-
-const LogStream& operator<<(const LogStream& stream, const DateTime& value)
-{
- return stream << value.to_string();
-}
-
-}
diff --git a/Libraries/LibCore/DateTime.h b/Libraries/LibCore/DateTime.h
deleted file mode 100644
index 15515cc0fd..0000000000
--- a/Libraries/LibCore/DateTime.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/String.h>
-#include <time.h>
-
-namespace Core {
-
-// Represents a time in local time.
-class DateTime {
-public:
- time_t timestamp() const { return m_timestamp; }
-
- unsigned year() const { return m_year; }
- unsigned month() const { return m_month; }
- unsigned day() const { return m_day; }
-
- unsigned hour() const { return m_hour; }
- unsigned minute() const { return m_minute; }
- unsigned second() const { return m_second; }
- unsigned weekday() const;
- unsigned days_in_month() const;
- unsigned day_of_year() const;
- bool is_leap_year() const;
-
- void set_time(unsigned year, unsigned month = 1, unsigned day = 0, unsigned hour = 0, unsigned minute = 0, unsigned second = 0);
- String to_string(const String& format = "%Y-%m-%d %H:%M:%S") const;
-
- static DateTime create(unsigned year, unsigned month = 1, unsigned day = 0, unsigned hour = 0, unsigned minute = 0, unsigned second = 0);
- static DateTime now();
- static DateTime from_timestamp(time_t);
-
- // FIXME: This should be replaced with a proper comparison
- // operator when we get the equivalent of strptime
- bool is_before(const String&) const;
-
-private:
- time_t m_timestamp { 0 };
- unsigned m_year { 0 };
- unsigned m_month { 0 };
- unsigned m_day { 0 };
- unsigned m_hour { 0 };
- unsigned m_minute { 0 };
- unsigned m_second { 0 };
-};
-
-const LogStream& operator<<(const LogStream&, const DateTime&);
-
-}
diff --git a/Libraries/LibCore/DirIterator.cpp b/Libraries/LibCore/DirIterator.cpp
deleted file mode 100644
index 3dbeecf24f..0000000000
--- a/Libraries/LibCore/DirIterator.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/Vector.h>
-#include <LibCore/DirIterator.h>
-#include <errno.h>
-
-namespace Core {
-
-DirIterator::DirIterator(const StringView& path, Flags flags)
- : m_path(path)
- , m_flags(flags)
-{
- m_dir = opendir(path.to_string().characters());
- if (!m_dir) {
- m_error = errno;
- }
-}
-
-DirIterator::~DirIterator()
-{
- if (m_dir) {
- closedir(m_dir);
- m_dir = nullptr;
- }
-}
-
-bool DirIterator::advance_next()
-{
- if (!m_dir)
- return false;
-
- while (true) {
- errno = 0;
- auto* de = readdir(m_dir);
- if (!de) {
- m_error = errno;
- m_next = String();
- return false;
- }
-
- m_next = de->d_name;
- if (m_next.is_null())
- return false;
-
- if (m_flags & Flags::SkipDots && m_next.starts_with('.'))
- continue;
-
- if (m_flags & Flags::SkipParentAndBaseDir && (m_next == "." || m_next == ".."))
- continue;
-
- return !m_next.is_empty();
- }
-}
-
-bool DirIterator::has_next()
-{
- if (!m_next.is_null())
- return true;
-
- return advance_next();
-}
-
-String DirIterator::next_path()
-{
- if (m_next.is_null())
- advance_next();
-
- auto tmp = m_next;
- m_next = String();
- return tmp;
-}
-
-String DirIterator::next_full_path()
-{
- return String::formatted("{}/{}", m_path, next_path());
-}
-
-String find_executable_in_path(String filename)
-{
- if (filename.starts_with('/')) {
- if (access(filename.characters(), X_OK) == 0)
- return filename;
-
- return {};
- }
-
- for (auto directory : String { getenv("PATH") }.split(':')) {
- auto fullpath = String::formatted("{}/{}", directory, filename);
-
- if (access(fullpath.characters(), X_OK) == 0)
- return fullpath;
- }
-
- return {};
-}
-
-}
diff --git a/Libraries/LibCore/DirIterator.h b/Libraries/LibCore/DirIterator.h
deleted file mode 100644
index 7f423b4f17..0000000000
--- a/Libraries/LibCore/DirIterator.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/String.h>
-#include <dirent.h>
-#include <string.h>
-
-namespace Core {
-
-class DirIterator {
-public:
- enum Flags {
- NoFlags = 0x0,
- SkipDots = 0x1,
- SkipParentAndBaseDir = 0x2,
- };
-
- DirIterator(const StringView& path, Flags = Flags::NoFlags);
- ~DirIterator();
-
- bool has_error() const { return m_error != 0; }
- int error() const { return m_error; }
- const char* error_string() const { return strerror(m_error); }
- bool has_next();
- String next_path();
- String next_full_path();
-
-private:
- DIR* m_dir = nullptr;
- int m_error = 0;
- String m_next;
- String m_path;
- int m_flags;
-
- bool advance_next();
-};
-
-String find_executable_in_path(String filename);
-
-}
diff --git a/Libraries/LibCore/DirectoryWatcher.cpp b/Libraries/LibCore/DirectoryWatcher.cpp
deleted file mode 100644
index a363c2461d..0000000000
--- a/Libraries/LibCore/DirectoryWatcher.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "DirectoryWatcher.h"
-#include <AK/LexicalPath.h>
-#include <AK/Optional.h>
-#include <LibCore/DirIterator.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-namespace Core {
-
-// Only supported in serenity mode because we use `watch_file`
-#ifdef __serenity__
-
-DirectoryWatcher::DirectoryWatcher(const String& path)
- : m_path(path)
-{
- m_watcher_fd = watch_file(path.characters(), path.length());
- ASSERT(m_watcher_fd != -1);
-}
-
-DirectoryWatcher::~DirectoryWatcher()
-{
- close(m_watcher_fd);
-}
-
-Optional<DirectoryWatcher::Event> DirectoryWatcher::wait_for_event()
-{
- InodeWatcherEvent event {};
- int rc = read(m_watcher_fd, &event, sizeof(event));
- if (rc <= 0)
- return {};
-
- Event result;
- if (event.type == InodeWatcherEvent::Type::ChildAdded)
- result.type = Event::Type::ChildAdded;
- else if (event.type == InodeWatcherEvent::Type::ChildRemoved)
- result.type = Event::Type::ChildRemoved;
- else
- return {};
-
- auto child_path = get_child_with_inode_index(event.inode_index);
- if (!LexicalPath(child_path).is_valid())
- return {};
-
- result.child_path = child_path;
- return result;
-}
-
-String DirectoryWatcher::get_child_with_inode_index(unsigned child_inode_index) const
-{
- DirIterator iterator(m_path, Core::DirIterator::SkipDots);
- if (iterator.has_error()) {
- return {};
- }
-
- while (iterator.has_next()) {
- auto child_full_path = String::formatted("{}/{}", m_path, iterator.next_path());
- struct stat st;
-
- if (lstat(child_full_path.characters(), &st)) {
- return {};
- }
-
- if (st.st_ino == child_inode_index) {
- return child_full_path;
- }
- }
- return {};
-}
-
-#endif
-
-}
diff --git a/Libraries/LibCore/DirectoryWatcher.h b/Libraries/LibCore/DirectoryWatcher.h
deleted file mode 100644
index 63be2c1aa7..0000000000
--- a/Libraries/LibCore/DirectoryWatcher.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Function.h>
-#include <AK/Noncopyable.h>
-#include <AK/String.h>
-#include <Kernel/API/InodeWatcherEvent.h>
-
-namespace Core {
-
-class DirectoryWatcher {
- AK_MAKE_NONCOPYABLE(DirectoryWatcher);
-
-public:
- explicit DirectoryWatcher(const String& path);
- ~DirectoryWatcher();
-
- struct Event {
- enum class Type {
- ChildAdded,
- ChildRemoved,
- };
- Type type;
- String child_path;
- };
-
- Optional<Event> wait_for_event();
-
-private:
- String get_child_with_inode_index(unsigned) const;
-
- String m_path;
- int m_watcher_fd { -1 };
-};
-
-}
diff --git a/Libraries/LibCore/ElapsedTimer.cpp b/Libraries/LibCore/ElapsedTimer.cpp
deleted file mode 100644
index 9d0fc95378..0000000000
--- a/Libraries/LibCore/ElapsedTimer.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/Assertions.h>
-#include <AK/Time.h>
-#include <LibCore/ElapsedTimer.h>
-#include <sys/time.h>
-#include <time.h>
-
-namespace Core {
-
-void ElapsedTimer::start()
-{
- m_valid = true;
- timespec now_spec;
- clock_gettime(m_precise ? CLOCK_MONOTONIC : CLOCK_MONOTONIC_COARSE, &now_spec);
- m_origin_time.tv_sec = now_spec.tv_sec;
- m_origin_time.tv_usec = now_spec.tv_nsec / 1000;
-}
-
-int ElapsedTimer::elapsed() const
-{
- ASSERT(is_valid());
- struct timeval now;
- timespec now_spec;
- clock_gettime(m_precise ? CLOCK_MONOTONIC : CLOCK_MONOTONIC_COARSE, &now_spec);
- now.tv_sec = now_spec.tv_sec;
- now.tv_usec = now_spec.tv_nsec / 1000;
- struct timeval diff;
- timeval_sub(now, m_origin_time, diff);
- return diff.tv_sec * 1000 + diff.tv_usec / 1000;
-}
-
-}
diff --git a/Libraries/LibCore/ElapsedTimer.h b/Libraries/LibCore/ElapsedTimer.h
deleted file mode 100644
index 224eb139e3..0000000000
--- a/Libraries/LibCore/ElapsedTimer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <sys/time.h>
-
-namespace Core {
-
-class ElapsedTimer {
-public:
- ElapsedTimer(bool precise = false)
- : m_precise(precise)
- {
- }
-
- bool is_valid() const { return m_valid; }
- void start();
- int elapsed() const;
-
- const struct timeval& origin_time() const { return m_origin_time; }
-
-private:
- bool m_precise { false };
- bool m_valid { false };
- struct timeval m_origin_time {
- 0, 0
- };
-};
-
-}
diff --git a/Libraries/LibCore/Event.cpp b/Libraries/LibCore/Event.cpp
deleted file mode 100644
index fac44e5537..0000000000
--- a/Libraries/LibCore/Event.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/WeakPtr.h>
-#include <LibCore/Event.h>
-#include <LibCore/Object.h>
-
-namespace Core {
-
-ChildEvent::ChildEvent(Type type, Object& child, Object* insertion_before_child)
- : Core::Event(type)
- , m_child(child.make_weak_ptr())
- , m_insertion_before_child(AK::try_make_weak_ptr(insertion_before_child))
-{
-}
-
-ChildEvent::~ChildEvent()
-{
-}
-
-Object* ChildEvent::child()
-{
- if (auto ref = m_child.strong_ref())
- return ref.ptr();
- return nullptr;
-}
-
-const Object* ChildEvent::child() const
-{
- if (auto ref = m_child.strong_ref())
- return ref.ptr();
- return nullptr;
-}
-
-Object* ChildEvent::insertion_before_child()
-{
- if (auto ref = m_insertion_before_child.strong_ref())
- return ref.ptr();
- return nullptr;
-}
-
-const Object* ChildEvent::insertion_before_child() const
-{
- if (auto ref = m_insertion_before_child.strong_ref())
- return ref.ptr();
- return nullptr;
-}
-
-}
diff --git a/Libraries/LibCore/Event.h b/Libraries/LibCore/Event.h
deleted file mode 100644
index 46dc3dc375..0000000000
--- a/Libraries/LibCore/Event.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Function.h>
-#include <AK/String.h>
-#include <AK/Types.h>
-#include <AK/WeakPtr.h>
-#include <LibCore/Forward.h>
-
-namespace Core {
-
-class Event {
-public:
- enum Type {
- Invalid = 0,
- Quit,
- Timer,
- NotifierRead,
- NotifierWrite,
- DeferredInvoke,
- ChildAdded,
- ChildRemoved,
- Custom,
- };
-
- Event() { }
- explicit Event(unsigned type)
- : m_type(type)
- {
- }
- virtual ~Event() { }
-
- unsigned type() const { return m_type; }
-
- bool is_accepted() const { return m_accepted; }
- void accept() { m_accepted = true; }
- void ignore() { m_accepted = false; }
-
-private:
- unsigned m_type { Type::Invalid };
- bool m_accepted { true };
-};
-
-class DeferredInvocationEvent : public Event {
- friend class EventLoop;
-
-public:
- DeferredInvocationEvent(Function<void(Object&)> invokee)
- : Event(Event::Type::DeferredInvoke)
- , m_invokee(move(invokee))
- {
- }
-
-private:
- Function<void(Object&)> m_invokee;
-};
-
-class TimerEvent final : public Event {
-public:
- explicit TimerEvent(int timer_id)
- : Event(Event::Timer)
- , m_timer_id(timer_id)
- {
- }
- ~TimerEvent() { }
-
- int timer_id() const { return m_timer_id; }
-
-private:
- int m_timer_id;
-};
-
-class NotifierReadEvent final : public Event {
-public:
- explicit NotifierReadEvent(int fd)
- : Event(Event::NotifierRead)
- , m_fd(fd)
- {
- }
- ~NotifierReadEvent() { }
-
- int fd() const { return m_fd; }
-
-private:
- int m_fd;
-};
-
-class NotifierWriteEvent final : public Event {
-public:
- explicit NotifierWriteEvent(int fd)
- : Event(Event::NotifierWrite)
- , m_fd(fd)
- {
- }
- ~NotifierWriteEvent() { }
-
- int fd() const { return m_fd; }
-
-private:
- int m_fd;
-};
-
-class ChildEvent final : public Event {
-public:
- ChildEvent(Type, Object& child, Object* insertion_before_child = nullptr);
- ~ChildEvent();
-
- Object* child();
- const Object* child() const;
-
- Object* insertion_before_child();
- const Object* insertion_before_child() const;
-
-private:
- WeakPtr<Object> m_child;
- WeakPtr<Object> m_insertion_before_child;
-};
-
-class CustomEvent : public Event {
-public:
- CustomEvent(int custom_type)
- : Event(Event::Type::Custom)
- , m_custom_type(custom_type)
- {
- }
- ~CustomEvent() { }
-
- int custom_type() const { return m_custom_type; }
-
-private:
- int m_custom_type { 0 };
-};
-
-}
diff --git a/Libraries/LibCore/EventLoop.cpp b/Libraries/LibCore/EventLoop.cpp
deleted file mode 100644
index c13cc986ea..0000000000
--- a/Libraries/LibCore/EventLoop.cpp
+++ /dev/null
@@ -1,835 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/Badge.h>
-#include <AK/ByteBuffer.h>
-#include <AK/IDAllocator.h>
-#include <AK/JsonObject.h>
-#include <AK/JsonValue.h>
-#include <AK/NeverDestroyed.h>
-#include <AK/Singleton.h>
-#include <AK/TemporaryChange.h>
-#include <AK/Time.h>
-#include <LibCore/Event.h>
-#include <LibCore/EventLoop.h>
-#include <LibCore/LocalServer.h>
-#include <LibCore/LocalSocket.h>
-#include <LibCore/Notifier.h>
-#include <LibCore/Object.h>
-#include <LibCore/SyscallUtils.h>
-#include <LibThread/Lock.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-
-//#define EVENTLOOP_DEBUG
-//#define DEFERRED_INVOKE_DEBUG
-
-namespace Core {
-
-class RPCClient;
-
-struct EventLoopTimer {
- int timer_id { 0 };
- int interval { 0 };
- timeval fire_time { 0, 0 };
- bool should_reload { false };
- TimerShouldFireWhenNotVisible fire_when_not_visible { TimerShouldFireWhenNotVisible::No };
- WeakPtr<Object> owner;
-
- void reload(const timeval& now);
- bool has_expired(const timeval& now) const;
-};
-
-struct EventLoop::Private {
- LibThread::Lock lock;
-};
-
-static EventLoop* s_main_event_loop;
-static Vector<EventLoop*>* s_event_loop_stack;
-static NeverDestroyed<IDAllocator> s_id_allocator;
-static HashMap<int, NonnullOwnPtr<EventLoopTimer>>* s_timers;
-static HashTable<Notifier*>* s_notifiers;
-int EventLoop::s_wake_pipe_fds[2];
-static RefPtr<LocalServer> s_rpc_server;
-HashMap<int, RefPtr<RPCClient>> s_rpc_clients;
-
-class SignalHandlers : public RefCounted<SignalHandlers> {
- AK_MAKE_NONCOPYABLE(SignalHandlers);
- AK_MAKE_NONMOVABLE(SignalHandlers);
-
-public:
- SignalHandlers(int signo, void (*handle_signal)(int));
- ~SignalHandlers();
-
- void dispatch();
- int add(Function<void(int)>&& handler);
- bool remove(int handler_id);
-
- bool is_empty() const
- {
- if (m_calling_handlers) {
- for (auto& handler : m_handlers_pending) {
- if (handler.value)
- return false; // an add is pending
- }
- }
- return m_handlers.is_empty();
- }
-
- bool have(int handler_id) const
- {
- if (m_calling_handlers) {
- auto it = m_handlers_pending.find(handler_id);
- if (it != m_handlers_pending.end()) {
- if (!it->value)
- return false; // a deletion is pending
- }
- }
- return m_handlers.contains(handler_id);
- }
-
- int m_signo;
- void (*m_original_handler)(int); // TODO: can't use sighandler_t?
- HashMap<int, Function<void(int)>> m_handlers;
- HashMap<int, Function<void(int)>> m_handlers_pending;
- bool m_calling_handlers { false };
-};
-
-struct SignalHandlersInfo {
- HashMap<int, NonnullRefPtr<SignalHandlers>> signal_handlers;
- int next_signal_id { 0 };
-};
-
-template<bool create_if_null = true>
-inline SignalHandlersInfo* signals_info()
-{
- static SignalHandlersInfo* s_signals;
- return AK::Singleton<SignalHandlersInfo>::get(s_signals);
-}
-
-pid_t EventLoop::s_pid;
-
-class RPCClient : public Object {
- C_OBJECT(RPCClient)
-public:
- explicit RPCClient(RefPtr<LocalSocket> socket)
- : m_socket(move(socket))
- , m_client_id(s_id_allocator->allocate())
- {
- s_rpc_clients.set(m_client_id, this);
- add_child(*m_socket);
- m_socket->on_ready_to_read = [this] {
- u32 length;
- int nread = m_socket->read((u8*)&length, sizeof(length));
- if (nread == 0) {
-#ifdef EVENTLOOP_DEBUG
- dbgln("RPC client disconnected");
-#endif
- shutdown();
- return;
- }
- ASSERT(nread == sizeof(length));
- auto request = m_socket->read(length);
-
- auto request_json = JsonValue::from_string(request);
- if (!request_json.has_value() || !request_json.value().is_object()) {
- dbgln("RPC client sent invalid request");
- shutdown();
- return;
- }
-
- handle_request(request_json.value().as_object());
- };
- }
- virtual ~RPCClient() override
- {
- if (auto inspected_object = m_inspected_object.strong_ref())
- inspected_object->decrement_inspector_count({});
- }
-
- void send_response(const JsonObject& response)
- {
- auto serialized = response.to_string();
- u32 length = serialized.length();
- m_socket->write((const u8*)&length, sizeof(length));
- m_socket->write(serialized);
- }
-
- void handle_request(const JsonObject& request)
- {
- auto type = request.get("type").as_string_or({});
-
- if (type.is_null()) {
- dbgln("RPC client sent request without type field");
- return;
- }
-
- if (type == "Identify") {
- JsonObject response;
- response.set("type", type);
- response.set("pid", getpid());
-#ifdef __serenity__
- char buffer[1024];
- if (get_process_name(buffer, sizeof(buffer)) >= 0) {
- response.set("process_name", buffer);
- } else {
- response.set("process_name", JsonValue());
- }
-#endif
- send_response(response);
- return;
- }
-
- if (type == "GetAllObjects") {
- JsonObject response;
- response.set("type", type);
- JsonArray objects;
- for (auto& object : Object::all_objects()) {
- JsonObject json_object;
- object.save_to(json_object);
- objects.append(move(json_object));
- }
- response.set("objects", move(objects));
- send_response(response);
- return;
- }
-
- if (type == "SetInspectedObject") {
- auto address = request.get("address").to_number<FlatPtr>();
- for (auto& object : Object::all_objects()) {
- if ((FlatPtr)&object == address) {
- if (auto inspected_object = m_inspected_object.strong_ref())
- inspected_object->decrement_inspector_count({});
- m_inspected_object = object;
- object.increment_inspector_count({});
- break;
- }
- }
- return;
- }
-
- if (type == "SetProperty") {
- auto address = request.get("address").to_number<FlatPtr>();
- for (auto& object : Object::all_objects()) {
- if ((FlatPtr)&object == address) {
- bool success = object.set_property(request.get("name").to_string(), request.get("value"));
- JsonObject response;
- response.set("type", "SetProperty");
- response.set("success", success);
- send_response(response);
- break;
- }
- }
- return;
- }
-
- if (type == "Disconnect") {
- shutdown();
- return;
- }
- }
-
- void shutdown()
- {
- s_rpc_clients.remove(m_client_id);
- s_id_allocator->deallocate(m_client_id);
- }
-
-private:
- RefPtr<LocalSocket> m_socket;
- WeakPtr<Object> m_inspected_object;
- int m_client_id { -1 };
-};
-
-EventLoop::EventLoop()
- : m_private(make<Private>())
-{
- if (!s_event_loop_stack) {
- s_event_loop_stack = new Vector<EventLoop*>;
- s_timers = new HashMap<int, NonnullOwnPtr<EventLoopTimer>>;
- s_notifiers = new HashTable<Notifier*>;
- }
-
- if (!s_main_event_loop) {
- s_main_event_loop = this;
- s_pid = getpid();
-#if defined(SOCK_NONBLOCK)
- int rc = pipe2(s_wake_pipe_fds, O_CLOEXEC);
-#else
- int rc = pipe(s_wake_pipe_fds);
- fcntl(s_wake_pipe_fds[0], F_SETFD, FD_CLOEXEC);
- fcntl(s_wake_pipe_fds[1], F_SETFD, FD_CLOEXEC);
-
-#endif
- ASSERT(rc == 0);
- s_event_loop_stack->append(this);
-
- if (!s_rpc_server) {
- if (!start_rpc_server())
- dbgln("Core::EventLoop: Failed to start an RPC server");
- }
- }
-
-#ifdef EVENTLOOP_DEBUG
- dbgln("{} Core::EventLoop constructed :)", getpid());
-#endif
-}
-
-EventLoop::~EventLoop()
-{
-}
-
-bool EventLoop::start_rpc_server()
-{
- s_rpc_server = LocalServer::construct();
- s_rpc_server->set_name("Core::EventLoop_RPC_server");
- s_rpc_server->on_ready_to_accept = [&] {
- RPCClient::construct(s_rpc_server->accept());
- };
- return s_rpc_server->listen(String::formatted("/tmp/rpc/{}", getpid()));
-}
-
-EventLoop& EventLoop::main()
-{
- ASSERT(s_main_event_loop);
- return *s_main_event_loop;
-}
-
-EventLoop& EventLoop::current()
-{
- EventLoop* event_loop = s_event_loop_stack->last();
- ASSERT(event_loop != nullptr);
- return *event_loop;
-}
-
-void EventLoop::quit(int code)
-{
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop::quit({})", code);
-#endif
- m_exit_requested = true;
- m_exit_code = code;
-}
-
-void EventLoop::unquit()
-{
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop::unquit()");
-#endif
- m_exit_requested = false;
- m_exit_code = 0;
-}
-
-struct EventLoopPusher {
-public:
- EventLoopPusher(EventLoop& event_loop)
- : m_event_loop(event_loop)
- {
- if (&m_event_loop != s_main_event_loop) {
- m_event_loop.take_pending_events_from(EventLoop::current());
- s_event_loop_stack->append(&event_loop);
- }
- }
- ~EventLoopPusher()
- {
- if (&m_event_loop != s_main_event_loop) {
- s_event_loop_stack->take_last();
- EventLoop::current().take_pending_events_from(m_event_loop);
- }
- }
-
-private:
- EventLoop& m_event_loop;
-};
-
-int EventLoop::exec()
-{
- EventLoopPusher pusher(*this);
- for (;;) {
- if (m_exit_requested)
- return m_exit_code;
- pump();
- }
- ASSERT_NOT_REACHED();
-}
-
-void EventLoop::pump(WaitMode mode)
-{
- wait_for_event(mode);
-
- decltype(m_queued_events) events;
- {
- LOCKER(m_private->lock);
- events = move(m_queued_events);
- }
-
- for (size_t i = 0; i < events.size(); ++i) {
- auto& queued_event = events.at(i);
- auto receiver = queued_event.receiver.strong_ref();
- auto& event = *queued_event.event;
-#ifdef EVENTLOOP_DEBUG
- if (receiver)
- dbgln("Core::EventLoop: {} event {}", *receiver, event.type());
-#endif
- if (!receiver) {
- switch (event.type()) {
- case Event::Quit:
- ASSERT_NOT_REACHED();
- return;
- default:
-#ifdef EVENTLOOP_DEBUG
- dbgln("Event type {} with no receiver :(", event.type());
-#endif
- break;
- }
- } else if (event.type() == Event::Type::DeferredInvoke) {
-#ifdef DEFERRED_INVOKE_DEBUG
- dbgln("DeferredInvoke: receiver = {}", *receiver);
-#endif
- static_cast<DeferredInvocationEvent&>(event).m_invokee(*receiver);
- } else {
- NonnullRefPtr<Object> protector(*receiver);
- receiver->dispatch_event(event);
- }
-
- if (m_exit_requested) {
- LOCKER(m_private->lock);
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop: Exit requested. Rejigging {} events.", events.size() - i);
-#endif
- decltype(m_queued_events) new_event_queue;
- new_event_queue.ensure_capacity(m_queued_events.size() + events.size());
- for (++i; i < events.size(); ++i)
- new_event_queue.unchecked_append(move(events[i]));
- new_event_queue.append(move(m_queued_events));
- m_queued_events = move(new_event_queue);
- return;
- }
- }
-}
-
-void EventLoop::post_event(Object& receiver, NonnullOwnPtr<Event>&& event)
-{
- LOCKER(m_private->lock);
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop::post_event: ({}) << receivier={}, event={}", m_queued_events.size(), receiver, event);
-#endif
- m_queued_events.empend(receiver, move(event));
-}
-
-SignalHandlers::SignalHandlers(int signo, void (*handle_signal)(int))
- : m_signo(signo)
- , m_original_handler(signal(signo, handle_signal))
-{
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop: Registered handler for signal {}", m_signo);
-#endif
-}
-
-SignalHandlers::~SignalHandlers()
-{
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop: Unregistering handler for signal {}", m_signo);
-#endif
- signal(m_signo, m_original_handler);
-}
-
-void SignalHandlers::dispatch()
-{
- TemporaryChange change(m_calling_handlers, true);
- for (auto& handler : m_handlers)
- handler.value(m_signo);
- if (!m_handlers_pending.is_empty()) {
- // Apply pending adds/removes
- for (auto& handler : m_handlers_pending) {
- if (handler.value) {
- auto result = m_handlers.set(handler.key, move(handler.value));
- ASSERT(result == AK::HashSetResult::InsertedNewEntry);
- } else {
- m_handlers.remove(handler.key);
- }
- }
- m_handlers_pending.clear();
- }
-}
-
-int SignalHandlers::add(Function<void(int)>&& handler)
-{
- int id = ++signals_info()->next_signal_id; // TODO: worry about wrapping and duplicates?
- if (m_calling_handlers)
- m_handlers_pending.set(id, move(handler));
- else
- m_handlers.set(id, move(handler));
- return id;
-}
-
-bool SignalHandlers::remove(int handler_id)
-{
- ASSERT(handler_id != 0);
- if (m_calling_handlers) {
- auto it = m_handlers.find(handler_id);
- if (it != m_handlers.end()) {
- // Mark pending remove
- m_handlers_pending.set(handler_id, {});
- return true;
- }
- it = m_handlers_pending.find(handler_id);
- if (it != m_handlers_pending.end()) {
- if (!it->value)
- return false; // already was marked as deleted
- it->value = nullptr;
- return true;
- }
- return false;
- }
- return m_handlers.remove(handler_id);
-}
-
-void EventLoop::dispatch_signal(int signo)
-{
- auto& info = *signals_info();
- auto handlers = info.signal_handlers.find(signo);
- if (handlers != info.signal_handlers.end()) {
- // Make sure we bump the ref count while dispatching the handlers!
- // This allows a handler to unregister/register while the handlers
- // are being called!
- auto handler = handlers->value;
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop: dispatching signal {}", signo);
-#endif
- handler->dispatch();
- }
-}
-
-void EventLoop::handle_signal(int signo)
-{
- ASSERT(signo != 0);
- // We MUST check if the current pid still matches, because there
- // is a window between fork() and exec() where a signal delivered
- // to our fork could be inadvertedly routed to the parent process!
- if (getpid() == s_pid) {
- int nwritten = write(s_wake_pipe_fds[1], &signo, sizeof(signo));
- if (nwritten < 0) {
- perror("EventLoop::register_signal: write");
- ASSERT_NOT_REACHED();
- }
- } else {
- // We're a fork who received a signal, reset s_pid
- s_pid = 0;
- }
-}
-
-int EventLoop::register_signal(int signo, Function<void(int)> handler)
-{
- ASSERT(signo != 0);
- auto& info = *signals_info();
- auto handlers = info.signal_handlers.find(signo);
- if (handlers == info.signal_handlers.end()) {
- auto signal_handlers = adopt(*new SignalHandlers(signo, EventLoop::handle_signal));
- auto handler_id = signal_handlers->add(move(handler));
- info.signal_handlers.set(signo, move(signal_handlers));
- return handler_id;
- } else {
- return handlers->value->add(move(handler));
- }
-}
-
-void EventLoop::unregister_signal(int handler_id)
-{
- ASSERT(handler_id != 0);
- int remove_signo = 0;
- auto& info = *signals_info();
- for (auto& h : info.signal_handlers) {
- auto& handlers = *h.value;
- if (handlers.remove(handler_id)) {
- if (handlers.is_empty())
- remove_signo = handlers.m_signo;
- break;
- }
- }
- if (remove_signo != 0)
- info.signal_handlers.remove(remove_signo);
-}
-
-void EventLoop::notify_forked(ForkEvent event)
-{
- switch (event) {
- case ForkEvent::Child:
- s_main_event_loop = nullptr;
- s_event_loop_stack->clear();
- s_timers->clear();
- s_notifiers->clear();
- if (auto* info = signals_info<false>()) {
- info->signal_handlers.clear();
- info->next_signal_id = 0;
- }
- s_pid = 0;
- s_rpc_server = nullptr;
- s_rpc_clients.clear();
- return;
- }
-
- ASSERT_NOT_REACHED();
-}
-
-void EventLoop::wait_for_event(WaitMode mode)
-{
- fd_set rfds;
- fd_set wfds;
-retry:
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
-
- int max_fd = 0;
- auto add_fd_to_set = [&max_fd](int fd, fd_set& set) {
- FD_SET(fd, &set);
- if (fd > max_fd)
- max_fd = fd;
- };
-
- int max_fd_added = -1;
- add_fd_to_set(s_wake_pipe_fds[0], rfds);
- max_fd = max(max_fd, max_fd_added);
- for (auto& notifier : *s_notifiers) {
- if (notifier->event_mask() & Notifier::Read)
- add_fd_to_set(notifier->fd(), rfds);
- if (notifier->event_mask() & Notifier::Write)
- add_fd_to_set(notifier->fd(), wfds);
- if (notifier->event_mask() & Notifier::Exceptional)
- ASSERT_NOT_REACHED();
- }
-
- bool queued_events_is_empty;
- {
- LOCKER(m_private->lock);
- queued_events_is_empty = m_queued_events.is_empty();
- }
-
- timeval now;
- struct timeval timeout = { 0, 0 };
- bool should_wait_forever = false;
- if (mode == WaitMode::WaitForEvents && queued_events_is_empty) {
- auto next_timer_expiration = get_next_timer_expiration();
- if (next_timer_expiration.has_value()) {
- timespec now_spec;
- clock_gettime(CLOCK_MONOTONIC_COARSE, &now_spec);
- now.tv_sec = now_spec.tv_sec;
- now.tv_usec = now_spec.tv_nsec / 1000;
- timeval_sub(next_timer_expiration.value(), now, timeout);
- if (timeout.tv_sec < 0 || (timeout.tv_sec == 0 && timeout.tv_usec < 0)) {
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- }
- } else {
- should_wait_forever = true;
- }
- }
-
-try_select_again:
- int marked_fd_count = select(max_fd + 1, &rfds, &wfds, nullptr, should_wait_forever ? nullptr : &timeout);
- if (marked_fd_count < 0) {
- int saved_errno = errno;
- if (saved_errno == EINTR) {
- if (m_exit_requested)
- return;
- goto try_select_again;
- }
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop::wait_for_event: {} ({}: {})", marked_fd_count, saved_errno, strerror(saved_errno));
-#endif
- // Blow up, similar to Core::safe_syscall.
- ASSERT_NOT_REACHED();
- }
- if (FD_ISSET(s_wake_pipe_fds[0], &rfds)) {
- int wake_events[8];
- auto nread = read(s_wake_pipe_fds[0], wake_events, sizeof(wake_events));
- if (nread < 0) {
- perror("read from wake pipe");
- ASSERT_NOT_REACHED();
- }
- ASSERT(nread > 0);
- bool wake_requested = false;
- int event_count = nread / sizeof(wake_events[0]);
- for (int i = 0; i < event_count; i++) {
- if (wake_events[i] != 0)
- dispatch_signal(wake_events[i]);
- else
- wake_requested = true;
- }
-
- if (!wake_requested && nread == sizeof(wake_events))
- goto retry;
- }
-
- if (!s_timers->is_empty()) {
- timespec now_spec;
- clock_gettime(CLOCK_MONOTONIC_COARSE, &now_spec);
- now.tv_sec = now_spec.tv_sec;
- now.tv_usec = now_spec.tv_nsec / 1000;
- }
-
- for (auto& it : *s_timers) {
- auto& timer = *it.value;
- if (!timer.has_expired(now))
- continue;
- auto owner = timer.owner.strong_ref();
- if (timer.fire_when_not_visible == TimerShouldFireWhenNotVisible::No
- && owner && !owner->is_visible_for_timer_purposes()) {
- continue;
- }
-#ifdef EVENTLOOP_DEBUG
- dbgln("Core::EventLoop: Timer {} has expired, sending Core::TimerEvent to {}", timer.timer_id, *owner);
-#endif
- if (owner)
- post_event(*owner, make<TimerEvent>(timer.timer_id));
- if (timer.should_reload) {
- timer.reload(now);
- } else {
- // FIXME: Support removing expired timers that don't want to reload.
- ASSERT_NOT_REACHED();
- }
- }
-
- if (!marked_fd_count)
- return;
-
- for (auto& notifier : *s_notifiers) {
- if (FD_ISSET(notifier->fd(), &rfds)) {
- if (notifier->event_mask() & Notifier::Event::Read)
- post_event(*notifier, make<NotifierReadEvent>(notifier->fd()));
- }
- if (FD_ISSET(notifier->fd(), &wfds)) {
- if (notifier->event_mask() & Notifier::Event::Write)
- post_event(*notifier, make<NotifierWriteEvent>(notifier->fd()));
- }
- }
-}
-
-bool EventLoopTimer::has_expired(const timeval& now) const
-{
- return now.tv_sec > fire_time.tv_sec || (now.tv_sec == fire_time.tv_sec && now.tv_usec >= fire_time.tv_usec);
-}
-
-void EventLoopTimer::reload(const timeval& now)
-{
- fire_time = now;
- fire_time.tv_sec += interval / 1000;
- fire_time.tv_usec += (interval % 1000) * 1000;
-}
-
-Optional<struct timeval> EventLoop::get_next_timer_expiration()
-{
- Optional<struct timeval> soonest {};
- for (auto& it : *s_timers) {
- auto& fire_time = it.value->fire_time;
- auto owner = it.value->owner.strong_ref();
- if (it.value->fire_when_not_visible == TimerShouldFireWhenNotVisible::No
- && owner && !owner->is_visible_for_timer_purposes()) {
- continue;
- }
- if (!soonest.has_value() || fire_time.tv_sec < soonest.value().tv_sec || (fire_time.tv_sec == soonest.value().tv_sec && fire_time.tv_usec < soonest.value().tv_usec))
- soonest = fire_time;
- }
- return soonest;
-}
-
-int EventLoop::register_timer(Object& object, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible fire_when_not_visible)
-{
- ASSERT(milliseconds >= 0);
- auto timer = make<EventLoopTimer>();
- timer->owner = object;
- timer->interval = milliseconds;
- timeval now;
- timespec now_spec;
- clock_gettime(CLOCK_MONOTONIC_COARSE, &now_spec);
- now.tv_sec = now_spec.tv_sec;
- now.tv_usec = now_spec.tv_nsec / 1000;
- timer->reload(now);
- timer->should_reload = should_reload;
- timer->fire_when_not_visible = fire_when_not_visible;
- int timer_id = s_id_allocator->allocate();
- timer->timer_id = timer_id;
- s_timers->set(timer_id, move(timer));
- return timer_id;
-}
-
-bool EventLoop::unregister_timer(int timer_id)
-{
- s_id_allocator->deallocate(timer_id);
- auto it = s_timers->find(timer_id);
- if (it == s_timers->end())
- return false;
- s_timers->remove(it);
- return true;
-}
-
-void EventLoop::register_notifier(Badge<Notifier>, Notifier& notifier)
-{
- s_notifiers->set(&notifier);
-}
-
-void EventLoop::unregister_notifier(Badge<Notifier>, Notifier& notifier)
-{
- s_notifiers->remove(&notifier);
-}
-
-void EventLoop::wake()
-{
- int wake_event = 0;
- int nwritten = write(s_wake_pipe_fds[1], &wake_event, sizeof(wake_event));
- if (nwritten < 0) {
- perror("EventLoop::wake: write");
- ASSERT_NOT_REACHED();
- }
-}
-
-EventLoop::QueuedEvent::QueuedEvent(Object& receiver, NonnullOwnPtr<Event> event)
- : receiver(receiver)
- , event(move(event))
-{
-}
-
-EventLoop::QueuedEvent::QueuedEvent(QueuedEvent&& other)
- : receiver(other.receiver)
- , event(move(other.event))
-{
-}
-
-EventLoop::QueuedEvent::~QueuedEvent()
-{
-}
-
-}
diff --git a/Libraries/LibCore/EventLoop.h b/Libraries/LibCore/EventLoop.h
deleted file mode 100644
index d299b93407..0000000000
--- a/Libraries/LibCore/EventLoop.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Forward.h>
-#include <AK/Function.h>
-#include <AK/HashMap.h>
-#include <AK/Noncopyable.h>
-#include <AK/NonnullOwnPtr.h>
-#include <AK/Vector.h>
-#include <AK/WeakPtr.h>
-#include <LibCore/Forward.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-namespace Core {
-
-class EventLoop {
-public:
- EventLoop();
- ~EventLoop();
-
- int exec();
-
- enum class WaitMode {
- WaitForEvents,
- PollForEvents,
- };
-
- // processe events, generally called by exec() in a loop.
- // this should really only be used for integrating with other event loops
- void pump(WaitMode = WaitMode::WaitForEvents);
-
- void post_event(Object& receiver, NonnullOwnPtr<Event>&&);
-
- static EventLoop& main();
- static EventLoop& current();
-
- bool was_exit_requested() const { return m_exit_requested; }
-
- static int register_timer(Object&, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible);
- static bool unregister_timer(int timer_id);
-
- static void register_notifier(Badge<Notifier>, Notifier&);
- static void unregister_notifier(Badge<Notifier>, Notifier&);
-
- void quit(int);
- void unquit();
-
- void take_pending_events_from(EventLoop& other)
- {
- m_queued_events.append(move(other.m_queued_events));
- }
-
- static void wake();
-
- static int register_signal(int signo, Function<void(int)> handler);
- static void unregister_signal(int handler_id);
-
- // Note: Boost uses Parent/Child/Prepare, but we don't really have anything
- // interesting to do in the parent or before forking.
- enum class ForkEvent {
- Child,
- };
- static void notify_forked(ForkEvent);
-
-private:
- bool start_rpc_server();
- void wait_for_event(WaitMode);
- Optional<struct timeval> get_next_timer_expiration();
- static void dispatch_signal(int);
- static void handle_signal(int);
-
- struct QueuedEvent {
- AK_MAKE_NONCOPYABLE(QueuedEvent);
-
- public:
- QueuedEvent(Object& receiver, NonnullOwnPtr<Event>);
- QueuedEvent(QueuedEvent&&);
- ~QueuedEvent();
-
- WeakPtr<Object> receiver;
- NonnullOwnPtr<Event> event;
- };
-
- Vector<QueuedEvent, 64> m_queued_events;
- static pid_t s_pid;
-
- bool m_exit_requested { false };
- int m_exit_code { 0 };
-
- static int s_wake_pipe_fds[2];
-
- struct Private;
- NonnullOwnPtr<Private> m_private;
-};
-
-}
diff --git a/Libraries/LibCore/File.cpp b/Libraries/LibCore/File.cpp
deleted file mode 100644
index 07192a9b18..0000000000
--- a/Libraries/LibCore/File.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef __serenity__
-# include <Kernel/API/Syscall.h>
-#endif
-#include <AK/ScopeGuard.h>
-#include <LibCore/File.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-namespace Core {
-
-Result<NonnullRefPtr<File>, String> File::open(const String& filename, IODevice::OpenMode mode, mode_t permissions)
-{
- auto file = File::construct(filename);
- if (!file->open_impl(mode, permissions))
- return String(file->error_string());
- return file;
-}
-
-File::File(const StringView& filename, Object* parent)
- : IODevice(parent)
- , m_filename(filename)
-{
-}
-
-File::~File()
-{
- if (m_should_close_file_descriptor == ShouldCloseFileDescriptor::Yes && mode() != NotOpen)
- close();
-}
-
-bool File::open(int fd, IODevice::OpenMode mode, ShouldCloseFileDescriptor should_close)
-{
- set_fd(fd);
- set_mode(mode);
- m_should_close_file_descriptor = should_close;
- return true;
-}
-
-bool File::open(IODevice::OpenMode mode)
-{
- return open_impl(mode, 0666);
-}
-
-bool File::open_impl(IODevice::OpenMode mode, mode_t permissions)
-{
- ASSERT(!m_filename.is_null());
- int flags = 0;
- if ((mode & IODevice::ReadWrite) == IODevice::ReadWrite) {
- flags |= O_RDWR | O_CREAT;
- } else if (mode & IODevice::ReadOnly) {
- flags |= O_RDONLY;
- } else if (mode & IODevice::WriteOnly) {
- flags |= O_WRONLY | O_CREAT;
- bool should_truncate = !((mode & IODevice::Append) || (mode & IODevice::MustBeNew));
- if (should_truncate)
- flags |= O_TRUNC;
- }
- if (mode & IODevice::Append)
- flags |= O_APPEND;
- if (mode & IODevice::Truncate)
- flags |= O_TRUNC;
- if (mode & IODevice::MustBeNew)
- flags |= O_EXCL;
- int fd = ::open(m_filename.characters(), flags, permissions);
- if (fd < 0) {
- set_error(errno);
- return false;
- }
-
- set_fd(fd);
- set_mode(mode);
- return true;
-}
-
-bool File::is_directory() const
-{
- struct stat stat;
- if (fstat(fd(), &stat) < 0)
- return false;
- return S_ISDIR(stat.st_mode);
-}
-
-bool File::is_directory(const String& filename)
-{
- struct stat st;
- if (stat(filename.characters(), &st) < 0)
- return false;
- return S_ISDIR(st.st_mode);
-}
-
-bool File::exists(const String& filename)
-{
- struct stat st;
- return stat(filename.characters(), &st) == 0;
-}
-
-String File::real_path_for(const String& filename)
-{
- if (filename.is_null())
- return {};
- auto* path = realpath(filename.characters(), nullptr);
- String real_path(path);
- free(path);
- return real_path;
-}
-
-bool File::ensure_parent_directories(const String& path)
-{
- ASSERT(path.starts_with("/"));
-
- int saved_errno = 0;
- ScopeGuard restore_errno = [&saved_errno] { errno = saved_errno; };
-
- char* parent_buffer = strdup(path.characters());
- ScopeGuard free_buffer = [parent_buffer] { free(parent_buffer); };
-
- const char* parent = dirname(parent_buffer);
-
- int rc = mkdir(parent, 0755);
- saved_errno = errno;
-
- if (rc == 0 || errno == EEXIST)
- return true;
-
- if (errno != ENOENT)
- return false;
-
- bool ok = ensure_parent_directories(parent);
- saved_errno = errno;
- if (!ok)
- return false;
-
- rc = mkdir(parent, 0755);
- saved_errno = errno;
- return rc == 0;
-}
-
-#ifdef __serenity__
-
-String File::read_link(const StringView& link_path)
-{
- // First, try using a 64-byte buffer, that ought to be enough for anybody.
- char small_buffer[64];
- Syscall::SC_readlink_params small_params {
- { link_path.characters_without_null_termination(), link_path.length() },
- { small_buffer, sizeof(small_buffer) }
- };
- int rc = syscall(SC_readlink, &small_params);
- if (rc < 0) {
- errno = -rc;
- return {};
- }
- size_t size = rc;
- // If the call was successful, the syscall (unlike the LibC wrapper)
- // returns the full size of the link. Let's see if our small buffer
- // was enough to read the whole link.
- if (size <= sizeof(small_buffer))
- return { small_buffer, size };
- // Nope, but at least now we know the right size.
- char* large_buffer_ptr;
- auto large_buffer = StringImpl::create_uninitialized(size, large_buffer_ptr);
- Syscall::SC_readlink_params large_params {
- { link_path.characters_without_null_termination(), link_path.length() },
- { large_buffer_ptr, (size_t)size }
- };
- rc = syscall(SC_readlink, &large_params);
- if (rc < 0) {
- errno = -rc;
- return {};
- }
- size_t new_size = rc;
- if (new_size == size)
- return { *large_buffer };
-
- // If we're here, the symlink has changed while we were looking at it.
- // If it became shorter, our buffer is valid, we just have to trim it a bit.
- if (new_size < size)
- return { large_buffer_ptr, new_size };
- // Otherwise, here's not much we can do, unless we want to loop endlessly
- // in this case. Let's leave it up to the caller whether to loop.
- errno = -EAGAIN;
- return {};
-}
-
-#else
-
-// This is a sad version for other systems. It has to always make a copy of the
-// link path, and to always make two syscalls to get the right size first.
-String File::read_link(const StringView& link_path)
-{
- String link_path_str = link_path;
- struct stat statbuf;
- int rc = lstat(link_path_str.characters(), &statbuf);
- if (rc < 0)
- return {};
- char* buffer_ptr;
- auto buffer = StringImpl::create_uninitialized(statbuf.st_size, buffer_ptr);
- rc = readlink(link_path_str.characters(), buffer_ptr, statbuf.st_size);
- if (rc < 0)
- return {};
- // (See above.)
- if (rc == statbuf.st_size)
- return { *buffer };
- return { buffer_ptr, (size_t)rc };
-}
-
-#endif
-
-static RefPtr<File> stdin_file;
-static RefPtr<File> stdout_file;
-static RefPtr<File> stderr_file;
-
-NonnullRefPtr<File> File::standard_input()
-{
- if (!stdin_file) {
- stdin_file = File::construct();
- stdin_file->open(STDIN_FILENO, IODevice::ReadOnly, ShouldCloseFileDescriptor::No);
- }
- return *stdin_file;
-}
-
-NonnullRefPtr<File> File::standard_output()
-{
- if (!stdout_file) {
- stdout_file = File::construct();
- stdout_file->open(STDOUT_FILENO, IODevice::WriteOnly, ShouldCloseFileDescriptor::No);
- }
- return *stdout_file;
-}
-
-NonnullRefPtr<File> File::standard_error()
-{
- if (!stderr_file) {
- stderr_file = File::construct();
- stderr_file->open(STDERR_FILENO, IODevice::WriteOnly, ShouldCloseFileDescriptor::No);
- }
- return *stderr_file;
-}
-}
diff --git a/Libraries/LibCore/File.h b/Libraries/LibCore/File.h
deleted file mode 100644
index 040a2813b7..0000000000
--- a/Libraries/LibCore/File.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Result.h>
-#include <AK/String.h>
-#include <LibCore/IODevice.h>
-
-namespace Core {
-
-class File final : public IODevice {
- C_OBJECT(File)
-public:
- virtual ~File() override;
-
- static Result<NonnullRefPtr<File>, String> open(const String& filename, IODevice::OpenMode, mode_t = 0644);
-
- String filename() const { return m_filename; }
- void set_filename(const StringView& filename) { m_filename = filename; }
-
- bool is_directory() const;
- static bool is_directory(const String& filename);
-
- static bool exists(const String& filename);
- static String real_path_for(const String& filename);
- static String read_link(const StringView& link_path);
- static bool ensure_parent_directories(const String& path);
-
- virtual bool open(IODevice::OpenMode) override;
-
- enum class ShouldCloseFileDescriptor {
- No = 0,
- Yes
- };
- bool open(int fd, IODevice::OpenMode, ShouldCloseFileDescriptor);
-
- static NonnullRefPtr<File> standard_input();
- static NonnullRefPtr<File> standard_output();
- static NonnullRefPtr<File> standard_error();
-
-private:
- File(Object* parent = nullptr)
- : IODevice(parent)
- {
- }
- explicit File(const StringView&, Object* parent = nullptr);
-
- bool open_impl(IODevice::OpenMode, mode_t);
-
- String m_filename;
- ShouldCloseFileDescriptor m_should_close_file_descriptor { ShouldCloseFileDescriptor::Yes };
-};
-
-}
diff --git a/Libraries/LibCore/FileStream.h b/Libraries/LibCore/FileStream.h
deleted file mode 100644
index 0c8774d28a..0000000000
--- a/Libraries/LibCore/FileStream.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2020, the SerenityOS developers.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Buffered.h>
-#include <AK/ByteBuffer.h>
-#include <AK/Stream.h>
-#include <LibCore/File.h>
-
-namespace Core {
-
-class InputFileStream final : public InputStream {
-public:
- explicit InputFileStream(NonnullRefPtr<File> file)
- : m_file(file)
- {
- }
-
- static Result<InputFileStream, String> open(StringView filename, IODevice::OpenMode mode = IODevice::OpenMode::ReadOnly, mode_t permissions = 0644)
- {
- ASSERT((mode & 0xf) == IODevice::OpenMode::ReadOnly || (mode & 0xf) == IODevice::OpenMode::ReadWrite);
-
- auto file_result = File::open(filename, mode, permissions);
-
- if (file_result.is_error())
- return file_result.error();
-
- return InputFileStream { file_result.value() };
- }
-
- static Result<Buffered<InputFileStream>, String> open_buffered(StringView filename, IODevice::OpenMode mode = IODevice::OpenMode::ReadOnly, mode_t permissions = 0644)
- {
- ASSERT((mode & 0xf) == IODevice::OpenMode::ReadOnly || (mode & 0xf) == IODevice::OpenMode::ReadWrite);
-
- auto file_result = File::open(filename, mode, permissions);
-
- if (file_result.is_error())
- return file_result.error();
-
- return Buffered<InputFileStream> { file_result.value() };
- }
-
- size_t read(Bytes bytes) override
- {
- if (has_any_error())
- return 0;
-
- const auto buffer = m_file->read(bytes.size());
- return buffer.bytes().copy_to(bytes);
- }
-
- bool read_or_error(Bytes bytes) override
- {
- if (read(bytes) < bytes.size()) {
- set_fatal_error();
- return false;
- }
-
- return true;
- }
-
- bool discard_or_error(size_t count) override { return m_file->seek(count, IODevice::SeekMode::FromCurrentPosition); }
-
- bool unreliable_eof() const override { return m_file->eof(); }
-
- void close()
- {
- if (!m_file->close())
- set_fatal_error();
- }
-
-private:
- NonnullRefPtr<File> m_file;
-};
-
-class OutputFileStream : public OutputStream {
-public:
- explicit OutputFileStream(NonnullRefPtr<File> file)
- : m_file(file)
- {
- }
-
- static Result<OutputFileStream, String> open(StringView filename, IODevice::OpenMode mode = IODevice::OpenMode::WriteOnly, mode_t permissions = 0644)
- {
- ASSERT((mode & 0xf) == IODevice::OpenMode::WriteOnly || (mode & 0xf) == IODevice::OpenMode::ReadWrite);
-
- auto file_result = File::open(filename, mode, permissions);
-
- if (file_result.is_error())
- return file_result.error();
-
- return OutputFileStream { file_result.value() };
- }
-
- static Result<Buffered<OutputFileStream>, String> open_buffered(StringView filename, IODevice::OpenMode mode = IODevice::OpenMode::WriteOnly, mode_t permissions = 0644)
- {
- ASSERT((mode & 0xf) == IODevice::OpenMode::WriteOnly || (mode & 0xf) == IODevice::OpenMode::ReadWrite);
-
- auto file_result = File::open(filename, mode, permissions);
-
- if (file_result.is_error())
- return file_result.error();
-
- return Buffered<OutputFileStream> { file_result.value() };
- }
-
- static OutputFileStream standard_output()
- {
- return OutputFileStream { Core::File::standard_output() };
- }
-
- static Buffered<OutputFileStream> stdout_buffered()
- {
- return Buffered<OutputFileStream> { Core::File::standard_output() };
- }
-
- size_t write(ReadonlyBytes bytes) override
- {
- if (!m_file->write(bytes.data(), bytes.size())) {
- set_fatal_error();
- return 0;
- }
-
- return bytes.size();
- }
-
- bool write_or_error(ReadonlyBytes bytes) override
- {
- if (write(bytes) < bytes.size()) {
- set_fatal_error();
- return false;
- }
-
- return true;
- }
-
- void close()
- {
- if (!m_file->close())
- set_fatal_error();
- }
-
-private:
- NonnullRefPtr<File> m_file;
-};
-
-}
diff --git a/Libraries/LibCore/Forward.h b/Libraries/LibCore/Forward.h
deleted file mode 100644
index 09497cb0bf..0000000000
--- a/Libraries/LibCore/Forward.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-namespace Core {
-
-class ArgsParser;
-class ChildEvent;
-class ConfigFile;
-class CustomEvent;
-class DateTime;
-class DirIterator;
-class ElapsedTimer;
-class Event;
-class EventLoop;
-class File;
-class IODevice;
-class LocalServer;
-class LocalSocket;
-class MimeData;
-class NetworkJob;
-class NetworkResponse;
-class Notifier;
-class Object;
-class ProcessStatisticsReader;
-class Socket;
-class SocketAddress;
-class TCPServer;
-class TCPSocket;
-class Timer;
-class TimerEvent;
-class UDPServer;
-class UDPSocket;
-
-enum class TimerShouldFireWhenNotVisible;
-
-}
diff --git a/Libraries/LibCore/GetPassword.cpp b/Libraries/LibCore/GetPassword.cpp
deleted file mode 100644
index dfcff21583..0000000000
--- a/Libraries/LibCore/GetPassword.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2020, Peter Elliott <pelliott@ualberta.ca>
- * Copyright (c) 2021, Emanuele Torre <torreemanuele6@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/GetPassword.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <termios.h>
-
-namespace Core {
-
-Result<String, OSError> get_password(const StringView& prompt)
-{
- if (write(STDOUT_FILENO, prompt.characters_without_null_termination(), prompt.length()) < 0)
- return OSError(errno);
-
- termios original {};
- if (tcgetattr(STDIN_FILENO, &original) < 0)
- return OSError(errno);
-
- termios no_echo = original;
- no_echo.c_lflag &= ~ECHO;
- if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &no_echo) < 0)
- return OSError(errno);
-
- char* password = nullptr;
- size_t n = 0;
-
- auto line_length = getline(&password, &n, stdin);
- auto saved_errno = errno;
-
- tcsetattr(STDIN_FILENO, TCSAFLUSH, &original);
- putchar('\n');
-
- if (line_length < 0)
- return OSError(saved_errno);
-
- ASSERT(line_length != 0);
-
- // Remove trailing '\n' read by getline().
- password[line_length - 1] = '\0';
-
- String s(password);
- free(password);
- return s;
-}
-}
diff --git a/Libraries/LibCore/GetPassword.h b/Libraries/LibCore/GetPassword.h
deleted file mode 100644
index c62a071935..0000000000
--- a/Libraries/LibCore/GetPassword.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2020, Peter Elliott <pelliott@ualberta.ca>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/OSError.h>
-#include <AK/Result.h>
-#include <AK/String.h>
-
-namespace Core {
-
-Result<String, OSError> get_password(const StringView& prompt = "Password: ");
-
-}
diff --git a/Libraries/LibCore/Gzip.cpp b/Libraries/LibCore/Gzip.cpp
deleted file mode 100644
index 49cf14c3a0..0000000000
--- a/Libraries/LibCore/Gzip.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/ByteBuffer.h>
-#include <AK/Optional.h>
-#include <LibCore/Gzip.h>
-#include <LibCore/puff.h>
-#include <limits.h>
-#include <stddef.h>
-
-//#define DEBUG_GZIP
-
-namespace Core {
-
-bool Gzip::is_compressed(const ByteBuffer& data)
-{
- return data.size() > 2 && data[0] == 0x1F && data[1] == 0x8b;
-}
-
-// skips the gzip header
-// see: https://tools.ietf.org/html/rfc1952#page-5
-static Optional<ByteBuffer> get_gzip_payload(const ByteBuffer& data)
-{
- size_t current = 0;
- auto read_byte = [&]() {
- if (current >= data.size()) {
- ASSERT_NOT_REACHED();
- return (u8)0;
- }
- return data[current++];
- };
-
-#ifdef DEBUG_GZIP
- dbgln("get_gzip_payload: Skipping over gzip header.");
-#endif
-
- // Magic Header
- if (read_byte() != 0x1F || read_byte() != 0x8B) {
- dbgln("get_gzip_payload: Wrong magic number.");
- return Optional<ByteBuffer>();
- }
-
- // Compression method
- auto method = read_byte();
- if (method != 8) {
- dbgln("get_gzip_payload: Wrong compression method={}", method);
- return Optional<ByteBuffer>();
- }
-
- u8 flags = read_byte();
-
- // Timestamp, Extra flags, OS
- current += 6;
-
- // FEXTRA
- if (flags & 4) {
- u16 length = read_byte() & read_byte() << 8;
- dbgln("get_gzip_payload: Header has FEXTRA flag set. length={}", length);
- current += length;
- }
-
- // FNAME
- if (flags & 8) {
- dbgln("get_gzip_payload: Header has FNAME flag set.");
- while (read_byte() != '\0')
- ;
- }
-
- // FCOMMENT
- if (flags & 16) {
- dbgln("get_gzip_payload: Header has FCOMMENT flag set.");
- while (read_byte() != '\0')
- ;
- }
-
- // FHCRC
- if (flags & 2) {
- dbgln("get_gzip_payload: Header has FHCRC flag set.");
- current += 2;
- }
-
- auto new_size = data.size() - current;
-#ifdef DEBUG_GZIP
- dbg() << "get_gzip_payload: Returning slice from " << current << " with size " << new_size;
-#endif
- return data.slice(current, new_size);
-}
-
-Optional<ByteBuffer> Gzip::decompress(const ByteBuffer& data)
-{
- ASSERT(is_compressed(data));
-
-#ifdef DEBUG_GZIP
- dbg() << "Gzip::decompress: Decompressing gzip compressed data. Size = " << data.size();
-#endif
- auto optional_payload = get_gzip_payload(data);
- if (!optional_payload.has_value()) {
- return Optional<ByteBuffer>();
- }
-
- auto source = optional_payload.value();
- unsigned long source_len = source.size();
- auto destination = ByteBuffer::create_uninitialized(1024);
- while (true) {
- unsigned long destination_len = destination.size();
-
-#ifdef DEBUG_GZIP
- dbg() << "Gzip::decompress: Calling puff()\n"
- << " destination_data = " << destination.data() << "\n"
- << " destination_len = " << destination_len << "\n"
- << " source_data = " << source.data() << "\n"
- << " source_len = " << source_len;
-#endif
-
- auto puff_ret = puff(
- destination.data(), &destination_len,
- source.data(), &source_len);
-
- if (puff_ret == 0) {
-#ifdef DEBUG_GZIP
- dbgln("Gzip::decompress: Decompression success.");
-#endif
- destination.trim(destination_len);
- break;
- }
-
- if (puff_ret == 1) {
- // FIXME: Find a better way of decompressing without needing to try over and over again.
-#ifdef DEBUG_GZIP
- dbgln("Gzip::decompress: Output buffer exhausted. Growing.");
-#endif
- destination.grow(destination.size() * 2);
- } else {
- dbgln("Gzip::decompress: Error. puff() returned: {}", puff_ret);
- ASSERT_NOT_REACHED();
- }
- }
-
- return destination;
-}
-
-}
diff --git a/Libraries/LibCore/Gzip.h b/Libraries/LibCore/Gzip.h
deleted file mode 100644
index a96af59536..0000000000
--- a/Libraries/LibCore/Gzip.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/ByteBuffer.h>
-#include <AK/Optional.h>
-#include <AK/String.h>
-
-namespace Core {
-
-class Gzip {
-public:
- static bool is_compressed(const ByteBuffer& data);
- static Optional<ByteBuffer> decompress(const ByteBuffer& data);
-};
-
-}
diff --git a/Libraries/LibCore/IODevice.cpp b/Libraries/LibCore/IODevice.cpp
deleted file mode 100644
index 453526e408..0000000000
--- a/Libraries/LibCore/IODevice.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/ByteBuffer.h>
-#include <AK/PrintfImplementation.h>
-#include <LibCore/IODevice.h>
-#include <LibCore/SyscallUtils.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/select.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-namespace Core {
-
-IODevice::IODevice(Object* parent)
- : Object(parent)
-{
-}
-
-IODevice::~IODevice()
-{
-}
-
-const char* IODevice::error_string() const
-{
- return strerror(m_error);
-}
-
-int IODevice::read(u8* buffer, int length)
-{
- auto read_buffer = read(length);
- if (read_buffer.is_null())
- return 0;
- memcpy(buffer, read_buffer.data(), length);
- return read_buffer.size();
-}
-
-ByteBuffer IODevice::read(size_t max_size)
-{
- if (m_fd < 0)
- return {};
- if (!max_size)
- return {};
- auto buffer = ByteBuffer::create_uninitialized(max_size);
- auto* buffer_ptr = (char*)buffer.data();
- size_t remaining_buffer_space = buffer.size();
- size_t taken_from_buffered = 0;
- if (!m_buffered_data.is_empty()) {
- taken_from_buffered = min(remaining_buffer_space, m_buffered_data.size());
- memcpy(buffer_ptr, m_buffered_data.data(), taken_from_buffered);
- Vector<u8> new_buffered_data;
- new_buffered_data.append(m_buffered_data.data() + taken_from_buffered, m_buffered_data.size() - taken_from_buffered);
- m_buffered_data = move(new_buffered_data);
- remaining_buffer_space -= taken_from_buffered;
- buffer_ptr += taken_from_buffered;
- }
- if (!remaining_buffer_space)
- return buffer;
- int nread = ::read(m_fd, buffer_ptr, remaining_buffer_space);
- if (nread < 0) {
- if (taken_from_buffered) {
- buffer.trim(taken_from_buffered);
- return buffer;
- }
- set_error(errno);
- return {};
- }
- if (nread == 0) {
- set_eof(true);
- if (taken_from_buffered) {
- buffer.trim(taken_from_buffered);
- return buffer;
- }
- return {};
- }
- buffer.trim(taken_from_buffered + nread);
- return buffer;
-}
-
-bool IODevice::can_read_from_fd() const
-{
- // FIXME: Can we somehow remove this once Core::Socket is implemented using non-blocking sockets?
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(m_fd, &rfds);
- struct timeval timeout {
- 0, 0
- };
- int rc = Core::safe_syscall(select, m_fd + 1, &rfds, nullptr, nullptr, &timeout);
- if (rc < 0) {
- // NOTE: We don't set m_error here.
- perror("IODevice::can_read: select");
- return false;
- }
- return FD_ISSET(m_fd, &rfds);
-}
-
-bool IODevice::can_read_line() const
-{
- if (m_eof && !m_buffered_data.is_empty())
- return true;
- if (m_buffered_data.contains_slow('\n'))
- return true;
- if (!can_read_from_fd())
- return false;
- populate_read_buffer();
- if (m_eof && !m_buffered_data.is_empty())
- return true;
- return m_buffered_data.contains_slow('\n');
-}
-
-bool IODevice::can_read() const
-{
- return !m_buffered_data.is_empty() || can_read_from_fd();
-}
-
-ByteBuffer IODevice::read_all()
-{
- off_t file_size = 0;
- struct stat st;
- int rc = fstat(fd(), &st);
- if (rc == 0)
- file_size = st.st_size;
-
- Vector<u8> data;
- data.ensure_capacity(file_size);
-
- if (!m_buffered_data.is_empty()) {
- data.append(m_buffered_data.data(), m_buffered_data.size());
- m_buffered_data.clear();
- }
-
- while (true) {
- char read_buffer[4096];
- int nread = ::read(m_fd, read_buffer, sizeof(read_buffer));
- if (nread < 0) {
- set_error(errno);
- break;
- }
- if (nread == 0) {
- set_eof(true);
- break;
- }
- data.append((const u8*)read_buffer, nread);
- }
- if (data.is_empty())
- return {};
- return ByteBuffer::copy(data.data(), data.size());
-}
-
-String IODevice::read_line(size_t max_size)
-{
- if (m_fd < 0)
- return {};
- if (!max_size)
- return {};
- if (!can_read_line())
- return {};
- if (m_eof) {
- if (m_buffered_data.size() > max_size) {
- dbgprintf("IODevice::read_line: At EOF but there's more than max_size(%zu) buffered\n", max_size);
- return {};
- }
- auto line = String((const char*)m_buffered_data.data(), m_buffered_data.size(), Chomp);
- m_buffered_data.clear();
- return line;
- }
- auto line = ByteBuffer::create_uninitialized(max_size + 1);
- size_t line_index = 0;
- while (line_index < max_size) {
- u8 ch = m_buffered_data[line_index];
- line[line_index++] = ch;
- if (ch == '\n') {
- Vector<u8> new_buffered_data;
- new_buffered_data.append(m_buffered_data.data() + line_index, m_buffered_data.size() - line_index);
- m_buffered_data = move(new_buffered_data);
- line.trim(line_index);
- return String::copy(line, Chomp);
- }
- }
- return {};
-}
-
-bool IODevice::populate_read_buffer() const
-{
- if (m_fd < 0)
- return false;
- u8 buffer[1024];
- int nread = ::read(m_fd, buffer, sizeof(buffer));
- if (nread < 0) {
- set_error(errno);
- return false;
- }
- if (nread == 0) {
- set_eof(true);
- return false;
- }
- m_buffered_data.append(buffer, nread);
- return true;
-}
-
-bool IODevice::close()
-{
- if (fd() < 0 || mode() == NotOpen)
- return false;
- int rc = ::close(fd());
- if (rc < 0) {
- set_error(errno);
- return false;
- }
- set_fd(-1);
- set_mode(IODevice::NotOpen);
- return true;
-}
-
-bool IODevice::seek(i64 offset, SeekMode mode, off_t* pos)
-{
- int m = SEEK_SET;
- switch (mode) {
- case SeekMode::SetPosition:
- m = SEEK_SET;
- break;
- case SeekMode::FromCurrentPosition:
- m = SEEK_CUR;
- break;
- case SeekMode::FromEndPosition:
- m = SEEK_END;
- break;
- }
- off_t rc = lseek(m_fd, offset, m);
- if (rc < 0) {
- set_error(errno);
- if (pos)
- *pos = -1;
- return false;
- }
- m_buffered_data.clear();
- m_eof = false;
- if (pos)
- *pos = rc;
- return true;
-}
-
-bool IODevice::truncate(off_t size)
-{
- int rc = ftruncate(m_fd, size);
- if (rc < 0) {
- set_error(errno);
- return false;
- }
- return true;
-}
-
-bool IODevice::write(const u8* data, int size)
-{
- int rc = ::write(m_fd, data, size);
- if (rc < 0) {
- perror("IODevice::write: write");
- set_error(errno);
- return false;
- }
- return rc == size;
-}
-
-int IODevice::printf(const char* format, ...)
-{
- va_list ap;
- va_start(ap, format);
- // FIXME: We're not propagating write() failures to client here!
- int ret = printf_internal([this](char*&, char ch) {
- write((const u8*)&ch, 1);
- },
- nullptr, format, ap);
- va_end(ap);
- return ret;
-}
-
-void IODevice::set_fd(int fd)
-{
- if (m_fd == fd)
- return;
-
- m_fd = fd;
- did_update_fd(fd);
-}
-
-bool IODevice::write(const StringView& v)
-{
- return write((const u8*)v.characters_without_null_termination(), v.length());
-}
-
-LineIterator::LineIterator(IODevice& device, bool is_end)
- : m_device(device)
- , m_is_end(is_end)
-{
- ++*this;
-}
-
-bool LineIterator::at_end() const
-{
- return m_device->eof();
-}
-
-LineIterator& LineIterator::operator++()
-{
- m_buffer = m_device->read_line();
- return *this;
-}
-
-}
diff --git a/Libraries/LibCore/IODevice.h b/Libraries/LibCore/IODevice.h
deleted file mode 100644
index 70a75532a1..0000000000
--- a/Libraries/LibCore/IODevice.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Forward.h>
-#include <LibCore/Object.h>
-
-namespace Core {
-
-// This is not necessarily a valid iterator in all contexts,
-// if we had concepts, this would be InputIterator, not Copyable, Movable.
-class LineIterator {
- AK_MAKE_NONCOPYABLE(LineIterator);
-
-public:
- explicit LineIterator(IODevice&, bool is_end = false);
-
- bool operator==(const LineIterator& other) const { return &other == this || (at_end() && other.is_end()) || (other.at_end() && is_end()); }
- bool is_end() const { return m_is_end; }
- bool at_end() const;
-
- LineIterator& operator++();
-
- StringView operator*() const { return m_buffer; }
-
-private:
- NonnullRefPtr<IODevice> m_device;
- bool m_is_end { false };
- String m_buffer;
-};
-
-class IODevice : public Object {
- C_OBJECT_ABSTRACT(IODevice)
-public:
- enum OpenMode {
- NotOpen = 0,
- ReadOnly = 1,
- WriteOnly = 2,
- ReadWrite = 3,
- Append = 4,
- Truncate = 8,
- MustBeNew = 16,
- };
-
- virtual ~IODevice() override;
-
- int fd() const { return m_fd; }
- unsigned mode() const { return m_mode; }
- bool is_open() const { return m_mode != NotOpen; }
- bool eof() const { return m_eof; }
-
- int error() const { return m_error; }
- const char* error_string() const;
-
- bool has_error() const { return m_error != 0; }
-
- int read(u8* buffer, int length);
-
- ByteBuffer read(size_t max_size);
- ByteBuffer read_all();
- String read_line(size_t max_size = 16384);
-
- bool write(const u8*, int size);
- bool write(const StringView&);
-
- bool truncate(off_t);
-
- bool can_read_line() const;
-
- bool can_read() const;
-
- enum class SeekMode {
- SetPosition,
- FromCurrentPosition,
- FromEndPosition,
- };
-
- bool seek(i64, SeekMode = SeekMode::SetPosition, off_t* = nullptr);
-
- virtual bool open(IODevice::OpenMode) = 0;
- virtual bool close();
-
- int printf(const char*, ...);
-
- LineIterator line_begin() & { return LineIterator(*this); }
- LineIterator line_end() { return LineIterator(*this, true); }
-
-protected:
- explicit IODevice(Object* parent = nullptr);
-
- void set_fd(int);
- void set_mode(OpenMode mode) { m_mode = mode; }
- void set_error(int error) const { m_error = error; }
- void set_eof(bool eof) const { m_eof = eof; }
-
- virtual void did_update_fd(int) { }
-
-private:
- bool populate_read_buffer() const;
- bool can_read_from_fd() const;
-
- int m_fd { -1 };
- OpenMode m_mode { NotOpen };
- mutable int m_error { 0 };
- mutable bool m_eof { false };
- mutable Vector<u8> m_buffered_data;
-};
-
-}
diff --git a/Libraries/LibCore/IODeviceStreamReader.h b/Libraries/LibCore/IODeviceStreamReader.h
deleted file mode 100644
index 0339c30272..0000000000
--- a/Libraries/LibCore/IODeviceStreamReader.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/StdLibExtras.h>
-#include <LibCore/IODevice.h>
-
-namespace Core {
-
-class IODeviceStreamReader {
-public:
- IODeviceStreamReader(IODevice& device)
- : m_device(device)
- {
- }
-
- bool handle_read_failure()
- {
- return exchange(m_had_failure, false);
- }
-
- template<typename T>
- IODeviceStreamReader& operator>>(T& value)
- {
- int nread = m_device.read((u8*)&value, sizeof(T));
- ASSERT(nread == sizeof(T));
- if (nread != sizeof(T))
- m_had_failure = true;
- return *this;
- }
-
-private:
- IODevice& m_device;
- bool m_had_failure { false };
-};
-
-}
diff --git a/Libraries/LibCore/LocalServer.cpp b/Libraries/LibCore/LocalServer.cpp
deleted file mode 100644
index 092cf82388..0000000000
--- a/Libraries/LibCore/LocalServer.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/LocalServer.h>
-#include <LibCore/LocalSocket.h>
-#include <LibCore/Notifier.h>
-#include <stdio.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#ifndef SOCK_NONBLOCK
-# include <sys/ioctl.h>
-#endif
-
-namespace Core {
-
-LocalServer::LocalServer(Object* parent)
- : Object(parent)
-{
-}
-
-LocalServer::~LocalServer()
-{
- if (m_fd >= 0)
- ::close(m_fd);
-}
-
-bool LocalServer::take_over_from_system_server()
-{
- if (m_listening)
- return false;
-
- constexpr auto socket_takeover = "SOCKET_TAKEOVER";
-
- if (getenv(socket_takeover)) {
- // Sanity check: it has to be a socket.
- struct stat stat;
- int rc = fstat(3, &stat);
- if (rc == 0 && S_ISSOCK(stat.st_mode)) {
- // The SystemServer has passed us the socket as fd 3,
- // so use that instead of creating our own.
- m_fd = 3;
- // It had to be !CLOEXEC for obvious reasons, but we
- // don't need it to be !CLOEXEC anymore, so set the
- // CLOEXEC flag now.
- fcntl(m_fd, F_SETFD, FD_CLOEXEC);
- // We wouldn't want our children to think we're passing
- // them a socket either, so unset the env variable.
- unsetenv(socket_takeover);
-
- m_listening = true;
- setup_notifier();
- return true;
- } else {
- if (rc != 0)
- perror("fstat");
- dbgln("It's not a socket, what the heck??");
- }
- }
-
- dbgln("Failed to take the socket over from SystemServer");
-
- return false;
-}
-
-void LocalServer::setup_notifier()
-{
- m_notifier = Notifier::construct(m_fd, Notifier::Event::Read, this);
- m_notifier->on_ready_to_read = [this] {
- if (on_ready_to_accept)
- on_ready_to_accept();
- };
-}
-
-bool LocalServer::listen(const String& address)
-{
- if (m_listening)
- return false;
-
- int rc;
-
-#ifdef SOCK_NONBLOCK
- m_fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
-#else
- m_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
- int option = 1;
- ioctl(m_fd, FIONBIO, &option);
- fcntl(m_fd, F_SETFD, FD_CLOEXEC);
-#endif
- ASSERT(m_fd >= 0);
-#ifndef __APPLE__
- rc = fchmod(m_fd, 0600);
- if (rc < 0) {
- perror("fchmod");
- ASSERT_NOT_REACHED();
- }
-#endif
-
- auto socket_address = SocketAddress::local(address);
- auto un_optional = socket_address.to_sockaddr_un();
- if (!un_optional.has_value()) {
- perror("bind");
- return false;
- }
- auto un = un_optional.value();
- rc = ::bind(m_fd, (const sockaddr*)&un, sizeof(un));
- if (rc < 0) {
- perror("bind");
- return false;
- }
-
- rc = ::listen(m_fd, 5);
- if (rc < 0) {
- perror("listen");
- return false;
- }
-
- m_listening = true;
- setup_notifier();
- return true;
-}
-
-RefPtr<LocalSocket> LocalServer::accept()
-{
- ASSERT(m_listening);
- sockaddr_un un;
- socklen_t un_size = sizeof(un);
- int accepted_fd = ::accept(m_fd, (sockaddr*)&un, &un_size);
- if (accepted_fd < 0) {
- perror("accept");
- return nullptr;
- }
-
- return LocalSocket::construct(accepted_fd);
-}
-
-}
diff --git a/Libraries/LibCore/LocalServer.h b/Libraries/LibCore/LocalServer.h
deleted file mode 100644
index bcb4fa6c00..0000000000
--- a/Libraries/LibCore/LocalServer.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibCore/Notifier.h>
-#include <LibCore/Object.h>
-
-namespace Core {
-
-class LocalServer : public Object {
- C_OBJECT(LocalServer)
-public:
- virtual ~LocalServer() override;
-
- bool take_over_from_system_server();
- bool is_listening() const { return m_listening; }
- bool listen(const String& address);
-
- RefPtr<LocalSocket> accept();
-
- Function<void()> on_ready_to_accept;
-
-private:
- explicit LocalServer(Object* parent = nullptr);
-
- void setup_notifier();
-
- int m_fd { -1 };
- bool m_listening { false };
- RefPtr<Notifier> m_notifier;
-};
-
-}
diff --git a/Libraries/LibCore/LocalSocket.cpp b/Libraries/LibCore/LocalSocket.cpp
deleted file mode 100644
index d49aa1d166..0000000000
--- a/Libraries/LibCore/LocalSocket.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/LocalSocket.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#ifndef SOCK_NONBLOCK
-# include <sys/ioctl.h>
-#endif
-
-namespace Core {
-
-LocalSocket::LocalSocket(int fd, Object* parent)
- : Socket(Socket::Type::Local, parent)
-{
- // NOTE: This constructor is used by LocalServer::accept(), so the socket is already connected.
- m_connected = true;
- set_fd(fd);
- set_mode(IODevice::ReadWrite);
- set_error(0);
-}
-
-LocalSocket::LocalSocket(Object* parent)
- : Socket(Socket::Type::Local, parent)
-{
-
-#ifdef SOCK_NONBLOCK
- int fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
-#else
- int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
- int option = 1;
- ioctl(fd, FIONBIO, &option);
- fcntl(fd, F_SETFD, FD_CLOEXEC);
-#endif
-
- if (fd < 0) {
- set_error(errno);
- } else {
- set_fd(fd);
- set_mode(IODevice::ReadWrite);
- set_error(0);
- }
-}
-
-LocalSocket::~LocalSocket()
-{
-}
-
-RefPtr<LocalSocket> LocalSocket::take_over_accepted_socket_from_system_server()
-{
- constexpr auto socket_takeover = "SOCKET_TAKEOVER";
- if (!getenv(socket_takeover))
- return nullptr;
-
- // The SystemServer has passed us the socket as fd 3,
- // so use that instead of creating our own.
- constexpr int fd = 3;
-
- // Sanity check: it has to be a socket.
- struct stat stat;
- int rc = fstat(fd, &stat);
- if (rc < 0 || !S_ISSOCK(stat.st_mode)) {
- if (rc != 0)
- perror("fstat");
- dbgln("ERROR: The fd we got from SystemServer is not a socket");
- return nullptr;
- }
-
- auto socket = LocalSocket::construct(fd);
-
- // It had to be !CLOEXEC for obvious reasons, but we
- // don't need it to be !CLOEXEC anymore, so set the
- // CLOEXEC flag now.
- fcntl(fd, F_SETFD, FD_CLOEXEC);
- // We wouldn't want our children to think we're passing
- // them a socket either, so unset the env variable.
- unsetenv(socket_takeover);
- return socket;
-}
-
-}
diff --git a/Libraries/LibCore/LocalSocket.h b/Libraries/LibCore/LocalSocket.h
deleted file mode 100644
index 921e16aaa2..0000000000
--- a/Libraries/LibCore/LocalSocket.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibCore/Socket.h>
-
-namespace Core {
-
-class LocalSocket final : public Socket {
- C_OBJECT(LocalSocket)
-public:
- virtual ~LocalSocket() override;
-
- static RefPtr<LocalSocket> take_over_accepted_socket_from_system_server();
-
-private:
- explicit LocalSocket(Object* parent = nullptr);
- LocalSocket(int fd, Object* parent = nullptr);
-};
-
-}
diff --git a/Libraries/LibCore/MimeData.cpp b/Libraries/LibCore/MimeData.cpp
deleted file mode 100644
index e48908661c..0000000000
--- a/Libraries/LibCore/MimeData.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/StringBuilder.h>
-#include <LibCore/MimeData.h>
-
-namespace Core {
-
-Vector<String> MimeData::formats() const
-{
- Vector<String> mime_types;
- mime_types.ensure_capacity(m_data.size());
- for (auto it : m_data)
- mime_types.unchecked_append(it.key);
- return mime_types;
-}
-
-Vector<URL> MimeData::urls() const
-{
- auto it = m_data.find("text/uri-list");
- if (it == m_data.end())
- return {};
- Vector<URL> urls;
- for (auto& line : StringView(it->value).split_view('\n')) {
- urls.append(URL(line));
- }
- return urls;
-}
-
-void MimeData::set_urls(const Vector<URL>& urls)
-{
- StringBuilder builder;
- for (auto& url : urls) {
- builder.append(url.to_string());
- builder.append('\n');
- }
- set_data("text/uri-list", builder.to_byte_buffer());
-}
-
-String MimeData::text() const
-{
- return String::copy(m_data.get("text/plain").value_or({}));
-}
-
-void MimeData::set_text(const String& text)
-{
- set_data("text/plain", text.to_byte_buffer());
-}
-
-String guess_mime_type_based_on_filename(const StringView& path)
-{
- if (path.ends_with(".pbm", CaseSensitivity::CaseInsensitive))
- return "image/x‑portable‑bitmap";
- if (path.ends_with(".pgm", CaseSensitivity::CaseInsensitive))
- return "image/x‑portable‑graymap";
- if (path.ends_with(".png", CaseSensitivity::CaseInsensitive))
- return "image/png";
- if (path.ends_with(".ppm", CaseSensitivity::CaseInsensitive))
- return "image/x‑portable‑pixmap";
- if (path.ends_with(".gif", CaseSensitivity::CaseInsensitive))
- return "image/gif";
- if (path.ends_with(".bmp", CaseSensitivity::CaseInsensitive))
- return "image/bmp";
- if (path.ends_with(".jpg", CaseSensitivity::CaseInsensitive) || path.ends_with(".jpeg", CaseSensitivity::CaseInsensitive))
- return "image/jpeg";
- if (path.ends_with(".svg", CaseSensitivity::CaseInsensitive))
- return "image/svg+xml";
- if (path.ends_with(".md", CaseSensitivity::CaseInsensitive))
- return "text/markdown";
- if (path.ends_with(".html", CaseSensitivity::CaseInsensitive) || path.ends_with(".htm", CaseSensitivity::CaseInsensitive))
- return "text/html";
- if (path.ends_with("/", CaseSensitivity::CaseInsensitive))
- return "text/html";
- if (path.ends_with(".csv", CaseSensitivity::CaseInsensitive))
- return "text/csv";
- return "text/plain";
-}
-
-}
diff --git a/Libraries/LibCore/MimeData.h b/Libraries/LibCore/MimeData.h
deleted file mode 100644
index fe575ab675..0000000000
--- a/Libraries/LibCore/MimeData.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/ByteBuffer.h>
-#include <AK/HashMap.h>
-#include <AK/URL.h>
-#include <LibCore/Object.h>
-
-namespace Core {
-
-class MimeData : public Object {
- C_OBJECT(MimeData);
-
-public:
- virtual ~MimeData() { }
-
- ByteBuffer data(const String& mime_type) const { return m_data.get(mime_type).value_or({}); }
- void set_data(const String& mime_type, const ByteBuffer& data) { m_data.set(mime_type, data); }
-
- bool has_format(const String& mime_type) const { return m_data.contains(mime_type); }
- Vector<String> formats() const;
-
- // Convenience helpers for "text/plain"
- bool has_text() const { return has_format("text/plain"); }
- String text() const;
- void set_text(const String&);
-
- // Convenience helpers for "text/uri-list"
- bool has_urls() const { return has_format("text/uri-list"); }
- Vector<URL> urls() const;
- void set_urls(const Vector<URL>&);
-
- const HashMap<String, ByteBuffer>& all_data() const { return m_data; }
-
-private:
- MimeData() { }
- explicit MimeData(const HashMap<String, ByteBuffer>& data)
- : m_data(data)
- {
- }
-
- HashMap<String, ByteBuffer> m_data;
-};
-
-String guess_mime_type_based_on_filename(const StringView&);
-
-}
diff --git a/Libraries/LibCore/NetworkJob.cpp b/Libraries/LibCore/NetworkJob.cpp
deleted file mode 100644
index 0b48a93a72..0000000000
--- a/Libraries/LibCore/NetworkJob.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/NetworkJob.h>
-#include <LibCore/NetworkResponse.h>
-#include <stdio.h>
-
-//#define CNETWORKJOB_DEBUG
-
-namespace Core {
-
-NetworkJob::NetworkJob(OutputStream& output_stream)
- : m_output_stream(output_stream)
-{
-}
-
-NetworkJob::~NetworkJob()
-{
-}
-
-void NetworkJob::start()
-{
-}
-
-void NetworkJob::shutdown()
-{
-}
-
-void NetworkJob::did_finish(NonnullRefPtr<NetworkResponse>&& response)
-{
- // NOTE: We protect ourselves here, since the on_finish callback may otherwise
- // trigger destruction of this job somehow.
- NonnullRefPtr<NetworkJob> protector(*this);
-
- m_response = move(response);
-#ifdef CNETWORKJOB_DEBUG
- dbg() << *this << " job did_finish!";
-#endif
- ASSERT(on_finish);
- on_finish(true);
- shutdown();
-}
-
-void NetworkJob::did_fail(Error error)
-{
- // NOTE: We protect ourselves here, since the on_finish callback may otherwise
- // trigger destruction of this job somehow.
- NonnullRefPtr<NetworkJob> protector(*this);
-
- m_error = error;
-#ifdef CNETWORKJOB_DEBUG
- dbgprintf("%s{%p} job did_fail! error: %u (%s)\n", class_name(), this, (unsigned)error, to_string(error));
-#endif
- ASSERT(on_finish);
- on_finish(false);
- shutdown();
-}
-
-void NetworkJob::did_progress(Optional<u32> total_size, u32 downloaded)
-{
- // NOTE: We protect ourselves here, since the callback may otherwise
- // trigger destruction of this job somehow.
- NonnullRefPtr<NetworkJob> protector(*this);
-
- if (on_progress)
- on_progress(total_size, downloaded);
-}
-
-const char* to_string(NetworkJob::Error error)
-{
- switch (error) {
- case NetworkJob::Error::ProtocolFailed:
- return "ProtocolFailed";
- case NetworkJob::Error::ConnectionFailed:
- return "ConnectionFailed";
- case NetworkJob::Error::TransmissionFailed:
- return "TransmissionFailed";
- case NetworkJob::Error::Cancelled:
- return "Cancelled";
- default:
- return "(Unknown error)";
- }
-}
-
-}
diff --git a/Libraries/LibCore/NetworkJob.h b/Libraries/LibCore/NetworkJob.h
deleted file mode 100644
index 94ead44805..0000000000
--- a/Libraries/LibCore/NetworkJob.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Function.h>
-#include <AK/Stream.h>
-#include <LibCore/Object.h>
-
-namespace Core {
-
-class NetworkJob : public Object {
- C_OBJECT_ABSTRACT(NetworkJob)
-public:
- enum class Error {
- None,
- ConnectionFailed,
- TransmissionFailed,
- ProtocolFailed,
- Cancelled,
- };
- virtual ~NetworkJob() override;
-
- // Could fire twice, after Headers and after Trailers!
- Function<void(const HashMap<String, String, CaseInsensitiveStringTraits>& response_headers, Optional<u32> response_code)> on_headers_received;
- Function<void(bool success)> on_finish;
- Function<void(Optional<u32>, u32)> on_progress;
-
- bool is_cancelled() const { return m_error == Error::Cancelled; }
- bool has_error() const { return m_error != Error::None; }
- Error error() const { return m_error; }
- NetworkResponse* response() { return m_response.ptr(); }
- const NetworkResponse* response() const { return m_response.ptr(); }
-
- virtual void start() = 0;
- virtual void shutdown() = 0;
-
- void cancel()
- {
- shutdown();
- m_error = Error::Cancelled;
- }
-
-protected:
- NetworkJob(OutputStream&);
- void did_finish(NonnullRefPtr<NetworkResponse>&&);
- void did_fail(Error);
- void did_progress(Optional<u32> total_size, u32 downloaded);
-
- size_t do_write(ReadonlyBytes bytes) { return m_output_stream.write(bytes); }
-
-private:
- RefPtr<NetworkResponse> m_response;
- OutputStream& m_output_stream;
- Error m_error { Error::None };
-};
-
-const char* to_string(NetworkJob::Error);
-
-}
diff --git a/Libraries/LibCore/NetworkResponse.cpp b/Libraries/LibCore/NetworkResponse.cpp
deleted file mode 100644
index ebaf7eff7d..0000000000
--- a/Libraries/LibCore/NetworkResponse.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/NetworkResponse.h>
-
-namespace Core {
-
-NetworkResponse::NetworkResponse()
-{
-}
-
-NetworkResponse::~NetworkResponse()
-{
-}
-
-}
diff --git a/Libraries/LibCore/NetworkResponse.h b/Libraries/LibCore/NetworkResponse.h
deleted file mode 100644
index d2ff33a569..0000000000
--- a/Libraries/LibCore/NetworkResponse.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/ByteBuffer.h>
-#include <AK/RefCounted.h>
-
-namespace Core {
-
-class NetworkResponse : public RefCounted<NetworkResponse> {
-public:
- virtual ~NetworkResponse();
-
- bool is_error() const { return m_error; }
-
-protected:
- explicit NetworkResponse();
-
- bool m_error { false };
-};
-
-}
diff --git a/Libraries/LibCore/Notifier.cpp b/Libraries/LibCore/Notifier.cpp
deleted file mode 100644
index 655a73ed1b..0000000000
--- a/Libraries/LibCore/Notifier.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/Badge.h>
-#include <LibCore/Event.h>
-#include <LibCore/EventLoop.h>
-#include <LibCore/Notifier.h>
-
-namespace Core {
-
-Notifier::Notifier(int fd, unsigned event_mask, Object* parent)
- : Object(parent)
- , m_fd(fd)
- , m_event_mask(event_mask)
-{
- set_enabled(true);
-}
-
-Notifier::~Notifier()
-{
- set_enabled(false);
-}
-
-void Notifier::set_enabled(bool enabled)
-{
- if (m_fd < 0)
- return;
- if (enabled)
- Core::EventLoop::register_notifier({}, *this);
- else
- Core::EventLoop::unregister_notifier({}, *this);
-}
-
-void Notifier::close()
-{
- if (m_fd < 0)
- return;
- set_enabled(false);
- m_fd = -1;
-}
-
-void Notifier::event(Core::Event& event)
-{
- if (event.type() == Core::Event::NotifierRead && on_ready_to_read) {
- on_ready_to_read();
- } else if (event.type() == Core::Event::NotifierWrite && on_ready_to_write) {
- on_ready_to_write();
- } else {
- Object::event(event);
- }
-}
-
-}
diff --git a/Libraries/LibCore/Notifier.h b/Libraries/LibCore/Notifier.h
deleted file mode 100644
index b197b55204..0000000000
--- a/Libraries/LibCore/Notifier.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Function.h>
-#include <LibCore/Object.h>
-
-namespace Core {
-
-class Notifier : public Object {
- C_OBJECT(Notifier)
-public:
- enum Event {
- None = 0,
- Read = 1,
- Write = 2,
- Exceptional = 4,
- };
-
- virtual ~Notifier() override;
-
- void set_enabled(bool);
-
- Function<void()> on_ready_to_read;
- Function<void()> on_ready_to_write;
-
- void close();
-
- int fd() const { return m_fd; }
- unsigned event_mask() const { return m_event_mask; }
- void set_event_mask(unsigned event_mask) { m_event_mask = event_mask; }
-
- void event(Core::Event&) override;
-
-private:
- Notifier(int fd, unsigned event_mask, Object* parent = nullptr);
-
- int m_fd { -1 };
- unsigned m_event_mask { 0 };
-};
-
-}
diff --git a/Libraries/LibCore/Object.cpp b/Libraries/LibCore/Object.cpp
deleted file mode 100644
index 55cd102409..0000000000
--- a/Libraries/LibCore/Object.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/Assertions.h>
-#include <AK/Badge.h>
-#include <AK/JsonObject.h>
-#include <LibCore/Event.h>
-#include <LibCore/EventLoop.h>
-#include <LibCore/Object.h>
-#include <stdio.h>
-
-namespace Core {
-
-IntrusiveList<Object, &Object::m_all_objects_list_node>& Object::all_objects()
-{
- static IntrusiveList<Object, &Object::m_all_objects_list_node> objects;
- return objects;
-}
-
-Object::Object(Object* parent)
- : m_parent(parent)
-{
- all_objects().append(*this);
- if (m_parent)
- m_parent->add_child(*this);
-
- REGISTER_READONLY_STRING_PROPERTY("class_name", class_name);
- REGISTER_STRING_PROPERTY("name", name, set_name);
-
- register_property(
- "address", [this] { return FlatPtr(this); },
- [](auto&) { return false; });
-
- register_property(
- "parent", [this] { return FlatPtr(this->parent()); },
- [](auto&) { return false; });
-}
-
-Object::~Object()
-{
- // NOTE: We move our children out to a stack vector to prevent other
- // code from trying to iterate over them.
- auto children = move(m_children);
- // NOTE: We also unparent the children, so that they won't try to unparent
- // themselves in their own destructors.
- for (auto& child : children)
- child.m_parent = nullptr;
-
- all_objects().remove(*this);
- stop_timer();
- if (m_parent)
- m_parent->remove_child(*this);
-}
-
-void Object::event(Core::Event& event)
-{
- switch (event.type()) {
- case Core::Event::Timer:
- return timer_event(static_cast<TimerEvent&>(event));
- case Core::Event::ChildAdded:
- case Core::Event::ChildRemoved:
- return child_event(static_cast<ChildEvent&>(event));
- case Core::Event::Invalid:
- ASSERT_NOT_REACHED();
- break;
- case Core::Event::Custom:
- return custom_event(static_cast<CustomEvent&>(event));
- default:
- break;
- }
-}
-
-void Object::add_child(Object& object)
-{
- // FIXME: Should we support reparenting objects?
- ASSERT(!object.parent() || object.parent() == this);
- object.m_parent = this;
- m_children.append(object);
- Core::ChildEvent child_event(Core::Event::ChildAdded, object);
- event(child_event);
-}
-
-void Object::insert_child_before(Object& new_child, Object& before_child)
-{
- // FIXME: Should we support reparenting objects?
- ASSERT(!new_child.parent() || new_child.parent() == this);
- new_child.m_parent = this;
- m_children.insert_before_matching(new_child, [&](auto& existing_child) { return existing_child.ptr() == &before_child; });
- Core::ChildEvent child_event(Core::Event::ChildAdded, new_child, &before_child);
- event(child_event);
-}
-
-void Object::remove_child(Object& object)
-{
- for (size_t i = 0; i < m_children.size(); ++i) {
- if (m_children.ptr_at(i).ptr() == &object) {
- // NOTE: We protect the child so it survives the handling of ChildRemoved.
- NonnullRefPtr<Object> protector = object;
- object.m_parent = nullptr;
- m_children.remove(i);
- Core::ChildEvent child_event(Core::Event::ChildRemoved, object);
- event(child_event);
- return;
- }
- }
- ASSERT_NOT_REACHED();
-}
-
-void Object::remove_all_children()
-{
- while (!m_children.is_empty())
- m_children.first().remove_from_parent();
-}
-
-void Object::timer_event(Core::TimerEvent&)
-{
-}
-
-void Object::child_event(Core::ChildEvent&)
-{
-}
-
-void Object::custom_event(CustomEvent&)
-{
-}
-
-void Object::start_timer(int ms, TimerShouldFireWhenNotVisible fire_when_not_visible)
-{
- if (m_timer_id) {
- dbgln("{} {:p} already has a timer!", class_name(), this);
- ASSERT_NOT_REACHED();
- }
-
- m_timer_id = Core::EventLoop::register_timer(*this, ms, true, fire_when_not_visible);
-}
-
-void Object::stop_timer()
-{
- if (!m_timer_id)
- return;
- bool success = Core::EventLoop::unregister_timer(m_timer_id);
- ASSERT(success);
- m_timer_id = 0;
-}
-
-void Object::dump_tree(int indent)
-{
- for (int i = 0; i < indent; ++i) {
- printf(" ");
- }
- printf("%s{%p}", class_name(), this);
- if (!name().is_null())
- printf(" %s", name().characters());
- printf("\n");
-
- for_each_child([&](auto& child) {
- child.dump_tree(indent + 2);
- return IterationDecision::Continue;
- });
-}
-
-void Object::deferred_invoke(Function<void(Object&)> invokee)
-{
- Core::EventLoop::current().post_event(*this, make<Core::DeferredInvocationEvent>(move(invokee)));
-}
-
-void Object::save_to(JsonObject& json)
-{
- for (auto& it : m_properties) {
- auto& property = it.value;
- json.set(property->name(), property->get());
- }
-}
-
-JsonValue Object::property(const StringView& name) const
-{
- auto it = m_properties.find(name);
- if (it == m_properties.end())
- return JsonValue();
- return it->value->get();
-}
-
-bool Object::set_property(const StringView& name, const JsonValue& value)
-{
- auto it = m_properties.find(name);
- if (it == m_properties.end())
- return false;
- return it->value->set(value);
-}
-
-bool Object::is_ancestor_of(const Object& other) const
-{
- if (&other == this)
- return false;
- for (auto* ancestor = other.parent(); ancestor; ancestor = ancestor->parent()) {
- if (ancestor == this)
- return true;
- }
- return false;
-}
-
-void Object::dispatch_event(Core::Event& e, Object* stay_within)
-{
- ASSERT(!stay_within || stay_within == this || stay_within->is_ancestor_of(*this));
- auto* target = this;
- do {
- target->event(e);
- target = target->parent();
- if (target == stay_within) {
- // Prevent the event from bubbling any further.
- return;
- }
- } while (target && !e.is_accepted());
-}
-
-bool Object::is_visible_for_timer_purposes() const
-{
- if (parent())
- return parent()->is_visible_for_timer_purposes();
- return true;
-}
-
-void Object::increment_inspector_count(Badge<RPCClient>)
-{
- ++m_inspector_count;
- if (m_inspector_count == 1)
- did_begin_inspection();
-}
-
-void Object::decrement_inspector_count(Badge<RPCClient>)
-{
- --m_inspector_count;
- if (!m_inspector_count)
- did_end_inspection();
-}
-
-void Object::register_property(const String& name, Function<JsonValue()> getter, Function<bool(const JsonValue&)> setter)
-{
- m_properties.set(name, make<Property>(name, move(getter), move(setter)));
-}
-
-const LogStream& operator<<(const LogStream& stream, const Object& object)
-{
- return stream << object.class_name() << '{' << &object << '}';
-}
-
-}
diff --git a/Libraries/LibCore/Object.h b/Libraries/LibCore/Object.h
deleted file mode 100644
index 9270d347d0..0000000000
--- a/Libraries/LibCore/Object.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Forward.h>
-#include <AK/HashMap.h>
-#include <AK/IntrusiveList.h>
-#include <AK/Noncopyable.h>
-#include <AK/NonnullRefPtrVector.h>
-#include <AK/String.h>
-#include <AK/TypeCasts.h>
-#include <AK/Weakable.h>
-#include <LibCore/Forward.h>
-#include <LibCore/Property.h>
-
-namespace Core {
-
-class RPCClient;
-
-enum class TimerShouldFireWhenNotVisible {
- No = 0,
- Yes
-};
-
-#define C_OBJECT(klass) \
-public: \
- virtual const char* class_name() const override { return #klass; } \
- template<class... Args> \
- static inline NonnullRefPtr<klass> construct(Args&&... args) \
- { \
- return adopt(*new klass(forward<Args>(args)...)); \
- }
-
-#define C_OBJECT_ABSTRACT(klass) \
-public: \
- virtual const char* class_name() const override { return #klass; }
-
-class Object
- : public RefCounted<Object>
- , public Weakable<Object> {
- // NOTE: No C_OBJECT macro for Core::Object itself.
-
- AK_MAKE_NONCOPYABLE(Object);
- AK_MAKE_NONMOVABLE(Object);
-
- IntrusiveListNode m_all_objects_list_node;
-
-public:
- virtual ~Object();
-
- virtual const char* class_name() const = 0;
- virtual void event(Core::Event&);
-
- const String& name() const { return m_name; }
- void set_name(const StringView& name) { m_name = name; }
-
- NonnullRefPtrVector<Object>& children() { return m_children; }
- const NonnullRefPtrVector<Object>& children() const { return m_children; }
-
- template<typename Callback>
- void for_each_child(Callback callback)
- {
- for (auto& child : m_children) {
- if (callback(child) == IterationDecision::Break)
- return;
- }
- }
-
- template<typename T, typename Callback>
- void for_each_child_of_type(Callback callback) requires IsBaseOf<Object, T>::value;
-
- template<typename T>
- T* find_child_of_type_named(const String&) requires IsBaseOf<Object, T>::value;
-
- template<typename T>
- T* find_descendant_of_type_named(const String&) requires IsBaseOf<Object, T>::value;
-
- bool is_ancestor_of(const Object&) const;
-
- Object* parent() { return m_parent; }
- const Object* parent() const { return m_parent; }
-
- void start_timer(int ms, TimerShouldFireWhenNotVisible = TimerShouldFireWhenNotVisible::No);
- void stop_timer();
- bool has_timer() const { return m_timer_id; }
-
- void add_child(Object&);
- void insert_child_before(Object& new_child, Object& before_child);
- void remove_child(Object&);
- void remove_all_children();
-
- void dump_tree(int indent = 0);
-
- void deferred_invoke(Function<void(Object&)>);
-
- void save_to(AK::JsonObject&);
-
- bool set_property(const StringView& name, const JsonValue& value);
- JsonValue property(const StringView& name) const;
- const HashMap<String, NonnullOwnPtr<Property>>& properties() const { return m_properties; }
-
- static IntrusiveList<Object, &Object::m_all_objects_list_node>& all_objects();
-
- void dispatch_event(Core::Event&, Object* stay_within = nullptr);
-
- void remove_from_parent()
- {
- if (m_parent)
- m_parent->remove_child(*this);
- }
-
- template<class T, class... Args>
- inline T& add(Args&&... args)
- {
- auto child = T::construct(forward<Args>(args)...);
- add_child(*child);
- return child;
- }
-
- virtual bool is_visible_for_timer_purposes() const;
-
- bool is_being_inspected() const { return m_inspector_count; }
-
- void increment_inspector_count(Badge<RPCClient>);
- void decrement_inspector_count(Badge<RPCClient>);
-
-protected:
- explicit Object(Object* parent = nullptr);
-
- void register_property(const String& name, Function<JsonValue()> getter, Function<bool(const JsonValue&)> setter = nullptr);
-
- virtual void timer_event(TimerEvent&);
- virtual void custom_event(CustomEvent&);
-
- // NOTE: You may get child events for children that are not yet fully constructed!
- virtual void child_event(ChildEvent&);
-
- virtual void did_begin_inspection() { }
- virtual void did_end_inspection() { }
-
-private:
- Object* m_parent { nullptr };
- String m_name;
- int m_timer_id { 0 };
- unsigned m_inspector_count { 0 };
- HashMap<String, NonnullOwnPtr<Property>> m_properties;
- NonnullRefPtrVector<Object> m_children;
-};
-
-}
-
-template<>
-struct AK::Formatter<Core::Object> : AK::Formatter<FormatString> {
- void format(FormatBuilder& builder, const Core::Object& value)
- {
- return AK::Formatter<FormatString>::format(builder, "{}({})", value.class_name(), &value);
- }
-};
-
-namespace Core {
-template<typename T, typename Callback>
-inline void Object::for_each_child_of_type(Callback callback) requires IsBaseOf<Object, T>::value
-{
- for_each_child([&](auto& child) {
- if (auto* child_as_t = dynamic_cast<T*>(&child); child_as_t)
- return callback(*child_as_t);
- return IterationDecision::Continue;
- });
-}
-
-template<typename T>
-T* Object::find_child_of_type_named(const String& name) requires IsBaseOf<Object, T>::value
-{
- T* found_child = nullptr;
- for_each_child_of_type<T>([&](auto& child) {
- if (child.name() == name) {
- found_child = &child;
- return IterationDecision::Break;
- }
- return IterationDecision::Continue;
- });
-
- return found_child;
-}
-
-template<typename T>
-T* Object::find_descendant_of_type_named(const String& name) requires IsBaseOf<Object, T>::value
-{
- auto* this_as_t = dynamic_cast<T*>(this);
- if (this_as_t && this->name() == name)
- return this_as_t;
- T* found_child = nullptr;
- for_each_child([&](auto& child) {
- found_child = child.template find_descendant_of_type_named<T>(name);
- if (found_child)
- return IterationDecision::Break;
- return IterationDecision::Continue;
- });
- return found_child;
-}
-
-const LogStream& operator<<(const LogStream&, const Object&);
-
-#define REGISTER_INT_PROPERTY(property_name, getter, setter) \
- register_property( \
- property_name, \
- [this] { return this->getter(); }, \
- [this](auto& value) { \
- this->setter(value.template to_number<int>()); \
- return true; \
- });
-
-#define REGISTER_BOOL_PROPERTY(property_name, getter, setter) \
- register_property( \
- property_name, \
- [this] { return this->getter(); }, \
- [this](auto& value) { \
- this->setter(value.to_bool()); \
- return true; \
- });
-
-#define REGISTER_STRING_PROPERTY(property_name, getter, setter) \
- register_property( \
- property_name, \
- [this] { return this->getter(); }, \
- [this](auto& value) { \
- this->setter(value.to_string()); \
- return true; \
- });
-
-#define REGISTER_READONLY_STRING_PROPERTY(property_name, getter) \
- register_property( \
- property_name, \
- [this] { return this->getter(); }, \
- {});
-
-#define REGISTER_RECT_PROPERTY(property_name, getter, setter) \
- register_property( \
- property_name, \
- [this] { \
- auto rect = this->getter(); \
- JsonObject rect_object; \
- rect_object.set("x", rect.x()); \
- rect_object.set("y", rect.y()); \
- rect_object.set("width", rect.width()); \
- rect_object.set("height", rect.height()); \
- return rect_object; \
- }, \
- [this](auto& value) { \
- if (!value.is_object()) \
- return false; \
- Gfx::IntRect rect; \
- rect.set_x(value.as_object().get("x").to_i32()); \
- rect.set_y(value.as_object().get("y").to_i32()); \
- rect.set_width(value.as_object().get("width").to_i32()); \
- rect.set_height(value.as_object().get("height").to_i32()); \
- setter(rect); \
- return true; \
- });
-
-#define REGISTER_SIZE_PROPERTY(property_name, getter, setter) \
- register_property( \
- property_name, \
- [this] { \
- auto size = this->getter(); \
- JsonObject size_object; \
- size_object.set("width", size.width()); \
- size_object.set("height", size.height()); \
- return size_object; \
- }, \
- [this](auto& value) { \
- if (!value.is_object()) \
- return false; \
- Gfx::IntSize size; \
- size.set_width(value.as_object().get("width").to_i32()); \
- size.set_height(value.as_object().get("height").to_i32()); \
- setter(size); \
- return true; \
- });
-
-#define REGISTER_ENUM_PROPERTY(property_name, getter, setter, EnumType, ...) \
- register_property( \
- property_name, \
- [this]() -> JsonValue { \
- struct { \
- EnumType enum_value; \
- String string_value; \
- } options[] = { __VA_ARGS__ }; \
- auto enum_value = getter(); \
- for (size_t i = 0; i < array_size(options); ++i) { \
- auto& option = options[i]; \
- if (enum_value == option.enum_value) \
- return option.string_value; \
- } \
- return JsonValue(); \
- }, \
- [this](auto& value) { \
- struct { \
- EnumType enum_value; \
- String string_value; \
- } options[] = { __VA_ARGS__ }; \
- auto string_value = value.as_string(); \
- for (size_t i = 0; i < array_size(options); ++i) { \
- auto& option = options[i]; \
- if (string_value == option.string_value) { \
- setter(option.enum_value); \
- return true; \
- } \
- } \
- return false; \
- })
-
-#define REGISTER_TEXT_ALIGNMENT_PROPERTY(property_name, getter, setter) \
- REGISTER_ENUM_PROPERTY( \
- property_name, getter, setter, Gfx::TextAlignment, \
- { Gfx::TextAlignment::TopLeft, "TopLeft" }, \
- { Gfx::TextAlignment::CenterLeft, "CenterLeft" }, \
- { Gfx::TextAlignment::Center, "Center" }, \
- { Gfx::TextAlignment::CenterRight, "CenterRight" }, \
- { Gfx::TextAlignment::TopRight, "TopRight" }, \
- { Gfx::TextAlignment::BottomRight, "BottomRight" })
-}
diff --git a/Libraries/LibCore/ProcessStatisticsReader.cpp b/Libraries/LibCore/ProcessStatisticsReader.cpp
deleted file mode 100644
index 566053d3af..0000000000
--- a/Libraries/LibCore/ProcessStatisticsReader.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/ByteBuffer.h>
-#include <AK/JsonArray.h>
-#include <AK/JsonObject.h>
-#include <AK/JsonValue.h>
-#include <LibCore/File.h>
-#include <LibCore/ProcessStatisticsReader.h>
-#include <pwd.h>
-#include <stdio.h>
-
-namespace Core {
-
-HashMap<uid_t, String> ProcessStatisticsReader::s_usernames;
-
-Optional<HashMap<pid_t, Core::ProcessStatistics>> ProcessStatisticsReader::get_all(RefPtr<Core::File>& proc_all_file)
-{
- if (proc_all_file) {
- if (!proc_all_file->seek(0, Core::File::SeekMode::SetPosition)) {
- fprintf(stderr, "ProcessStatisticsReader: Failed to refresh /proc/all: %s\n", proc_all_file->error_string());
- return {};
- }
- } else {
- proc_all_file = Core::File::construct("/proc/all");
- if (!proc_all_file->open(Core::IODevice::ReadOnly)) {
- fprintf(stderr, "ProcessStatisticsReader: Failed to open /proc/all: %s\n", proc_all_file->error_string());
- return {};
- }
- }
-
- HashMap<pid_t, Core::ProcessStatistics> map;
-
- auto file_contents = proc_all_file->read_all();
- auto json = JsonValue::from_string(file_contents);
- if (!json.has_value())
- return {};
- json.value().as_array().for_each([&](auto& value) {
- const JsonObject& process_object = value.as_object();
- Core::ProcessStatistics process;
-
- // kernel data first
- process.pid = process_object.get("pid").to_u32();
- process.pgid = process_object.get("pgid").to_u32();
- process.pgp = process_object.get("pgp").to_u32();
- process.sid = process_object.get("sid").to_u32();
- process.uid = process_object.get("uid").to_u32();
- process.gid = process_object.get("gid").to_u32();
- process.ppid = process_object.get("ppid").to_u32();
- process.nfds = process_object.get("nfds").to_u32();
- process.name = process_object.get("name").to_string();
- process.executable = process_object.get("executable").to_string();
- process.tty = process_object.get("tty").to_string();
- process.pledge = process_object.get("pledge").to_string();
- process.veil = process_object.get("veil").to_string();
- process.amount_virtual = process_object.get("amount_virtual").to_u32();
- process.amount_resident = process_object.get("amount_resident").to_u32();
- process.amount_shared = process_object.get("amount_shared").to_u32();
- process.amount_dirty_private = process_object.get("amount_dirty_private").to_u32();
- process.amount_clean_inode = process_object.get("amount_clean_inode").to_u32();
- process.amount_purgeable_volatile = process_object.get("amount_purgeable_volatile").to_u32();
- process.amount_purgeable_nonvolatile = process_object.get("amount_purgeable_nonvolatile").to_u32();
-
- auto& thread_array = process_object.get_ptr("threads")->as_array();
- process.threads.ensure_capacity(thread_array.size());
- thread_array.for_each([&](auto& value) {
- auto& thread_object = value.as_object();
- Core::ThreadStatistics thread;
- thread.tid = thread_object.get("tid").to_u32();
- thread.times_scheduled = thread_object.get("times_scheduled").to_u32();
- thread.name = thread_object.get("name").to_string();
- thread.state = thread_object.get("state").to_string();
- thread.ticks_user = thread_object.get("ticks_user").to_u32();
- thread.ticks_kernel = thread_object.get("ticks_kernel").to_u32();
- thread.cpu = thread_object.get("cpu").to_u32();
- thread.priority = thread_object.get("priority").to_u32();
- thread.effective_priority = thread_object.get("effective_priority").to_u32();
- thread.syscall_count = thread_object.get("syscall_count").to_u32();
- thread.inode_faults = thread_object.get("inode_faults").to_u32();
- thread.zero_faults = thread_object.get("zero_faults").to_u32();
- thread.cow_faults = thread_object.get("cow_faults").to_u32();
- thread.unix_socket_read_bytes = thread_object.get("unix_socket_read_bytes").to_u32();
- thread.unix_socket_write_bytes = thread_object.get("unix_socket_write_bytes").to_u32();
- thread.ipv4_socket_read_bytes = thread_object.get("ipv4_socket_read_bytes").to_u32();
- thread.ipv4_socket_write_bytes = thread_object.get("ipv4_socket_write_bytes").to_u32();
- thread.file_read_bytes = thread_object.get("file_read_bytes").to_u32();
- thread.file_write_bytes = thread_object.get("file_write_bytes").to_u32();
- process.threads.append(move(thread));
- });
-
- // and synthetic data last
- process.username = username_from_uid(process.uid);
- map.set(process.pid, process);
- });
-
- return map;
-}
-
-Optional<HashMap<pid_t, Core::ProcessStatistics>> ProcessStatisticsReader::get_all()
-{
- RefPtr<Core::File> proc_all_file;
- return get_all(proc_all_file);
-}
-
-String ProcessStatisticsReader::username_from_uid(uid_t uid)
-{
- if (s_usernames.is_empty()) {
- setpwent();
- while (auto* passwd = getpwent())
- s_usernames.set(passwd->pw_uid, passwd->pw_name);
- endpwent();
- }
-
- auto it = s_usernames.find(uid);
- if (it != s_usernames.end())
- return (*it).value;
- return String::number(uid);
-}
-}
diff --git a/Libraries/LibCore/ProcessStatisticsReader.h b/Libraries/LibCore/ProcessStatisticsReader.h
deleted file mode 100644
index b6e506cd9d..0000000000
--- a/Libraries/LibCore/ProcessStatisticsReader.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/HashMap.h>
-#include <AK/String.h>
-#include <LibCore/File.h>
-#include <unistd.h>
-
-namespace Core {
-
-struct ThreadStatistics {
- pid_t tid;
- unsigned times_scheduled;
- unsigned ticks_user;
- unsigned ticks_kernel;
- unsigned syscall_count;
- unsigned inode_faults;
- unsigned zero_faults;
- unsigned cow_faults;
- unsigned unix_socket_read_bytes;
- unsigned unix_socket_write_bytes;
- unsigned ipv4_socket_read_bytes;
- unsigned ipv4_socket_write_bytes;
- unsigned file_read_bytes;
- unsigned file_write_bytes;
- String state;
- u32 cpu;
- u32 priority;
- u32 effective_priority;
- String name;
-};
-
-struct ProcessStatistics {
- // Keep this in sync with /proc/all.
- // From the kernel side:
- pid_t pid;
- pid_t pgid;
- pid_t pgp;
- pid_t sid;
- uid_t uid;
- gid_t gid;
- pid_t ppid;
- unsigned nfds;
- String name;
- String executable;
- String tty;
- String pledge;
- String veil;
- size_t amount_virtual;
- size_t amount_resident;
- size_t amount_shared;
- size_t amount_dirty_private;
- size_t amount_clean_inode;
- size_t amount_purgeable_volatile;
- size_t amount_purgeable_nonvolatile;
-
- Vector<Core::ThreadStatistics> threads;
-
- // synthetic
- String username;
-};
-
-class ProcessStatisticsReader {
-public:
- static Optional<HashMap<pid_t, Core::ProcessStatistics>> get_all(RefPtr<Core::File>&);
- static Optional<HashMap<pid_t, Core::ProcessStatistics>> get_all();
-
-private:
- static String username_from_uid(uid_t);
- static HashMap<uid_t, String> s_usernames;
-};
-
-}
diff --git a/Libraries/LibCore/Property.cpp b/Libraries/LibCore/Property.cpp
deleted file mode 100644
index 8c6c2587c6..0000000000
--- a/Libraries/LibCore/Property.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/Property.h>
-
-namespace Core {
-
-Property::Property(String name, Function<JsonValue()> getter, Function<bool(const JsonValue&)> setter)
- : m_name(move(name))
- , m_getter(move(getter))
- , m_setter(move(setter))
-{
-}
-
-Property::~Property()
-{
-}
-
-}
diff --git a/Libraries/LibCore/Property.h b/Libraries/LibCore/Property.h
deleted file mode 100644
index aa04e833fb..0000000000
--- a/Libraries/LibCore/Property.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Function.h>
-#include <AK/JsonValue.h>
-
-namespace Core {
-
-class Property {
- AK_MAKE_NONCOPYABLE(Property);
-
-public:
- Property(String name, Function<JsonValue()> getter, Function<bool(const JsonValue&)> setter = nullptr);
- ~Property();
-
- bool set(const JsonValue& value)
- {
- if (!m_setter)
- return false;
- return m_setter(value);
- }
-
- JsonValue get() const { return m_getter(); }
-
- const String& name() const { return m_name; }
- bool is_readonly() const { return !m_setter; }
-
-private:
- String m_name;
- Function<JsonValue()> m_getter;
- Function<bool(const JsonValue&)> m_setter;
-};
-
-}
diff --git a/Libraries/LibCore/Socket.cpp b/Libraries/LibCore/Socket.cpp
deleted file mode 100644
index 4ced6734b1..0000000000
--- a/Libraries/LibCore/Socket.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/ByteBuffer.h>
-#include <LibCore/Notifier.h>
-#include <LibCore/Socket.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-//#define CSOCKET_DEBUG
-
-namespace Core {
-
-Socket::Socket(Type type, Object* parent)
- : IODevice(parent)
- , m_type(type)
-{
- register_property(
- "source_address", [this] { return m_source_address.to_string(); },
- [](auto&) { return false; });
-
- register_property(
- "destination_address", [this] { return m_destination_address.to_string(); },
- [](auto&) { return false; });
-
- register_property(
- "source_port", [this] { return m_source_port; },
- [](auto&) { return false; });
-
- register_property(
- "destination_port", [this] { return m_destination_port; },
- [](auto&) { return false; });
-
- register_property(
- "connected", [this] { return m_connected; },
- [](auto&) { return false; });
-}
-
-Socket::~Socket()
-{
- close();
-}
-
-bool Socket::connect(const String& hostname, int port)
-{
- auto* hostent = gethostbyname(hostname.characters());
- if (!hostent) {
- dbgln("Socket::connect: Unable to resolve '{}'", hostname);
- return false;
- }
-
- IPv4Address host_address((const u8*)hostent->h_addr_list[0]);
-#ifdef CSOCKET_DEBUG
- dbg() << "Socket::connect: Resolved '" << hostname << "' to " << host_address;
-#endif
- return connect(host_address, port);
-}
-
-void Socket::set_blocking(bool blocking)
-{
- int flags = fcntl(fd(), F_GETFL, 0);
- ASSERT(flags >= 0);
- if (blocking)
- flags = fcntl(fd(), F_SETFL, flags & ~O_NONBLOCK);
- else
- flags = fcntl(fd(), F_SETFL, flags | O_NONBLOCK);
- ASSERT(flags == 0);
-}
-
-bool Socket::connect(const SocketAddress& address, int port)
-{
- ASSERT(!is_connected());
- ASSERT(address.type() == SocketAddress::Type::IPv4);
-#ifdef CSOCKET_DEBUG
- dbg() << *this << " connecting to " << address << "...";
-#endif
-
- ASSERT(port > 0 && port <= 65535);
-
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- auto ipv4_address = address.ipv4_address();
- memcpy(&addr.sin_addr.s_addr, &ipv4_address, sizeof(IPv4Address));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
-
- m_destination_address = address;
- m_destination_port = port;
-
- return common_connect((struct sockaddr*)&addr, sizeof(addr));
-}
-
-bool Socket::connect(const SocketAddress& address)
-{
- ASSERT(!is_connected());
- ASSERT(address.type() == SocketAddress::Type::Local);
-#ifdef CSOCKET_DEBUG
- dbg() << *this << " connecting to " << address << "...";
-#endif
-
- sockaddr_un saddr;
- saddr.sun_family = AF_LOCAL;
- auto dest_address = address.to_string();
- bool fits = dest_address.copy_characters_to_buffer(saddr.sun_path, sizeof(saddr.sun_path));
- if (!fits) {
- fprintf(stderr, "Core::Socket: Failed to connect() to %s: Path is too long!\n", dest_address.characters());
- errno = EINVAL;
- return false;
- }
- m_destination_address = address;
-
- return common_connect((const sockaddr*)&saddr, sizeof(saddr));
-}
-
-bool Socket::common_connect(const struct sockaddr* addr, socklen_t addrlen)
-{
- auto connected = [this] {
-#ifdef CSOCKET_DEBUG
- dbg() << *this << " connected!";
-#endif
- if (!m_connected) {
- m_connected = true;
- ensure_read_notifier();
- if (m_notifier) {
- m_notifier->remove_from_parent();
- m_notifier = nullptr;
- }
- if (on_connected)
- on_connected();
- }
- };
- int rc = ::connect(fd(), addr, addrlen);
- if (rc < 0) {
- if (errno == EINPROGRESS) {
-#ifdef CSOCKET_DEBUG
- dbg() << *this << " connection in progress (EINPROGRESS)";
-#endif
- m_notifier = Notifier::construct(fd(), Notifier::Event::Write, this);
- m_notifier->on_ready_to_write = move(connected);
- return true;
- }
- int saved_errno = errno;
- fprintf(stderr, "Core::Socket: Failed to connect() to %s: %s\n", destination_address().to_string().characters(), strerror(saved_errno));
- errno = saved_errno;
- return false;
- }
-#ifdef CSOCKET_DEBUG
- dbg() << *this << " connected ok!";
-#endif
- connected();
- return true;
-}
-
-ByteBuffer Socket::receive(int max_size)
-{
- auto buffer = read(max_size);
- if (eof())
- m_connected = false;
- return buffer;
-}
-
-bool Socket::send(ReadonlyBytes data)
-{
- ssize_t nsent = ::send(fd(), data.data(), data.size(), 0);
- if (nsent < 0) {
- set_error(errno);
- return false;
- }
- ASSERT(static_cast<size_t>(nsent) == data.size());
- return true;
-}
-
-void Socket::did_update_fd(int fd)
-{
- if (fd < 0) {
- if (m_read_notifier) {
- m_read_notifier->remove_from_parent();
- m_read_notifier = nullptr;
- }
- if (m_notifier) {
- m_notifier->remove_from_parent();
- m_notifier = nullptr;
- }
- return;
- }
- if (m_connected) {
- ensure_read_notifier();
- } else {
- // I don't think it would be right if we updated the fd while not connected *but* while having a notifier..
- ASSERT(!m_read_notifier);
- }
-}
-
-void Socket::ensure_read_notifier()
-{
- ASSERT(m_connected);
- m_read_notifier = Notifier::construct(fd(), Notifier::Event::Read, this);
- m_read_notifier->on_ready_to_read = [this] {
- if (!can_read())
- return;
- if (on_ready_to_read)
- on_ready_to_read();
- };
-}
-
-}
diff --git a/Libraries/LibCore/Socket.h b/Libraries/LibCore/Socket.h
deleted file mode 100644
index fcbd2af31d..0000000000
--- a/Libraries/LibCore/Socket.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Function.h>
-#include <AK/Span.h>
-#include <LibCore/IODevice.h>
-#include <LibCore/SocketAddress.h>
-
-namespace Core {
-
-class Socket : public IODevice {
- C_OBJECT(Socket)
-public:
- enum class Type {
- Invalid,
- TCP,
- UDP,
- Local,
- };
- virtual ~Socket() override;
-
- Type type() const { return m_type; }
-
- virtual bool connect(const String& hostname, int port);
- bool connect(const SocketAddress&, int port);
- bool connect(const SocketAddress&);
-
- ByteBuffer receive(int max_size);
- bool send(ReadonlyBytes);
-
- bool is_connected() const { return m_connected; }
- void set_blocking(bool blocking);
-
- SocketAddress source_address() const { return m_source_address; }
- int source_port() const { return m_source_port; }
-
- SocketAddress destination_address() const { return m_destination_address; }
- int destination_port() const { return m_destination_port; }
-
- Function<void()> on_connected;
- Function<void()> on_ready_to_read;
-
-protected:
- Socket(Type, Object* parent);
-
- SocketAddress m_source_address;
- SocketAddress m_destination_address;
- int m_source_port { -1 };
- int m_destination_port { -1 };
- bool m_connected { false };
-
- virtual void did_update_fd(int) override;
- virtual bool common_connect(const struct sockaddr*, socklen_t);
-
-private:
- virtual bool open(IODevice::OpenMode) override { ASSERT_NOT_REACHED(); }
- void ensure_read_notifier();
-
- Type m_type { Type::Invalid };
- RefPtr<Notifier> m_notifier;
- RefPtr<Notifier> m_read_notifier;
-};
-
-}
diff --git a/Libraries/LibCore/SocketAddress.cpp b/Libraries/LibCore/SocketAddress.cpp
deleted file mode 100644
index d4d451a150..0000000000
--- a/Libraries/LibCore/SocketAddress.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/SocketAddress.h>
-
-namespace Core {
-
-const LogStream& operator<<(const LogStream& stream, const SocketAddress& value)
-{
- return stream << value.to_string();
-}
-
-}
diff --git a/Libraries/LibCore/SocketAddress.h b/Libraries/LibCore/SocketAddress.h
deleted file mode 100644
index 717f4e8fd3..0000000000
--- a/Libraries/LibCore/SocketAddress.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/IPv4Address.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-namespace Core {
-
-class SocketAddress {
-public:
- enum class Type {
- Invalid,
- IPv4,
- Local
- };
-
- SocketAddress() { }
- SocketAddress(const IPv4Address& address)
- : m_type(Type::IPv4)
- , m_ipv4_address(address)
- {
- }
-
- SocketAddress(const IPv4Address& address, u16 port)
- : m_type(Type::IPv4)
- , m_ipv4_address(address)
- , m_port(port)
- {
- }
-
- static SocketAddress local(const String& address)
- {
- SocketAddress addr;
- addr.m_type = Type::Local;
- addr.m_local_address = address;
- return addr;
- }
-
- Type type() const { return m_type; }
- bool is_valid() const { return m_type != Type::Invalid; }
- IPv4Address ipv4_address() const { return m_ipv4_address; }
- u16 port() const { return m_port; }
-
- String to_string() const
- {
- switch (m_type) {
- case Type::IPv4:
- return String::format("%s:%d", m_ipv4_address.to_string().characters(), m_port);
- case Type::Local:
- return m_local_address;
- default:
- return "[SocketAddress]";
- }
- }
-
- Optional<sockaddr_un> to_sockaddr_un() const
- {
- ASSERT(type() == Type::Local);
- sockaddr_un address;
- address.sun_family = AF_LOCAL;
- bool fits = m_local_address.copy_characters_to_buffer(address.sun_path, sizeof(address.sun_path));
- if (!fits)
- return {};
- return address;
- }
-
- sockaddr_in to_sockaddr_in() const
- {
- ASSERT(type() == Type::IPv4);
- sockaddr_in address {};
- address.sin_family = AF_INET;
- address.sin_addr.s_addr = m_ipv4_address.to_in_addr_t();
- address.sin_port = htons(m_port);
- return address;
- }
-
-private:
- Type m_type { Type::Invalid };
- IPv4Address m_ipv4_address;
- u16 m_port { 0 };
- String m_local_address;
-};
-
-const LogStream& operator<<(const LogStream&, const SocketAddress&);
-
-}
diff --git a/Libraries/LibCore/StandardPaths.cpp b/Libraries/LibCore/StandardPaths.cpp
deleted file mode 100644
index 3ed9197835..0000000000
--- a/Libraries/LibCore/StandardPaths.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/LexicalPath.h>
-#include <AK/String.h>
-#include <AK/StringBuilder.h>
-#include <LibCore/StandardPaths.h>
-#include <pwd.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-namespace Core {
-
-String StandardPaths::home_directory()
-{
- if (auto* home_env = getenv("HOME"))
- return LexicalPath::canonicalized_path(home_env);
-
- auto* pwd = getpwuid(getuid());
- String path = pwd ? pwd->pw_dir : "/";
- endpwent();
- return LexicalPath::canonicalized_path(path);
-}
-
-String StandardPaths::desktop_directory()
-{
- StringBuilder builder;
- builder.append(home_directory());
- builder.append("/Desktop");
- return LexicalPath::canonicalized_path(builder.to_string());
-}
-
-String StandardPaths::downloads_directory()
-{
- StringBuilder builder;
- builder.append(home_directory());
- builder.append("/Downloads");
- return LexicalPath::canonicalized_path(builder.to_string());
-}
-
-String StandardPaths::config_directory()
-{
- StringBuilder builder;
- builder.append(home_directory());
- builder.append("/.config");
- return LexicalPath::canonicalized_path(builder.to_string());
-}
-
-String StandardPaths::tempfile_directory()
-{
- return "/tmp";
-}
-
-}
diff --git a/Libraries/LibCore/StandardPaths.h b/Libraries/LibCore/StandardPaths.h
deleted file mode 100644
index 51346250c2..0000000000
--- a/Libraries/LibCore/StandardPaths.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Forward.h>
-
-namespace Core {
-
-class StandardPaths {
-public:
- static String home_directory();
- static String desktop_directory();
- static String downloads_directory();
- static String tempfile_directory();
- static String config_directory();
-};
-
-}
diff --git a/Libraries/LibCore/SyscallUtils.h b/Libraries/LibCore/SyscallUtils.h
deleted file mode 100644
index 1c24efd9c2..0000000000
--- a/Libraries/LibCore/SyscallUtils.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/LogStream.h>
-#include <AK/StdLibExtras.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace Core {
-
-template<typename Syscall, class... Args>
-inline int safe_syscall(Syscall syscall, Args&&... args)
-{
- for (;;) {
- int sysret = syscall(forward<Args>(args)...);
- if (sysret == -1) {
-#ifdef SAFE_SYSCALL_DEBUG
- int saved_errno = errno;
- dbg() << "Core::safe_syscall: " << sysret << " (" << saved_errno << ": " << strerror(saved_errno) << ")";
-#endif
- if (errno == EINTR)
- continue;
- ASSERT_NOT_REACHED();
- }
- return sysret;
- }
-}
-
-}
diff --git a/Libraries/LibCore/TCPServer.cpp b/Libraries/LibCore/TCPServer.cpp
deleted file mode 100644
index 0ef241b717..0000000000
--- a/Libraries/LibCore/TCPServer.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/IPv4Address.h>
-#include <AK/Types.h>
-#include <LibCore/Notifier.h>
-#include <LibCore/TCPServer.h>
-#include <LibCore/TCPSocket.h>
-#include <stdio.h>
-#include <sys/socket.h>
-
-#ifndef SOCK_NONBLOCK
-# include <sys/ioctl.h>
-#endif
-namespace Core {
-
-TCPServer::TCPServer(Object* parent)
- : Object(parent)
-{
-#ifdef SOCK_NONBLOCK
- m_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
-#else
- m_fd = socket(AF_INET, SOCK_STREAM, 0);
- int option = 1;
- ioctl(m_fd, FIONBIO, &option);
- fcntl(m_fd, F_SETFD, FD_CLOEXEC);
-#endif
- ASSERT(m_fd >= 0);
-}
-
-TCPServer::~TCPServer()
-{
- ::close(m_fd);
-}
-
-bool TCPServer::listen(const IPv4Address& address, u16 port)
-{
- if (m_listening)
- return false;
-
- auto socket_address = SocketAddress(address, port);
- auto in = socket_address.to_sockaddr_in();
- if (::bind(m_fd, (const sockaddr*)&in, sizeof(in)) < 0) {
- perror("TCPServer::listen: bind");
- return false;
- }
-
- if (::listen(m_fd, 5) < 0) {
- perror("TCPServer::listen: listen");
- return false;
- }
- m_listening = true;
-
- m_notifier = Notifier::construct(m_fd, Notifier::Event::Read, this);
- m_notifier->on_ready_to_read = [this] {
- if (on_ready_to_accept)
- on_ready_to_accept();
- };
- return true;
-}
-
-RefPtr<TCPSocket> TCPServer::accept()
-{
- ASSERT(m_listening);
- sockaddr_in in;
- socklen_t in_size = sizeof(in);
- int accepted_fd = ::accept(m_fd, (sockaddr*)&in, &in_size);
- if (accepted_fd < 0) {
- perror("accept");
- return nullptr;
- }
-
- return TCPSocket::construct(accepted_fd);
-}
-
-Optional<IPv4Address> TCPServer::local_address() const
-{
- if (m_fd == -1)
- return {};
-
- sockaddr_in address;
- socklen_t len = sizeof(address);
- if (getsockname(m_fd, (sockaddr*)&address, &len) != 0)
- return {};
-
- return IPv4Address(address.sin_addr.s_addr);
-}
-
-Optional<u16> TCPServer::local_port() const
-{
- if (m_fd == -1)
- return {};
-
- sockaddr_in address;
- socklen_t len = sizeof(address);
- if (getsockname(m_fd, (sockaddr*)&address, &len) != 0)
- return {};
-
- return ntohs(address.sin_port);
-}
-
-}
diff --git a/Libraries/LibCore/TCPServer.h b/Libraries/LibCore/TCPServer.h
deleted file mode 100644
index b516ec1500..0000000000
--- a/Libraries/LibCore/TCPServer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/IPv4Address.h>
-#include <LibCore/Notifier.h>
-#include <LibCore/Object.h>
-
-namespace Core {
-
-class TCPServer : public Object {
- C_OBJECT(TCPServer)
-public:
- virtual ~TCPServer() override;
-
- bool is_listening() const { return m_listening; }
- bool listen(const IPv4Address& address, u16 port);
-
- RefPtr<TCPSocket> accept();
-
- Optional<IPv4Address> local_address() const;
- Optional<u16> local_port() const;
-
- Function<void()> on_ready_to_accept;
-
-private:
- explicit TCPServer(Object* parent = nullptr);
-
- int m_fd { -1 };
- bool m_listening { false };
- RefPtr<Notifier> m_notifier;
-};
-
-}
diff --git a/Libraries/LibCore/TCPSocket.cpp b/Libraries/LibCore/TCPSocket.cpp
deleted file mode 100644
index 6029a82432..0000000000
--- a/Libraries/LibCore/TCPSocket.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/TCPSocket.h>
-#include <errno.h>
-#include <sys/socket.h>
-
-#ifndef SOCK_NONBLOCK
-# include <sys/ioctl.h>
-#endif
-
-namespace Core {
-
-TCPSocket::TCPSocket(int fd, Object* parent)
- : Socket(Socket::Type::TCP, parent)
-{
- // NOTE: This constructor is used by TCPServer::accept(), so the socket is already connected.
- m_connected = true;
- set_fd(fd);
- set_mode(IODevice::ReadWrite);
- set_error(0);
-}
-
-TCPSocket::TCPSocket(Object* parent)
- : Socket(Socket::Type::TCP, parent)
-{
-#ifdef SOCK_NONBLOCK
- int fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
-#else
- int fd = socket(AF_INET, SOCK_STREAM, 0);
- int option = 1;
- ioctl(fd, FIONBIO, &option);
-#endif
- if (fd < 0) {
- set_error(errno);
- } else {
- set_fd(fd);
- set_mode(IODevice::ReadWrite);
- set_error(0);
- }
-}
-
-TCPSocket::~TCPSocket()
-{
-}
-
-}
diff --git a/Libraries/LibCore/TCPSocket.h b/Libraries/LibCore/TCPSocket.h
deleted file mode 100644
index 8bdd1ae70c..0000000000
--- a/Libraries/LibCore/TCPSocket.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Badge.h>
-#include <LibCore/Socket.h>
-
-namespace Core {
-
-class TCPSocket final : public Socket {
- C_OBJECT(TCPSocket)
-public:
- virtual ~TCPSocket() override;
-
-private:
- TCPSocket(int fd, Object* parent = nullptr);
- explicit TCPSocket(Object* parent = nullptr);
-};
-
-}
diff --git a/Libraries/LibCore/Timer.cpp b/Libraries/LibCore/Timer.cpp
deleted file mode 100644
index aa0a0cb17d..0000000000
--- a/Libraries/LibCore/Timer.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/Timer.h>
-
-namespace Core {
-
-Timer::Timer(Object* parent)
- : Object(parent)
-{
-}
-
-Timer::Timer(int interval, Function<void()>&& timeout_handler, Object* parent)
- : Object(parent)
- , on_timeout(move(timeout_handler))
-{
- start(interval);
-}
-
-Timer::~Timer()
-{
-}
-
-void Timer::start()
-{
- start(m_interval);
-}
-
-void Timer::start(int interval)
-{
- if (m_active)
- return;
- m_interval = interval;
- start_timer(interval);
- m_active = true;
-}
-
-void Timer::restart()
-{
- restart(m_interval);
-}
-
-void Timer::restart(int interval)
-{
- if (m_active)
- stop();
- start(interval);
-}
-
-void Timer::stop()
-{
- if (!m_active)
- return;
- stop_timer();
- m_active = false;
-}
-
-void Timer::timer_event(TimerEvent&)
-{
- if (m_single_shot)
- stop();
- else {
- if (m_interval_dirty) {
- stop();
- start(m_interval);
- }
- }
-
- if (on_timeout)
- on_timeout();
-}
-
-}
diff --git a/Libraries/LibCore/Timer.h b/Libraries/LibCore/Timer.h
deleted file mode 100644
index 04f41e39a0..0000000000
--- a/Libraries/LibCore/Timer.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/Function.h>
-#include <LibCore/Object.h>
-
-namespace Core {
-
-class Timer final : public Object {
- C_OBJECT(Timer);
-
-public:
- static NonnullRefPtr<Timer> create_single_shot(int interval, Function<void()>&& timeout_handler, Object* parent = nullptr)
- {
- auto timer = adopt(*new Timer(interval, move(timeout_handler), parent));
- timer->set_single_shot(true);
- timer->stop();
- return timer;
- }
-
- virtual ~Timer() override;
-
- void start();
- void start(int interval);
- void restart();
- void restart(int interval);
- void stop();
-
- bool is_active() const { return m_active; }
- int interval() const { return m_interval; }
- void set_interval(int interval)
- {
- if (m_interval == interval)
- return;
- m_interval = interval;
- m_interval_dirty = true;
- }
-
- bool is_single_shot() const { return m_single_shot; }
- void set_single_shot(bool single_shot) { m_single_shot = single_shot; }
-
- Function<void()> on_timeout;
-
-private:
- explicit Timer(Object* parent = nullptr);
- Timer(int interval, Function<void()>&& timeout_handler, Object* parent = nullptr);
-
- virtual void timer_event(TimerEvent&) override;
-
- bool m_active { false };
- bool m_single_shot { false };
- bool m_interval_dirty { false };
- int m_interval { 0 };
-};
-
-}
diff --git a/Libraries/LibCore/UDPServer.cpp b/Libraries/LibCore/UDPServer.cpp
deleted file mode 100644
index 6716865e6b..0000000000
--- a/Libraries/LibCore/UDPServer.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/IPv4Address.h>
-#include <AK/Types.h>
-#include <LibCore/Notifier.h>
-#include <LibCore/UDPServer.h>
-#include <LibCore/UDPSocket.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#ifndef SOCK_NONBLOCK
-# include <sys/ioctl.h>
-#endif
-
-namespace Core {
-
-UDPServer::UDPServer(Object* parent)
- : Object(parent)
-{
-#ifdef SOCK_NONBLOCK
- m_fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
-#else
- m_fd = socket(AF_INET, SOCK_DGRAM, 0);
- int option = 1;
- ioctl(m_fd, FIONBIO, &option);
- fcntl(m_fd, F_SETFD, FD_CLOEXEC);
-#endif
- ASSERT(m_fd >= 0);
-}
-
-UDPServer::~UDPServer()
-{
- ::close(m_fd);
-}
-
-bool UDPServer::bind(const IPv4Address& address, u16 port)
-{
- if (m_bound)
- return false;
-
- auto saddr = SocketAddress(address, port);
- auto in = saddr.to_sockaddr_in();
-
- if (::bind(m_fd, (const sockaddr*)&in, sizeof(in)) != 0) {
- perror("UDPServer::bind");
- return false;
- }
-
- m_bound = true;
-
- m_notifier = Notifier::construct(m_fd, Notifier::Event::Read, this);
- m_notifier->on_ready_to_read = [this] {
- if (on_ready_to_receive)
- on_ready_to_receive();
- };
- return true;
-}
-
-ByteBuffer UDPServer::receive(size_t size, sockaddr_in& in)
-{
- auto buf = ByteBuffer::create_uninitialized(size);
- socklen_t in_len = sizeof(in);
- ssize_t rlen = ::recvfrom(m_fd, buf.data(), size, 0, (sockaddr*)&in, &in_len);
- if (rlen < 0) {
- dbgln("recvfrom: {}", strerror(errno));
- return {};
- }
-
- buf.trim(rlen);
- return buf;
-}
-
-Optional<IPv4Address> UDPServer::local_address() const
-{
- if (m_fd == -1)
- return {};
-
- sockaddr_in address;
- socklen_t len = sizeof(address);
- if (getsockname(m_fd, (sockaddr*)&address, &len) != 0)
- return {};
-
- return IPv4Address(address.sin_addr.s_addr);
-}
-
-Optional<u16> UDPServer::local_port() const
-{
- if (m_fd == -1)
- return {};
-
- sockaddr_in address;
- socklen_t len = sizeof(address);
- if (getsockname(m_fd, (sockaddr*)&address, &len) != 0)
- return {};
-
- return ntohs(address.sin_port);
-}
-
-}
diff --git a/Libraries/LibCore/UDPServer.h b/Libraries/LibCore/UDPServer.h
deleted file mode 100644
index 29dfd29d60..0000000000
--- a/Libraries/LibCore/UDPServer.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/ByteBuffer.h>
-#include <AK/Forward.h>
-#include <AK/Function.h>
-#include <LibCore/Forward.h>
-#include <LibCore/Object.h>
-#include <LibCore/SocketAddress.h>
-
-namespace Core {
-
-class UDPServer : public Object {
- C_OBJECT(UDPServer)
-public:
- virtual ~UDPServer() override;
-
- bool is_bound() const { return m_bound; }
-
- bool bind(const IPv4Address& address, u16 port);
- ByteBuffer receive(size_t size, sockaddr_in& from);
- ByteBuffer receive(size_t size)
- {
- struct sockaddr_in saddr;
- return receive(size, saddr);
- };
-
- Optional<IPv4Address> local_address() const;
- Optional<u16> local_port() const;
-
- Function<void()> on_ready_to_receive;
-
-private:
- explicit UDPServer(Object* parent = nullptr);
-
- int m_fd { -1 };
- bool m_bound { false };
- RefPtr<Notifier> m_notifier;
-};
-
-}
diff --git a/Libraries/LibCore/UDPSocket.cpp b/Libraries/LibCore/UDPSocket.cpp
deleted file mode 100644
index c319ac3dc1..0000000000
--- a/Libraries/LibCore/UDPSocket.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibCore/UDPSocket.h>
-#include <errno.h>
-#include <sys/socket.h>
-
-#ifndef SOCK_NONBLOCK
-# include <sys/ioctl.h>
-#endif
-
-namespace Core {
-
-UDPSocket::UDPSocket(Object* parent)
- : Socket(Socket::Type::UDP, parent)
-{
-#ifdef SOCK_NONBLOCK
- int fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0);
-#else
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
- int option = 1;
- ioctl(fd, FIONBIO, &option);
-#endif
-
- if (fd < 0) {
- set_error(errno);
- } else {
- set_fd(fd);
- set_mode(IODevice::ReadWrite);
- set_error(0);
- }
-}
-
-UDPSocket::~UDPSocket()
-{
-}
-
-}
diff --git a/Libraries/LibCore/UDPSocket.h b/Libraries/LibCore/UDPSocket.h
deleted file mode 100644
index 3bb65d9831..0000000000
--- a/Libraries/LibCore/UDPSocket.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibCore/Socket.h>
-
-namespace Core {
-
-class UDPSocket final : public Socket {
- C_OBJECT(UDPSocket)
-public:
- virtual ~UDPSocket() override;
-
-private:
- explicit UDPSocket(Object* parent = nullptr);
-};
-
-}
diff --git a/Libraries/LibCore/puff.cpp b/Libraries/LibCore/puff.cpp
deleted file mode 100644
index c6c90d7142..0000000000
--- a/Libraries/LibCore/puff.cpp
+++ /dev/null
@@ -1,840 +0,0 @@
-/*
- * puff.c
- * Copyright (C) 2002-2013 Mark Adler
- * For conditions of distribution and use, see copyright notice in puff.h
- * version 2.3, 21 Jan 2013
- *
- * puff.c is a simple inflate written to be an unambiguous way to specify the
- * deflate format. It is not written for speed but rather simplicity. As a
- * side benefit, this code might actually be useful when small code is more
- * important than speed, such as bootstrap applications. For typical deflate
- * data, zlib's inflate() is about four times as fast as puff(). zlib's
- * inflate compiles to around 20K on my machine, whereas puff.c compiles to
- * around 4K on my machine (a PowerPC using GNU cc). If the faster decode()
- * function here is used, then puff() is only twice as slow as zlib's
- * inflate().
- *
- * All dynamically allocated memory comes from the stack. The stack required
- * is less than 2K bytes. This code is compatible with 16-bit int's and
- * assumes that long's are at least 32 bits. puff.c uses the short data type,
- * assumed to be 16 bits, for arrays in order to conserve memory. The code
- * works whether integers are stored big endian or little endian.
- *
- * In the comments below are "Format notes" that describe the inflate process
- * and document some of the less obvious aspects of the format. This source
- * code is meant to supplement RFC 1951, which formally describes the deflate
- * format:
- *
- * http://www.zlib.org/rfc-deflate.html
- */
-
-/*
- * Change history:
- *
- * 1.0 10 Feb 2002 - First version
- * 1.1 17 Feb 2002 - Clarifications of some comments and notes
- * - Update puff() dest and source pointers on negative
- * errors to facilitate debugging deflators
- * - Remove longest from struct huffman -- not needed
- * - Simplify offs[] index in construct()
- * - Add input size and checking, using longjmp() to
- * maintain easy readability
- * - Use short data type for large arrays
- * - Use pointers instead of long to specify source and
- * destination sizes to avoid arbitrary 4 GB limits
- * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!),
- * but leave simple version for readabilty
- * - Make sure invalid distances detected if pointers
- * are 16 bits
- * - Fix fixed codes table error
- * - Provide a scanning mode for determining size of
- * uncompressed data
- * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly]
- * - Add a puff.h file for the interface
- * - Add braces in puff() for else do [Gailly]
- * - Use indexes instead of pointers for readability
- * 1.4 31 Mar 2002 - Simplify construct() code set check
- * - Fix some comments
- * - Add FIXLCODES #define
- * 1.5 6 Apr 2002 - Minor comment fixes
- * 1.6 7 Aug 2002 - Minor format changes
- * 1.7 3 Mar 2003 - Added test code for distribution
- * - Added zlib-like license
- * 1.8 9 Jan 2004 - Added some comments on no distance codes case
- * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland]
- * - Catch missing end-of-block symbol error
- * 2.0 25 Jul 2008 - Add #define to permit distance too far back
- * - Add option in TEST code for puff to write the data
- * - Add option in TEST code to skip input bytes
- * - Allow TEST code to read from piped stdin
- * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers
- * - Avoid unsigned comparisons for even happier compilers
- * 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer]
- * - Add const where appropriate [Oberhumer]
- * - Split if's and ?'s for coverage testing
- * - Break out test code to separate file
- * - Move NIL to puff.h
- * - Allow incomplete code only if single code length is 1
- * - Add full code coverage test to Makefile
- * 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks
- */
-
-#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
-#include "puff.h" /* prototype for puff() */
-
-#define local static /* for local function definitions */
-
-/*
- * Maximums for allocations and loops. It is not useful to change these --
- * they are fixed by the deflate format.
- */
-#define MAXBITS 15 /* maximum bits in a code */
-#define MAXLCODES 286 /* maximum number of literal/length codes */
-#define MAXDCODES 30 /* maximum number of distance codes */
-#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */
-#define FIXLCODES 288 /* number of fixed literal/length codes */
-
-/* input and output state */
-struct state {
- /* output state */
- unsigned char *out; /* output buffer */
- unsigned long outlen; /* available space at out */
- unsigned long outcnt; /* bytes written to out so far */
-
- /* input state */
- const unsigned char *in; /* input buffer */
- unsigned long inlen; /* available input at in */
- unsigned long incnt; /* bytes read so far */
- int bitbuf; /* bit buffer */
- int bitcnt; /* number of bits in bit buffer */
-
- /* input limit error return state for bits() and decode() */
- jmp_buf env;
-};
-
-/*
- * Return need bits from the input stream. This always leaves less than
- * eight bits in the buffer. bits() works properly for need == 0.
- *
- * Format notes:
- *
- * - Bits are stored in bytes from the least significant bit to the most
- * significant bit. Therefore bits are dropped from the bottom of the bit
- * buffer, using shift right, and new bytes are appended to the top of the
- * bit buffer, using shift left.
- */
-local int bits(struct state *s, int need)
-{
- long val; /* bit accumulator (can use up to 20 bits) */
-
- /* load at least need bits into val */
- val = s->bitbuf;
- while (s->bitcnt < need) {
- if (s->incnt == s->inlen)
- longjmp(s->env, 1); /* out of input */
- val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
- s->bitcnt += 8;
- }
-
- /* drop need bits and update buffer, always zero to seven bits left */
- s->bitbuf = (int)(val >> need);
- s->bitcnt -= need;
-
- /* return need bits, zeroing the bits above that */
- return (int)(val & ((1L << need) - 1));
-}
-
-/*
- * Process a stored block.
- *
- * Format notes:
- *
- * - After the two-bit stored block type (00), the stored block length and
- * stored bytes are byte-aligned for fast copying. Therefore any leftover
- * bits in the byte that has the last bit of the type, as many as seven, are
- * discarded. The value of the discarded bits are not defined and should not
- * be checked against any expectation.
- *
- * - The second inverted copy of the stored block length does not have to be
- * checked, but it's probably a good idea to do so anyway.
- *
- * - A stored block can have zero length. This is sometimes used to byte-align
- * subsets of the compressed data for random access or partial recovery.
- */
-local int stored(struct state *s)
-{
- unsigned len; /* length of stored block */
-
- /* discard leftover bits from current byte (assumes s->bitcnt < 8) */
- s->bitbuf = 0;
- s->bitcnt = 0;
-
- /* get length and check against its one's complement */
- if (s->incnt + 4 > s->inlen)
- return 2; /* not enough input */
- len = s->in[s->incnt++];
- len |= s->in[s->incnt++] << 8;
- if (s->in[s->incnt++] != (~len & 0xff) ||
- s->in[s->incnt++] != ((~len >> 8) & 0xff))
- return -2; /* didn't match complement! */
-
- /* copy len bytes from in to out */
- if (s->incnt + len > s->inlen)
- return 2; /* not enough input */
- if (s->out != NIL) {
- if (s->outcnt + len > s->outlen)
- return 1; /* not enough output space */
- while (len--)
- s->out[s->outcnt++] = s->in[s->incnt++];
- }
- else { /* just scanning */
- s->outcnt += len;
- s->incnt += len;
- }
-
- /* done with a valid stored block */
- return 0;
-}
-
-/*
- * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
- * each length, which for a canonical code are stepped through in order.
- * symbol[] are the symbol values in canonical order, where the number of
- * entries is the sum of the counts in count[]. The decoding process can be
- * seen in the function decode() below.
- */
-struct huffman {
- short *count; /* number of symbols of each length */
- short *symbol; /* canonically ordered symbols */
-};
-
-/*
- * Decode a code from the stream s using huffman table h. Return the symbol or
- * a negative value if there is an error. If all of the lengths are zero, i.e.
- * an empty code, or if the code is incomplete and an invalid code is received,
- * then -10 is returned after reading MAXBITS bits.
- *
- * Format notes:
- *
- * - The codes as stored in the compressed data are bit-reversed relative to
- * a simple integer ordering of codes of the same lengths. Hence below the
- * bits are pulled from the compressed data one at a time and used to
- * build the code value reversed from what is in the stream in order to
- * permit simple integer comparisons for decoding. A table-based decoding
- * scheme (as used in zlib) does not need to do this reversal.
- *
- * - The first code for the shortest length is all zeros. Subsequent codes of
- * the same length are simply integer increments of the previous code. When
- * moving up a length, a zero bit is appended to the code. For a complete
- * code, the last code of the longest length will be all ones.
- *
- * - Incomplete codes are handled by this decoder, since they are permitted
- * in the deflate format. See the format notes for fixed() and dynamic().
- */
-#ifdef SLOW
-local int decode(struct state *s, const struct huffman *h)
-{
- int len; /* current number of bits in code */
- int code; /* len bits being decoded */
- int first; /* first code of length len */
- int count; /* number of codes of length len */
- int index; /* index of first code of length len in symbol table */
-
- code = first = index = 0;
- for (len = 1; len <= MAXBITS; len++) {
- code |= bits(s, 1); /* get next bit */
- count = h->count[len];
- if (code - count < first) /* if length len, return symbol */
- return h->symbol[index + (code - first)];
- index += count; /* else update for next length */
- first += count;
- first <<= 1;
- code <<= 1;
- }
- return -10; /* ran out of codes */
-}
-
-/*
- * A faster version of decode() for real applications of this code. It's not
- * as readable, but it makes puff() twice as fast. And it only makes the code
- * a few percent larger.
- */
-#else /* !SLOW */
-local int decode(struct state *s, const struct huffman *h)
-{
- int len; /* current number of bits in code */
- int code; /* len bits being decoded */
- int first; /* first code of length len */
- int count; /* number of codes of length len */
- int index; /* index of first code of length len in symbol table */
- int bitbuf; /* bits from stream */
- int left; /* bits left in next or left to process */
- short *next; /* next number of codes */
-
- bitbuf = s->bitbuf;
- left = s->bitcnt;
- code = first = index = 0;
- len = 1;
- next = h->count + 1;
- while (1) {
- while (left--) {
- code |= bitbuf & 1;
- bitbuf >>= 1;
- count = *next++;
- if (code - count < first) { /* if length len, return symbol */
- s->bitbuf = bitbuf;
- s->bitcnt = (s->bitcnt - len) & 7;
- return h->symbol[index + (code - first)];
- }
- index += count; /* else update for next length */
- first += count;
- first <<= 1;
- code <<= 1;
- len++;
- }
- left = (MAXBITS+1) - len;
- if (left == 0)
- break;
- if (s->incnt == s->inlen)
- longjmp(s->env, 1); /* out of input */
- bitbuf = s->in[s->incnt++];
- if (left > 8)
- left = 8;
- }
- return -10; /* ran out of codes */
-}
-#endif /* SLOW */
-
-/*
- * Given the list of code lengths length[0..n-1] representing a canonical
- * Huffman code for n symbols, construct the tables required to decode those
- * codes. Those tables are the number of codes of each length, and the symbols
- * sorted by length, retaining their original order within each length. The
- * return value is zero for a complete code set, negative for an over-
- * subscribed code set, and positive for an incomplete code set. The tables
- * can be used if the return value is zero or positive, but they cannot be used
- * if the return value is negative. If the return value is zero, it is not
- * possible for decode() using that table to return an error--any stream of
- * enough bits will resolve to a symbol. If the return value is positive, then
- * it is possible for decode() using that table to return an error for received
- * codes past the end of the incomplete lengths.
- *
- * Not used by decode(), but used for error checking, h->count[0] is the number
- * of the n symbols not in the code. So n - h->count[0] is the number of
- * codes. This is useful for checking for incomplete codes that have more than
- * one symbol, which is an error in a dynamic block.
- *
- * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
- * This is assured by the construction of the length arrays in dynamic() and
- * fixed() and is not verified by construct().
- *
- * Format notes:
- *
- * - Permitted and expected examples of incomplete codes are one of the fixed
- * codes and any code with a single symbol which in deflate is coded as one
- * bit instead of zero bits. See the format notes for fixed() and dynamic().
- *
- * - Within a given code length, the symbols are kept in ascending order for
- * the code bits definition.
- */
-local int construct(struct huffman *h, const short *length, int n)
-{
- int symbol; /* current symbol when stepping through length[] */
- int len; /* current length when stepping through h->count[] */
- int left; /* number of possible codes left of current length */
- short offs[MAXBITS+1]; /* offsets in symbol table for each length */
-
- /* count number of codes of each length */
- for (len = 0; len <= MAXBITS; len++)
- h->count[len] = 0;
- for (symbol = 0; symbol < n; symbol++)
- (h->count[length[symbol]])++; /* assumes lengths are within bounds */
- if (h->count[0] == n) /* no codes! */
- return 0; /* complete, but decode() will fail */
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1; /* one possible code of zero length */
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1; /* one more bit, double codes left */
- left -= h->count[len]; /* deduct count from possible codes */
- if (left < 0)
- return left; /* over-subscribed--return negative */
- } /* left > 0 means incomplete */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + h->count[len];
-
- /*
- * put symbols in table sorted by length, by symbol order within each
- * length
- */
- for (symbol = 0; symbol < n; symbol++)
- if (length[symbol] != 0)
- h->symbol[offs[length[symbol]]++] = symbol;
-
- /* return zero for complete set, positive for incomplete set */
- return left;
-}
-
-/*
- * Decode literal/length and distance codes until an end-of-block code.
- *
- * Format notes:
- *
- * - Compressed data that is after the block type if fixed or after the code
- * description if dynamic is a combination of literals and length/distance
- * pairs terminated by and end-of-block code. Literals are simply Huffman
- * coded bytes. A length/distance pair is a coded length followed by a
- * coded distance to represent a string that occurs earlier in the
- * uncompressed data that occurs again at the current location.
- *
- * - Literals, lengths, and the end-of-block code are combined into a single
- * code of up to 286 symbols. They are 256 literals (0..255), 29 length
- * symbols (257..285), and the end-of-block symbol (256).
- *
- * - There are 256 possible lengths (3..258), and so 29 symbols are not enough
- * to represent all of those. Lengths 3..10 and 258 are in fact represented
- * by just a length symbol. Lengths 11..257 are represented as a symbol and
- * some number of extra bits that are added as an integer to the base length
- * of the length symbol. The number of extra bits is determined by the base
- * length symbol. These are in the static arrays below, lens[] for the base
- * lengths and lext[] for the corresponding number of extra bits.
- *
- * - The reason that 258 gets its own symbol is that the longest length is used
- * often in highly redundant files. Note that 258 can also be coded as the
- * base value 227 plus the maximum extra value of 31. While a good deflate
- * should never do this, it is not an error, and should be decoded properly.
- *
- * - If a length is decoded, including its extra bits if any, then it is
- * followed a distance code. There are up to 30 distance symbols. Again
- * there are many more possible distances (1..32768), so extra bits are added
- * to a base value represented by the symbol. The distances 1..4 get their
- * own symbol, but the rest require extra bits. The base distances and
- * corresponding number of extra bits are below in the static arrays dist[]
- * and dext[].
- *
- * - Literal bytes are simply written to the output. A length/distance pair is
- * an instruction to copy previously uncompressed bytes to the output. The
- * copy is from distance bytes back in the output stream, copying for length
- * bytes.
- *
- * - Distances pointing before the beginning of the output data are not
- * permitted.
- *
- * - Overlapped copies, where the length is greater than the distance, are
- * allowed and common. For example, a distance of one and a length of 258
- * simply copies the last byte 258 times. A distance of four and a length of
- * twelve copies the last four bytes three times. A simple forward copy
- * ignoring whether the length is greater than the distance or not implements
- * this correctly. You should not use memcpy() since its behavior is not
- * defined for overlapped arrays. You should not use memmove() or bcopy()
- * since though their behavior -is- defined for overlapping arrays, it is
- * defined to do the wrong thing in this case.
- */
-local int codes(struct state *s,
- const struct huffman *lencode,
- const struct huffman *distcode)
-{
- int symbol; /* decoded symbol */
- int len; /* length for copy */
- unsigned dist; /* distance for copy */
- static const short lens[29] = { /* Size base for length codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
- static const short lext[29] = { /* Extra bits for length codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
- static const short dists[30] = { /* Offset base for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
- static const short dext[30] = { /* Extra bits for distance codes 0..29 */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
- /* decode literals and length/distance pairs */
- do {
- symbol = decode(s, lencode);
- if (symbol < 0)
- return symbol; /* invalid symbol */
- if (symbol < 256) { /* literal: symbol is the byte */
- /* write out the literal */
- if (s->out != NIL) {
- if (s->outcnt == s->outlen)
- return 1;
- s->out[s->outcnt] = symbol;
- }
- s->outcnt++;
- }
- else if (symbol > 256) { /* length */
- /* get and compute length */
- symbol -= 257;
- if (symbol >= 29)
- return -10; /* invalid fixed code */
- len = lens[symbol] + bits(s, lext[symbol]);
-
- /* get and check distance */
- symbol = decode(s, distcode);
- if (symbol < 0)
- return symbol; /* invalid symbol */
- dist = dists[symbol] + bits(s, dext[symbol]);
-#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
- if (dist > s->outcnt)
- return -11; /* distance too far back */
-#endif
-
- /* copy length bytes from distance bytes back */
- if (s->out != NIL) {
- if (s->outcnt + len > s->outlen)
- return 1;
- while (len--) {
- s->out[s->outcnt] =
-#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
- dist > s->outcnt ?
- 0 :
-#endif
- s->out[s->outcnt - dist];
- s->outcnt++;
- }
- }
- else
- s->outcnt += len;
- }
- } while (symbol != 256); /* end of block symbol */
-
- /* done with a valid fixed or dynamic block */
- return 0;
-}
-
-/*
- * Process a fixed codes block.
- *
- * Format notes:
- *
- * - This block type can be useful for compressing small amounts of data for
- * which the size of the code descriptions in a dynamic block exceeds the
- * benefit of custom codes for that block. For fixed codes, no bits are
- * spent on code descriptions. Instead the code lengths for literal/length
- * codes and distance codes are fixed. The specific lengths for each symbol
- * can be seen in the "for" loops below.
- *
- * - The literal/length code is complete, but has two symbols that are invalid
- * and should result in an error if received. This cannot be implemented
- * simply as an incomplete code since those two symbols are in the "middle"
- * of the code. They are eight bits long and the longest literal/length\
- * code is nine bits. Therefore the code must be constructed with those
- * symbols, and the invalid symbols must be detected after decoding.
- *
- * - The fixed distance codes also have two invalid symbols that should result
- * in an error if received. Since all of the distance codes are the same
- * length, this can be implemented as an incomplete code. Then the invalid
- * codes are detected while decoding.
- */
-local int fixed(struct state *s)
-{
- static int virgin = 1;
- static short lencnt[MAXBITS+1], lensym[FIXLCODES];
- static short distcnt[MAXBITS+1], distsym[MAXDCODES];
- static struct huffman lencode, distcode;
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- int symbol;
- short lengths[FIXLCODES];
-
- /* construct lencode and distcode */
- lencode.count = lencnt;
- lencode.symbol = lensym;
- distcode.count = distcnt;
- distcode.symbol = distsym;
-
- /* literal/length table */
- for (symbol = 0; symbol < 144; symbol++)
- lengths[symbol] = 8;
- for (; symbol < 256; symbol++)
- lengths[symbol] = 9;
- for (; symbol < 280; symbol++)
- lengths[symbol] = 7;
- for (; symbol < FIXLCODES; symbol++)
- lengths[symbol] = 8;
- construct(&lencode, lengths, FIXLCODES);
-
- /* distance table */
- for (symbol = 0; symbol < MAXDCODES; symbol++)
- lengths[symbol] = 5;
- construct(&distcode, lengths, MAXDCODES);
-
- /* do this just once */
- virgin = 0;
- }
-
- /* decode data until end-of-block code */
- return codes(s, &lencode, &distcode);
-}
-
-/*
- * Process a dynamic codes block.
- *
- * Format notes:
- *
- * - A dynamic block starts with a description of the literal/length and
- * distance codes for that block. New dynamic blocks allow the compressor to
- * rapidly adapt to changing data with new codes optimized for that data.
- *
- * - The codes used by the deflate format are "canonical", which means that
- * the actual bits of the codes are generated in an unambiguous way simply
- * from the number of bits in each code. Therefore the code descriptions
- * are simply a list of code lengths for each symbol.
- *
- * - The code lengths are stored in order for the symbols, so lengths are
- * provided for each of the literal/length symbols, and for each of the
- * distance symbols.
- *
- * - If a symbol is not used in the block, this is represented by a zero as
- * as the code length. This does not mean a zero-length code, but rather
- * that no code should be created for this symbol. There is no way in the
- * deflate format to represent a zero-length code.
- *
- * - The maximum number of bits in a code is 15, so the possible lengths for
- * any code are 1..15.
- *
- * - The fact that a length of zero is not permitted for a code has an
- * interesting consequence. Normally if only one symbol is used for a given
- * code, then in fact that code could be represented with zero bits. However
- * in deflate, that code has to be at least one bit. So for example, if
- * only a single distance base symbol appears in a block, then it will be
- * represented by a single code of length one, in particular one 0 bit. This
- * is an incomplete code, since if a 1 bit is received, it has no meaning,
- * and should result in an error. So incomplete distance codes of one symbol
- * should be permitted, and the receipt of invalid codes should be handled.
- *
- * - It is also possible to have a single literal/length code, but that code
- * must be the end-of-block code, since every dynamic block has one. This
- * is not the most efficient way to create an empty block (an empty fixed
- * block is fewer bits), but it is allowed by the format. So incomplete
- * literal/length codes of one symbol should also be permitted.
- *
- * - If there are only literal codes and no lengths, then there are no distance
- * codes. This is represented by one distance code with zero bits.
- *
- * - The list of up to 286 length/literal lengths and up to 30 distance lengths
- * are themselves compressed using Huffman codes and run-length encoding. In
- * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
- * that length, and the symbols 16, 17, and 18 are run-length instructions.
- * Each of 16, 17, and 18 are follwed by extra bits to define the length of
- * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10
- * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols
- * are common, hence the special coding for zero lengths.
- *
- * - The symbols for 0..18 are Huffman coded, and so that code must be
- * described first. This is simply a sequence of up to 19 three-bit values
- * representing no code (0) or the code length for that symbol (1..7).
- *
- * - A dynamic block starts with three fixed-size counts from which is computed
- * the number of literal/length code lengths, the number of distance code
- * lengths, and the number of code length code lengths (ok, you come up with
- * a better name!) in the code descriptions. For the literal/length and
- * distance codes, lengths after those provided are considered zero, i.e. no
- * code. The code length code lengths are received in a permuted order (see
- * the order[] array below) to make a short code length code length list more
- * likely. As it turns out, very short and very long codes are less likely
- * to be seen in a dynamic code description, hence what may appear initially
- * to be a peculiar ordering.
- *
- * - Given the number of literal/length code lengths (nlen) and distance code
- * lengths (ndist), then they are treated as one long list of nlen + ndist
- * code lengths. Therefore run-length coding can and often does cross the
- * boundary between the two sets of lengths.
- *
- * - So to summarize, the code description at the start of a dynamic block is
- * three counts for the number of code lengths for the literal/length codes,
- * the distance codes, and the code length codes. This is followed by the
- * code length code lengths, three bits each. This is used to construct the
- * code length code which is used to read the remainder of the lengths. Then
- * the literal/length code lengths and distance lengths are read as a single
- * set of lengths using the code length codes. Codes are constructed from
- * the resulting two sets of lengths, and then finally you can start
- * decoding actual compressed data in the block.
- *
- * - For reference, a "typical" size for the code description in a dynamic
- * block is around 80 bytes.
- */
-local int dynamic(struct state *s)
-{
- int nlen, ndist, ncode; /* number of lengths in descriptor */
- int index; /* index of lengths[] */
- int err; /* construct() return value */
- short lengths[MAXCODES]; /* descriptor code lengths */
- short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
- short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
- struct huffman lencode, distcode; /* length and distance codes */
- static const short order[19] = /* permutation of code length codes */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- /* construct lencode and distcode */
- lencode.count = lencnt;
- lencode.symbol = lensym;
- distcode.count = distcnt;
- distcode.symbol = distsym;
-
- /* get number of lengths in each table, check lengths */
- nlen = bits(s, 5) + 257;
- ndist = bits(s, 5) + 1;
- ncode = bits(s, 4) + 4;
- if (nlen > MAXLCODES || ndist > MAXDCODES)
- return -3; /* bad counts */
-
- /* read code length code lengths (really), missing lengths are zero */
- for (index = 0; index < ncode; index++)
- lengths[order[index]] = bits(s, 3);
- for (; index < 19; index++)
- lengths[order[index]] = 0;
-
- /* build huffman table for code lengths codes (use lencode temporarily) */
- err = construct(&lencode, lengths, 19);
- if (err != 0) /* require complete code set here */
- return -4;
-
- /* read length/literal and distance code length tables */
- index = 0;
- while (index < nlen + ndist) {
- int symbol; /* decoded value */
- int len; /* last length to repeat */
-
- symbol = decode(s, &lencode);
- if (symbol < 0)
- return symbol; /* invalid symbol */
- if (symbol < 16) /* length in 0..15 */
- lengths[index++] = symbol;
- else { /* repeat instruction */
- len = 0; /* assume repeating zeros */
- if (symbol == 16) { /* repeat last length 3..6 times */
- if (index == 0)
- return -5; /* no last length! */
- len = lengths[index - 1]; /* last length */
- symbol = 3 + bits(s, 2);
- }
- else if (symbol == 17) /* repeat zero 3..10 times */
- symbol = 3 + bits(s, 3);
- else /* == 18, repeat zero 11..138 times */
- symbol = 11 + bits(s, 7);
- if (index + symbol > nlen + ndist)
- return -6; /* too many lengths! */
- while (symbol--) /* repeat last or zero symbol times */
- lengths[index++] = len;
- }
- }
-
- /* check for end-of-block code -- there better be one! */
- if (lengths[256] == 0)
- return -9;
-
- /* build huffman table for literal/length codes */
- err = construct(&lencode, lengths, nlen);
- if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
- return -7; /* incomplete code ok only for single length 1 code */
-
- /* build huffman table for distance codes */
- err = construct(&distcode, lengths + nlen, ndist);
- if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
- return -8; /* incomplete code ok only for single length 1 code */
-
- /* decode data until end-of-block code */
- return codes(s, &lencode, &distcode);
-}
-
-/*
- * Inflate source to dest. On return, destlen and sourcelen are updated to the
- * size of the uncompressed data and the size of the deflate data respectively.
- * On success, the return value of puff() is zero. If there is an error in the
- * source data, i.e. it is not in the deflate format, then a negative value is
- * returned. If there is not enough input available or there is not enough
- * output space, then a positive error is returned. In that case, destlen and
- * sourcelen are not updated to facilitate retrying from the beginning with the
- * provision of more input data or more output space. In the case of invalid
- * inflate data (a negative error), the dest and source pointers are updated to
- * facilitate the debugging of deflators.
- *
- * puff() also has a mode to determine the size of the uncompressed output with
- * no output written. For this dest must be (unsigned char *)0. In this case,
- * the input value of *destlen is ignored, and on return *destlen is set to the
- * size of the uncompressed output.
- *
- * The return codes are:
- *
- * 2: available inflate data did not terminate
- * 1: output space exhausted before completing inflate
- * 0: successful inflate
- * -1: invalid block type (type == 3)
- * -2: stored block length did not match one's complement
- * -3: dynamic block code description: too many length or distance codes
- * -4: dynamic block code description: code lengths codes incomplete
- * -5: dynamic block code description: repeat lengths with no first length
- * -6: dynamic block code description: repeat more than specified lengths
- * -7: dynamic block code description: invalid literal/length code lengths
- * -8: dynamic block code description: invalid distance code lengths
- * -9: dynamic block code description: missing end-of-block code
- * -10: invalid literal/length or distance code in fixed or dynamic block
- * -11: distance is too far back in fixed or dynamic block
- *
- * Format notes:
- *
- * - Three bits are read for each block to determine the kind of block and
- * whether or not it is the last block. Then the block is decoded and the
- * process repeated if it was not the last block.
- *
- * - The leftover bits in the last byte of the deflate data after the last
- * block (if it was a fixed or dynamic block) are undefined and have no
- * expected values to check.
- */
-int puff(unsigned char *dest, /* pointer to destination pointer */
- unsigned long *destlen, /* amount of output space */
- const unsigned char *source, /* pointer to source data pointer */
- unsigned long *sourcelen) /* amount of input available */
-{
- struct state s; /* input/output state */
- int last, type; /* block information */
- int err; /* return value */
-
- /* initialize output state */
- s.out = dest;
- s.outlen = *destlen; /* ignored if dest is NIL */
- s.outcnt = 0;
-
- /* initialize input state */
- s.in = source;
- s.inlen = *sourcelen;
- s.incnt = 0;
- s.bitbuf = 0;
- s.bitcnt = 0;
-
- /* return if bits() or decode() tries to read past available input */
- if (setjmp(s.env) != 0) /* if came back here via longjmp() */
- err = 2; /* then skip do-loop, return error */
- else {
- /* process blocks until last block or error */
- do {
- last = bits(&s, 1); /* one if last block */
- type = bits(&s, 2); /* block type 0..3 */
- err = type == 0 ?
- stored(&s) :
- (type == 1 ?
- fixed(&s) :
- (type == 2 ?
- dynamic(&s) :
- -1)); /* type == 3, invalid */
- if (err != 0)
- break; /* return with error */
- } while (!last);
- }
-
- /* update the lengths and return */
- if (err <= 0) {
- *destlen = s.outcnt;
- *sourcelen = s.incnt;
- }
- return err;
-}
diff --git a/Libraries/LibCore/puff.h b/Libraries/LibCore/puff.h
deleted file mode 100644
index 5943910403..0000000000
--- a/Libraries/LibCore/puff.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-/* puff.h
- Copyright (C) 2002-2013 Mark Adler, all rights reserved
- version 2.3, 21 Jan 2013
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * See puff.c for purpose and usage.
- */
-#ifndef NIL
-# define NIL ((unsigned char*)0) /* for no output option */
-#endif
-
-int puff(unsigned char* dest, /* pointer to destination pointer */
- unsigned long* destlen, /* amount of output space */
- const unsigned char* source, /* pointer to source data pointer */
- unsigned long* sourcelen); /* amount of input available */
-
-#ifdef __cplusplus
-}
-#endif