// Copyright 2017 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef CRASHPAD_UTIL_POSIX_SIGNALS_H_
#define CRASHPAD_UTIL_POSIX_SIGNALS_H_

#include <signal.h>

#include <set>


namespace crashpad {

//! \brief Utilities for handling POSIX signals.
class Signals {
 public:
  //! \brief A signal number used by Crashpad to simulate signals.
  static constexpr int kSimulatedSigno = -1;

  //! \brief The type used for `struct sigaction::sa_sigaction`.
  using Handler = void (*)(int, siginfo_t*, void*);

  //! \brief A group of `struct sigaction` structures corresponding to a set
  //!     of signals’ previous actions, addressable by signal number.
  //!
  //! This type is used to store previous signal actions when new actions are
  //! installed in batch by InstallCrashHandlers() or
  //! InstallTerminateHandlers().
  //!
  //! This object is not initialized by any constructor. Its expected initial
  //! state is to have its contents filled with zeroes. Because signal handlers
  //! are stateless (there is no “context” parameter), any state must be
  //! accessed via objects of static storage duration, and it is expected that
  //! objects of this class will only ever exist with static storage duration,
  //! which in the absence of a constructor will be zero-initialized as
  //! expected. In the event that an object of this class must exist with a
  //! different storage duration, such as automatic or dynamic storage duration,
  //! it must be explicitly initialized. For example: `OldActions old_actions =
  //! {};`.
  class OldActions {
   public:
    // DISALLOW_COPY_AND_ASSIGN removes the default constructor, so explicitly
    // opt for it. This should not result in any static initialization code even
    // when an object of this class is given static storage duration.
    OldActions() = default;

    OldActions(const OldActions&) = delete;
    OldActions& operator=(const OldActions&) = delete;

    //! \brief Returns a `struct sigaction` structure corresponding to the
    //!     given signal.
    //!
    //! \note This method is safe to call from a signal handler.
    struct sigaction* ActionForSignal(int sig);

   private:
    // As a small storage optimization, don’t waste any space on a slot for
    // signal 0, because there is no signal 0.
    struct sigaction actions_[NSIG - 1];
  };

  Signals() = delete;
  Signals(const Signals&) = delete;
  Signals& operator=(const Signals&) = delete;

  //! \brief Installs a new signal handler.
  //!
  //! \param[in] sig The signal number to handle.
  //! \param[in] handler A signal-handling function to execute, used as the
  //!     `struct sigaction::sa_sigaction` field when calling `sigaction()`.
  //! \param[in] flags Flags to pass to `sigaction()` in the `struct
  //!     sigaction::sa_flags` field. `SA_SIGINFO` will be specified implicitly.
  //! \param[out] old_action The previous action for the signal, replaced by the
  //!     new action. May be `nullptr` if not needed.
  //!
  //! \return `true` on success. `false` on failure with a message logged.
  //!
  //! \warning This function may not be called from a signal handler because of
  //!     its use of logging. See RestoreHandlerAndReraiseSignalOnReturn()
  //!     instead.
  static bool InstallHandler(int sig,
                             Handler handler,
                             int flags,
                             struct sigaction* old_action);

  //! \brief Installs `SIG_DFL` for the signal \a sig.
  //!
  //! \param[in] sig The signal to set the default action for.
  //!
  //! \return `true` on success, `false` on failure with errno set. No message
  //!     is logged.
  static bool InstallDefaultHandler(int sig);

  //! \brief Installs a new signal handler for all signals associated with
  //!     crashes.
  //!
  //! Signals associated with crashes are those whose default dispositions
  //! involve creating a core dump. The precise set of signals involved varies
  //! between operating systems.
  //!
  //! A single signal may either be associated with a crash or with termination
  //! (see InstallTerminateHandlers()), and perhaps neither, but never both.
  //!
  //! \param[in] handler A signal-handling function to execute, used as the
  //!     `struct sigaction::sa_sigaction` field when calling `sigaction()`.
  //! \param[in] flags Flags to pass to `sigaction()` in the `struct
  //!     sigaction::sa_flags` field. `SA_SIGINFO` will be specified implicitly.
  //! \param[out] old_actions The previous actions for the signals, replaced by
  //!     the new action. May be `nullptr` if not needed. The same \a
  //!     old_actions object may be used for calls to both this function and
  //!     InstallTerminateHandlers().
  //! \param[in] unhandled_signals Signal handlers will not be installed for
  //!     signal numbers in this set. Optional.
  //!
  //! \return `true` on success. `false` on failure with a message logged.
  //!
  //! \warning This function may not be called from a signal handler because of
  //!     its use of logging. See RestoreHandlerAndReraiseSignalOnReturn()
  //!     instead.
  static bool InstallCrashHandlers(
      Handler handler,
      int flags,
      OldActions* old_actions,
      const std::set<int>* unhandled_signals = nullptr);

