From 688702a2366e358dee11d4d0a2eff8f2af7ee08a Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Thu, 17 Oct 2024 19:59:28 -0300 Subject: [PATCH] fix: fix compiler errors on Windows --- src/fork-result.h | 33 +++++++++++++++++++++++++++++++++ src/json-util.cpp | 2 +- src/json-util.h | 2 +- src/jsonrpc-connection.h | 7 +------ src/jsonrpc-machine-c-api.cpp | 7 +++++++ src/jsonrpc-remote-machine.cpp | 1 + src/jsonrpc-virtual-machine.cpp | 1 + src/os-features.h | 4 ++++ src/os.cpp | 30 +++++++++++++++++++++++------- 9 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 src/fork-result.h diff --git a/src/fork-result.h b/src/fork-result.h new file mode 100644 index 000000000..0f47f43a3 --- /dev/null +++ b/src/fork-result.h @@ -0,0 +1,33 @@ +// Copyright Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with this program (see COPYING). If not, see . +// + +#ifndef FORK_RESULT_H +#define FORK_RESULT_H + +#include +#include + +namespace cartesi { + +/// Result of a fork +struct fork_result final { + std::string address; + uint32_t pid{}; +}; + +} // namespace cartesi + +#endif diff --git a/src/json-util.cpp b/src/json-util.cpp index be8ac9044..55177b9f9 100644 --- a/src/json-util.cpp +++ b/src/json-util.cpp @@ -31,10 +31,10 @@ #include "access-log.h" #include "base64.h" #include "bracket-note.h" +#include "fork-result.h" #include "interpret.h" #include "json-util.h" #include "json.hpp" -#include "jsonrpc-connection.h" #include "machine-config.h" #include "machine-memory-range-descr.h" #include "machine-merkle-tree.h" diff --git a/src/json-util.h b/src/json-util.h index a5d8429a2..73c0cbf41 100644 --- a/src/json-util.h +++ b/src/json-util.h @@ -29,8 +29,8 @@ #include "access-log.h" #include "bracket-note.h" +#include "fork-result.h" #include "interpret.h" -#include "jsonrpc-connection.h" #include "machine-config.h" #include "machine-memory-range-descr.h" #include "machine-merkle-tree.h" diff --git a/src/jsonrpc-connection.h b/src/jsonrpc-connection.h index 0d5dc6d1c..2f48063d6 100644 --- a/src/jsonrpc-connection.h +++ b/src/jsonrpc-connection.h @@ -27,16 +27,11 @@ #include #pragma GCC diagnostic pop +#include "fork-result.h" #include "semantic-version.h" namespace cartesi { -/// Result of a fork -struct fork_result final { - std::string address; - uint32_t pid{}; -}; - class jsonrpc_connection final { public: jsonrpc_connection(std::string remote_address, bool detach_server); diff --git a/src/jsonrpc-machine-c-api.cpp b/src/jsonrpc-machine-c-api.cpp index 069ffd4ed..b35a059ce 100644 --- a/src/jsonrpc-machine-c-api.cpp +++ b/src/jsonrpc-machine-c-api.cpp @@ -89,6 +89,7 @@ cm_error cm_jsonrpc_connect(const char *address, int detach_server, cm_jsonrpc_c return cm_result_failure(); } +#ifdef HAVE_FORK static boost::asio::ip::tcp::endpoint address_to_endpoint(const std::string &address) { try { const auto pos = address.find_last_of(':'); @@ -108,6 +109,7 @@ static std::string endpoint_to_string(const boost::asio::ip::tcp::endpoint &endp ss << endpoint; return ss.str(); } +#endif cm_error cm_jsonrpc_spawn_server(const char *address, int detach_server, cm_jsonrpc_connection **con, const char **bound_address, int32_t *pid) try { @@ -131,6 +133,7 @@ cm_error cm_jsonrpc_spawn_server(const char *address, int detach_server, cm_json if (pid == nullptr) { throw std::invalid_argument("invalid pid output"); } +#ifdef HAVE_FORK sigset_t mask{}; sigset_t omask{}; sigemptyset(&mask); // always returns 0 @@ -239,6 +242,10 @@ cm_error cm_jsonrpc_spawn_server(const char *address, int detach_server, cm_json } } return cm_result_success(); // code never reaches here +#else + throw std::runtime_error{"spawn is unsupported in this platform"}; + +#endif } catch (...) { *con = nullptr; *bound_address = nullptr; diff --git a/src/jsonrpc-remote-machine.cpp b/src/jsonrpc-remote-machine.cpp index 3d4ce60ff..835ae9079 100644 --- a/src/jsonrpc-remote-machine.cpp +++ b/src/jsonrpc-remote-machine.cpp @@ -54,6 +54,7 @@ #include "access-log.h" #include "base64.h" +#include "fork-result.h" #include "interpret.h" #include "json-util.h" #include "jsonrpc-connection.h" diff --git a/src/jsonrpc-virtual-machine.cpp b/src/jsonrpc-virtual-machine.cpp index 05101d02d..c6c505f71 100644 --- a/src/jsonrpc-virtual-machine.cpp +++ b/src/jsonrpc-virtual-machine.cpp @@ -37,6 +37,7 @@ #include "access-log.h" #include "base64.h" +#include "fork-result.h" #include "interpret.h" #include "json-util.h" #include "json.hpp" diff --git a/src/os-features.h b/src/os-features.h index 6daf54827..42b591f1d 100644 --- a/src/os-features.h +++ b/src/os-features.h @@ -68,4 +68,8 @@ #define HAVE_USLEEP #endif +#if !defined(NO_FORK) && (defined(__linux__) || defined(__unix__)) +#define HAVE_FORK +#endif + #endif diff --git a/src/os.cpp b/src/os.cpp index ad15da20c..af98d5255 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -34,7 +34,6 @@ #include "unique-c-ptr.h" #include -#include #ifdef HAVE_SIGACTION #include @@ -92,14 +91,18 @@ #else // not _WIN32 -#if defined(HAVE_TTY) || defined(HAVE_MMAP) || defined(HAVE_TERMIOS) || defined(HAVE_USLEEP) -#include // write/read/close +#if defined(HAVE_TTY) || defined(HAVE_MMAP) || defined(HAVE_TERMIOS) || defined(HAVE_USLEEP) || defined(HAVE_FORK) +#include // write/read/close/usleep/fork #endif #if defined(HAVE_SELECT) #include // select #endif +#if defined(HAVE_FORK) +#include +#endif + #define plat_write write #define plat_mkdir mkdir @@ -383,7 +386,7 @@ void os_prepare_tty_select([[maybe_unused]] select_fd_sets *fds) { #endif } -bool os_poll_selected_tty(int select_ret, select_fd_sets *fds) { +bool os_poll_selected_tty([[maybe_unused]] int select_ret, [[maybe_unused]] select_fd_sets *fds) { auto *s = get_state(); if (!s->initialized) { // We can't poll when TTY is not initialized return false; @@ -522,7 +525,7 @@ void os_putchars(const uint8_t *data, size_t len) { } } -int os_mkdir(const char *path, int mode) { +int os_mkdir([[maybe_unused]] const char *path, [[maybe_unused]] int mode) { #ifdef HAVE_MKDIR return plat_mkdir(path, mode); #else @@ -781,9 +784,11 @@ void os_sleep_us(uint64_t timeout_us) { #endif } +#ifdef HAVE_FORK static void sig_alrm(int /*unused*/) { ; } +#endif // this function forks and intermediate child, and the intermediate child forks a final child // the intermediate child simply exits immediately @@ -791,7 +796,8 @@ static void sig_alrm(int /*unused*/) { // the parent returns the final child pid // the final child returns 0 // on error, the parent throws and the final child does not return -int os_double_fork_or_throw(int newpgid) { +int os_double_fork_or_throw([[maybe_unused]] int newpgid) { +#ifdef HAVE_FORK int fd[2] = {-1, -1}; struct sigaction chld_act {}; bool restore_sigchld = false; @@ -926,9 +932,15 @@ int os_double_fork_or_throw(int newpgid) { } throw; // rethrow so caller can see why we failed } + +#else + throw std::runtime_error{"fork() is unsupported in this platform"s}; + +#endif } -int os_double_fork(int newpgid, const char **err_msg) { +int os_double_fork([[maybe_unused]] int newpgid, [[maybe_unused]] const char **err_msg) { +#ifdef HAVE_FORK static THREAD_LOCAL std::string error_storage; try { *err_msg = nullptr; @@ -938,6 +950,10 @@ int os_double_fork(int newpgid, const char **err_msg) { *err_msg = error_storage.c_str(); return -1; } +#else + throw std::runtime_error{"fork() is unsupported in this platform"s}; + +#endif } } // namespace cartesi