  //! \brief Installs a new signal handler for all signals associated with
  //!     termination.
  //!
  //! Signals associated with termination are those whose default dispositions
  //! involve terminating the process without creating a core dump. The precise
  //! set of signals involved varies between operating systems.
  //!
  //! A single signal may either be associated with termination or with a
  //! crash (see InstalCrashHandlers()), and perhaps neither, but never both.
  //!
  //! \param[in] handler A signal-handling function to execute, used as the
  //!     `struct sigaction::sa_sigaction` field when calling `sigaction()`.
  //! \param[in] flags Flags to pass to `sigaction()` in the `struct
  //!     sigaction::sa_flags` field. `SA_SIGINFO` will be specified implicitly.
  //! \param[out] old_actions The previous actions for the signals, replaced by
  //!     the new action. May be `nullptr` if not needed. The same \a
  //!     old_actions object may be used for calls to both this function and
  //!     InstallCrashHandlers().
  //!
  //! \return `true` on success. `false` on failure with a message logged.
  //!
  //! \warning This function may not be called from a signal handler because of
  //!     its use of logging. See RestoreHandlerAndReraiseSignalOnReturn()
  //!     instead.
  static bool InstallTerminateHandlers(Handler handler,
                                       int flags,
                                       OldActions* old_actions);

  //! \brief Determines whether a signal will be re-raised autonomously upon
  //!     return from a signal handler.
  //!
  //! Certain signals, when generated synchronously in response to a hardware
  //! fault, are unrecoverable. Upon return from the signal handler, the same
  //! action that triggered the signal to be raised initially will be retried,
  //! and unless the signal handler took action to mitigate this error, the same
  //! signal will be re-raised. As an example, a CPU will not be able to read
  //! unmapped memory (causing `SIGSEGV`), thus the signal will be re-raised
  //! upon return from the signal handler unless the signal handler established
  //! a memory mapping where required.
  //!
  //! It is important to distinguish between these synchronous signals generated
  //! in response to a hardware fault and signals generated asynchronously or in
  //! software. As an example, `SIGSEGV` will not re-raise autonomously if sent
  //! by `kill()`.
  //!
  //! This function distinguishes between signals that can re-raise
  //! autonomously, and for those that can, between instances of the signal that
  //! were generated synchronously in response to a hardware fault and instances
  //! that were generated by other means.
  //!
  //! \param[in] siginfo A pointer to a `siginfo_t` object received by a signal
  //!     handler.
  //!
  //! \return `true` if the signal being handled will re-raise itself
  //!     autonomously upon return from a signal handler. `false` if it will
  //!     not. When this function returns `false`, a signal can still be
  //!     re-raised upon return from a signal handler by calling `raise()` from
  //!     within the signal handler.
  //!
  //! \note This function is safe to call from a signal handler.
  static bool WillSignalReraiseAutonomously(const siginfo_t* siginfo);

  //! \brief Restores a previous signal action and arranges to re-raise a signal
  //!     on return from a signal handler.
  //!
  //! \param[in] siginfo A pointer to a `siginfo_t` object received by a signal
  //!     handler.
  //! \param[in] old_action The previous action for the signal, which will be
  //!     re-established as the signal’s action. May be `nullptr`, which directs
  //!     the default action for the signal to be used.
  //!
  //! If this function fails, it will immediately call `_exit()` and set an exit
  //! status of `191`.
  //!
  //! \note This function may only be called from a signal handler.
  static void RestoreHandlerAndReraiseSignalOnReturn(
      const siginfo_t* siginfo,
      const struct sigaction* old_action);

  //! \brief Determines whether a signal is associated with a crash.
  //!
  //! Signals associated with crashes are those whose default dispositions
  //! involve creating a core dump. The precise set of signals involved varies
  //! between operating systems.
  //!
  //! \param[in] sig The signal to test.
  //!
  //! \return `true` if \a sig is associated with a crash. `false` otherwise.
  //!
  //! \note This function is safe to call from a signal handler.
  static bool IsCrashSignal(int sig);

  //! \brief Determines whether a signal is associated with termination.
  //!
  //! Signals associated with termination are those whose default dispositions
  //! involve terminating the process without creating a core dump. The precise
  //! set of signals involved varies between operating systems.
  //!
  //! \param[in] sig The signal to test.
  //!
  //! \return `true` if \a sig is associated with termination. `false`
  //!     otherwise.
  //!
  //! \note This function is safe to call from a signal handler.
  static bool IsTerminateSignal(int sig);
};

}  // namespace crashpad

#endif  // CRASHPAD_UTIL_POSIX_SIGNALS_H_
