mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Rework signal handling code
This commit is contained in:
parent
3b1bd58a36
commit
3d1ecc3db0
@ -169,15 +169,15 @@ nsa bool UserModeExceptionHandler(CPU::ExceptionFrame *Frame)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->Signals->SendSignal(SIGSEGV,
|
proc->Signals.SendSignal(SIGSEGV,
|
||||||
{Tasking::KILL_CRASH});
|
{Tasking::KILL_CRASH});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CPU::x86::Debug:
|
case CPU::x86::Debug:
|
||||||
case CPU::x86::Breakpoint:
|
case CPU::x86::Breakpoint:
|
||||||
{
|
{
|
||||||
proc->Signals->SendSignal(SIGTRAP,
|
proc->Signals.SendSignal(SIGTRAP,
|
||||||
{Tasking::KILL_CRASH});
|
{Tasking::KILL_CRASH});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CPU::x86::DivideByZero:
|
case CPU::x86::DivideByZero:
|
||||||
@ -186,21 +186,21 @@ nsa bool UserModeExceptionHandler(CPU::ExceptionFrame *Frame)
|
|||||||
case CPU::x86::x87FloatingPoint:
|
case CPU::x86::x87FloatingPoint:
|
||||||
case CPU::x86::SIMDFloatingPoint:
|
case CPU::x86::SIMDFloatingPoint:
|
||||||
{
|
{
|
||||||
proc->Signals->SendSignal(SIGFPE,
|
proc->Signals.SendSignal(SIGFPE,
|
||||||
{Tasking::KILL_CRASH});
|
{Tasking::KILL_CRASH});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CPU::x86::InvalidOpcode:
|
case CPU::x86::InvalidOpcode:
|
||||||
case CPU::x86::GeneralProtectionFault:
|
case CPU::x86::GeneralProtectionFault:
|
||||||
{
|
{
|
||||||
proc->Signals->SendSignal(SIGILL,
|
proc->Signals.SendSignal(SIGILL,
|
||||||
{Tasking::KILL_CRASH});
|
{Tasking::KILL_CRASH});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CPU::x86::DeviceNotAvailable:
|
case CPU::x86::DeviceNotAvailable:
|
||||||
{
|
{
|
||||||
proc->Signals->SendSignal(SIGBUS,
|
proc->Signals.SendSignal(SIGBUS,
|
||||||
{Tasking::KILL_CRASH});
|
{Tasking::KILL_CRASH});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CPU::x86::NonMaskableInterrupt:
|
case CPU::x86::NonMaskableInterrupt:
|
||||||
|
@ -18,171 +18,121 @@
|
|||||||
#ifndef __FENNIX_KERNEL_SIGNAL_H__
|
#ifndef __FENNIX_KERNEL_SIGNAL_H__
|
||||||
#define __FENNIX_KERNEL_SIGNAL_H__
|
#define __FENNIX_KERNEL_SIGNAL_H__
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <syscalls.hpp>
|
#include <syscalls.hpp>
|
||||||
#include <lock.hpp>
|
#include <lock.hpp>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
#include <bitset>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <syscall/linux/signals.hpp>
|
|
||||||
|
|
||||||
enum Signals : int
|
enum Signals : int
|
||||||
{
|
{
|
||||||
SIG_NULL = 0,
|
SIG_NULL = 0,
|
||||||
|
/* Process abort signal. */
|
||||||
/**
|
SIGABRT = 1,
|
||||||
* Process abort signal.
|
/* Alarm clock. */
|
||||||
*/
|
SIGALRM = 2,
|
||||||
SIGABRT,
|
/* Access to an undefined portion of a memory object. */
|
||||||
|
SIGBUS = 3,
|
||||||
/**
|
/* Child process terminated, stopped, or continued. */
|
||||||
* Alarm clock.
|
SIGCHLD = 4,
|
||||||
*/
|
/* Continue executing, if stopped. */
|
||||||
SIGALRM,
|
SIGCONT = 5,
|
||||||
|
/* Erroneous arithmetic operation. */
|
||||||
/**
|
SIGFPE = 6,
|
||||||
* Access to an undefined portion of a memory object.
|
/* Hangup. */
|
||||||
*/
|
SIGHUP = 7,
|
||||||
SIGBUS,
|
/* Illegal instruction. */
|
||||||
|
SIGILL = 8,
|
||||||
/**
|
/* Terminal interrupt signal. */
|
||||||
* Child process terminated, stopped, or continued.
|
SIGINT = 9,
|
||||||
*/
|
/* Kill (cannot be caught or ignored). */
|
||||||
SIGCHLD,
|
SIGKILL = 10,
|
||||||
|
/* Write on a pipe with no one to read it. */
|
||||||
/**
|
SIGPIPE = 11,
|
||||||
* Continue executing, if stopped.
|
/* Terminal quit signal. */
|
||||||
*/
|
SIGQUIT = 12,
|
||||||
SIGCONT,
|
/* Invalid memory reference. */
|
||||||
|
SIGSEGV = 13,
|
||||||
/**
|
/* Stop executing (cannot be caught or ignored). */
|
||||||
* Erroneous arithmetic operation.
|
SIGSTOP = 14,
|
||||||
*/
|
/* Termination signal. */
|
||||||
SIGFPE,
|
SIGTERM = 15,
|
||||||
|
/* Terminal stop signal. */
|
||||||
/**
|
SIGTSTP = 16,
|
||||||
* Hangup.
|
/* Background process attempting read. */
|
||||||
*/
|
SIGTTIN = 17,
|
||||||
SIGHUP,
|
/* Background process attempting write. */
|
||||||
|
SIGTTOU = 18,
|
||||||
/**
|
/* User-defined signal 1. */
|
||||||
* Illegal instruction.
|
SIGUSR1 = 19,
|
||||||
*/
|
/* User-defined signal 2. */
|
||||||
SIGILL,
|
SIGUSR2 = 20,
|
||||||
|
/* Pollable event. */
|
||||||
/**
|
SIGPOLL = 21,
|
||||||
* Terminal interrupt signal.
|
/* Profiling timer expired. */
|
||||||
*/
|
SIGPROF = 22,
|
||||||
SIGINT,
|
/* Bad system call. */
|
||||||
|
SIGSYS = 23,
|
||||||
/**
|
/* Trace/breakpoint trap. */
|
||||||
* Kill (cannot be caught or ignored).
|
SIGTRAP = 24,
|
||||||
*/
|
/* High bandwidth data is available at a socket. */
|
||||||
SIGKILL,
|
SIGURG = 25,
|
||||||
|
/* Virtual timer expired. */
|
||||||
/**
|
SIGVTALRM = 26,
|
||||||
* Write on a pipe with no one to read it.
|
/* CPU time limit exceeded. */
|
||||||
*/
|
SIGXCPU = 27,
|
||||||
SIGPIPE,
|
/* File size limit exceeded. */
|
||||||
|
SIGXFSZ = 28,
|
||||||
/**
|
|
||||||
* Terminal quit signal.
|
|
||||||
*/
|
|
||||||
SIGQUIT,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalid memory reference.
|
|
||||||
*/
|
|
||||||
SIGSEGV,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop executing (cannot be caught or ignored).
|
|
||||||
*/
|
|
||||||
SIGSTOP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Termination signal.
|
|
||||||
*/
|
|
||||||
SIGTERM,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Terminal stop signal.
|
|
||||||
*/
|
|
||||||
SIGTSTP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Background process attempting read.
|
|
||||||
*/
|
|
||||||
SIGTTIN,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Background process attempting write.
|
|
||||||
*/
|
|
||||||
SIGTTOU,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User-defined signal 1.
|
|
||||||
*/
|
|
||||||
SIGUSR1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User-defined signal 2.
|
|
||||||
*/
|
|
||||||
SIGUSR2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pollable event.
|
|
||||||
*/
|
|
||||||
SIGPOLL,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Profiling timer expired.
|
|
||||||
*/
|
|
||||||
SIGPROF,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bad system call.
|
|
||||||
*/
|
|
||||||
SIGSYS,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trace/breakpoint trap.
|
|
||||||
*/
|
|
||||||
SIGTRAP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* High bandwidth data is available at a socket.
|
|
||||||
*/
|
|
||||||
SIGURG,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Virtual timer expired.
|
|
||||||
*/
|
|
||||||
SIGVTALRM,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CPU time limit exceeded.
|
|
||||||
*/
|
|
||||||
SIGXCPU,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File size limit exceeded.
|
|
||||||
*/
|
|
||||||
SIGXFSZ,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reserved
|
* Reserved
|
||||||
*
|
|
||||||
* These are just to match Linux's signal numbers.
|
* These are just to match Linux's signal numbers.
|
||||||
*/
|
*/
|
||||||
SIGRSV1,
|
SIGCOMP1 = 29,
|
||||||
SIGRSV2,
|
SIGCOMP2 = 30,
|
||||||
|
SIGCOMP3 = 31,
|
||||||
|
|
||||||
/**
|
/* Real-time signals. */
|
||||||
* Maximum signal number.
|
SIGRTMIN = 32,
|
||||||
*/
|
SIGRT_1 = 33,
|
||||||
SIGNAL_MAX
|
SIGRT_2 = 34,
|
||||||
|
SIGRT_3 = 35,
|
||||||
|
SIGRT_4 = 36,
|
||||||
|
SIGRT_5 = 37,
|
||||||
|
SIGRT_6 = 38,
|
||||||
|
SIGRT_7 = 39,
|
||||||
|
SIGRT_8 = 40,
|
||||||
|
SIGRT_9 = 41,
|
||||||
|
SIGRT_10 = 42,
|
||||||
|
SIGRT_11 = 43,
|
||||||
|
SIGRT_12 = 44,
|
||||||
|
SIGRT_13 = 45,
|
||||||
|
SIGRT_14 = 46,
|
||||||
|
SIGRT_15 = 47,
|
||||||
|
SIGRT_16 = 48,
|
||||||
|
SIGRT_17 = 49,
|
||||||
|
SIGRT_18 = 50,
|
||||||
|
SIGRT_19 = 51,
|
||||||
|
SIGRT_20 = 52,
|
||||||
|
SIGRT_21 = 53,
|
||||||
|
SIGRT_22 = 54,
|
||||||
|
SIGRT_23 = 55,
|
||||||
|
SIGRT_24 = 56,
|
||||||
|
SIGRT_25 = 57,
|
||||||
|
SIGRT_26 = 58,
|
||||||
|
SIGRT_27 = 59,
|
||||||
|
SIGRT_28 = 60,
|
||||||
|
SIGRT_29 = 61,
|
||||||
|
SIGRT_30 = 62,
|
||||||
|
SIGRT_31 = 63,
|
||||||
|
SIGRTMAX = 64,
|
||||||
|
|
||||||
|
/* Maximum signal number. */
|
||||||
|
SIGNAL_MAX = SIGRTMAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SignalDisposition
|
enum SignalDispositions
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Terminate the process.
|
* Terminate the process.
|
||||||
@ -210,21 +160,28 @@ enum SignalDisposition
|
|||||||
SIG_CONT
|
SIG_CONT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SignalAction
|
enum SignalActions
|
||||||
{
|
{
|
||||||
SIG_BLOCK,
|
SIG_BLOCK,
|
||||||
SIG_UNBLOCK,
|
SIG_UNBLOCK,
|
||||||
SIG_SETMASK
|
SIG_SETMASK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SignalActionDisposition : long
|
||||||
|
{
|
||||||
|
SAD_ERR = -1,
|
||||||
|
SAD_DFL = 0,
|
||||||
|
SAD_IGN = 1,
|
||||||
|
};
|
||||||
|
|
||||||
#define SA_NOCLDSTOP 1
|
#define SA_NOCLDSTOP 1
|
||||||
#define SA_NOCLDWAIT 2
|
#define SA_NOCLDWAIT 2
|
||||||
#define SA_SIGINFO 4
|
#define SA_SIGINFO 4
|
||||||
|
#define SA_RESTORER 0x04000000
|
||||||
#define SA_ONSTACK 0x08000000
|
#define SA_ONSTACK 0x08000000
|
||||||
#define SA_RESTART 0x10000000
|
#define SA_RESTART 0x10000000
|
||||||
#define SA_NODEFER 0x40000000
|
#define SA_NODEFER 0x40000000
|
||||||
#define SA_RESETHAND 0x80000000
|
#define SA_RESETHAND 0x80000000
|
||||||
#define SA_RESTORER 0x04000000
|
|
||||||
|
|
||||||
#define __SI_PAD_SIZE \
|
#define __SI_PAD_SIZE \
|
||||||
(128 - 2 * sizeof(int) - sizeof(long))
|
(128 - 2 * sizeof(int) - sizeof(long))
|
||||||
@ -323,41 +280,32 @@ typedef struct
|
|||||||
} __si_fields;
|
} __si_fields;
|
||||||
} siginfo_t;
|
} siginfo_t;
|
||||||
|
|
||||||
struct sigaction
|
struct SignalAction
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
void (*sa_handler)(int);
|
void (*Handler)(int);
|
||||||
void (*sa_sigaction)(int, siginfo_t *, void *);
|
void (*Action)(int, siginfo_t *, void *);
|
||||||
} __sa_handler;
|
sigset_t Disposition;
|
||||||
sigset_t sa_mask;
|
} sa_handler;
|
||||||
int sa_flags;
|
std::bitset<64> Mask;
|
||||||
void (*sa_restorer)(void);
|
unsigned long Flags;
|
||||||
|
void (*Restorer)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Tasking
|
namespace Tasking
|
||||||
{
|
{
|
||||||
__no_sanitize("shift") inline __always_inline
|
|
||||||
sigset_t
|
|
||||||
ToFlag(sigset_t sig)
|
|
||||||
{
|
|
||||||
return 1 << (sig - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline __always_inline
|
|
||||||
sigset_t
|
|
||||||
ToSig(sigset_t flag)
|
|
||||||
{
|
|
||||||
return __builtin_ctzl(flag) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Signal
|
class Signal
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
struct SignalInfo
|
struct SignalInfo
|
||||||
{
|
{
|
||||||
int sig;
|
int sig = SIG_NULL;
|
||||||
union sigval val;
|
union sigval val
|
||||||
|
{
|
||||||
|
0
|
||||||
|
};
|
||||||
|
pid_t tid = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StackInfo
|
struct StackInfo
|
||||||
@ -388,109 +336,97 @@ namespace Tasking
|
|||||||
void *TrampAddr = nullptr;
|
void *TrampAddr = nullptr;
|
||||||
size_t TrampSz = 0;
|
size_t TrampSz = 0;
|
||||||
|
|
||||||
std::list<SignalInfo> SignalQueue;
|
std::list<SignalInfo> Queue;
|
||||||
std::atomic<sigset_t> SignalMask = 0;
|
SignalAction sa[64 + 1]{};
|
||||||
sigaction SignalAction[SIGNAL_MAX]{};
|
// std::bitset<SIGNAL_MAX> GlobalMask;
|
||||||
SignalDisposition sigDisp[SIGNAL_MAX];
|
// SignalDispositions Disposition[SIGNAL_MAX];
|
||||||
std::list<SignalInfo> Watchers;
|
std::list<SignalInfo> Watchers;
|
||||||
|
std::unordered_map<Signals, SignalDispositions> Disposition = {
|
||||||
|
{SIGHUP, SIG_TERM},
|
||||||
|
{SIGINT, SIG_TERM},
|
||||||
|
{SIGQUIT, SIG_TERM},
|
||||||
|
{SIGILL, SIG_CORE},
|
||||||
|
{SIGTRAP, SIG_CORE},
|
||||||
|
{SIGABRT, SIG_CORE},
|
||||||
|
{SIGBUS, SIG_CORE},
|
||||||
|
{SIGFPE, SIG_CORE},
|
||||||
|
{SIGKILL, SIG_TERM},
|
||||||
|
{SIGUSR1, SIG_TERM},
|
||||||
|
{SIGSEGV, SIG_CORE},
|
||||||
|
{SIGUSR2, SIG_TERM},
|
||||||
|
{SIGPIPE, SIG_TERM},
|
||||||
|
{SIGALRM, SIG_TERM},
|
||||||
|
{SIGTERM, SIG_TERM},
|
||||||
|
{SIGCOMP1, SIG_IGN},
|
||||||
|
{SIGCHLD, SIG_IGN},
|
||||||
|
{SIGCONT, SIG_CONT},
|
||||||
|
{SIGSTOP, SIG_STOP},
|
||||||
|
{SIGTSTP, SIG_STOP},
|
||||||
|
{SIGTTIN, SIG_STOP},
|
||||||
|
{SIGTTOU, SIG_STOP},
|
||||||
|
{SIGURG, SIG_IGN},
|
||||||
|
{SIGXCPU, SIG_CORE},
|
||||||
|
{SIGXFSZ, SIG_CORE},
|
||||||
|
{SIGVTALRM, SIG_TERM},
|
||||||
|
{SIGPROF, SIG_TERM},
|
||||||
|
{SIGCOMP2, SIG_IGN},
|
||||||
|
{SIGPOLL, SIG_TERM},
|
||||||
|
{SIGCOMP3, SIG_IGN},
|
||||||
|
{SIGSYS, SIG_CORE},
|
||||||
|
{SIGRTMIN, SIG_IGN},
|
||||||
|
{SIGRT_1, SIG_IGN},
|
||||||
|
{SIGRT_2, SIG_IGN},
|
||||||
|
{SIGRT_3, SIG_IGN},
|
||||||
|
{SIGRT_4, SIG_IGN},
|
||||||
|
{SIGRT_5, SIG_IGN},
|
||||||
|
{SIGRT_6, SIG_IGN},
|
||||||
|
{SIGRT_7, SIG_IGN},
|
||||||
|
{SIGRT_8, SIG_IGN},
|
||||||
|
{SIGRT_9, SIG_IGN},
|
||||||
|
{SIGRT_10, SIG_IGN},
|
||||||
|
{SIGRT_11, SIG_IGN},
|
||||||
|
{SIGRT_12, SIG_IGN},
|
||||||
|
{SIGRT_13, SIG_IGN},
|
||||||
|
{SIGRT_14, SIG_IGN},
|
||||||
|
{SIGRT_15, SIG_IGN},
|
||||||
|
{SIGRT_16, SIG_IGN},
|
||||||
|
{SIGRT_17, SIG_IGN},
|
||||||
|
{SIGRT_18, SIG_IGN},
|
||||||
|
{SIGRT_19, SIG_IGN},
|
||||||
|
{SIGRT_20, SIG_IGN},
|
||||||
|
{SIGRT_21, SIG_IGN},
|
||||||
|
{SIGRT_22, SIG_IGN},
|
||||||
|
{SIGRT_23, SIG_IGN},
|
||||||
|
{SIGRT_24, SIG_IGN},
|
||||||
|
{SIGRT_25, SIG_IGN},
|
||||||
|
{SIGRT_26, SIG_IGN},
|
||||||
|
{SIGRT_27, SIG_IGN},
|
||||||
|
{SIGRT_28, SIG_IGN},
|
||||||
|
{SIGRT_29, SIG_IGN},
|
||||||
|
{SIGRT_30, SIG_IGN},
|
||||||
|
{SIGRT_31, SIG_IGN},
|
||||||
|
{SIGRTMAX, SIG_IGN}};
|
||||||
|
|
||||||
bool LinuxSig();
|
bool LinuxSig();
|
||||||
|
int MakeExitCode(Signals sig);
|
||||||
int ConvertToLinuxIfNecessary(int sig);
|
|
||||||
int ConvertToNativeIfNecessary(int sig);
|
|
||||||
|
|
||||||
sigset_t ConvertSigsetToLinuxIfNecessary(sigset_t sig);
|
|
||||||
sigset_t ConvertSigsetToNativeIfNecessary(sigset_t sig);
|
|
||||||
|
|
||||||
int MakeExitCode(int sig);
|
|
||||||
|
|
||||||
void InitTrampoline();
|
void InitTrampoline();
|
||||||
|
SignalInfo GetAvailableSignal(void *thread);
|
||||||
const sigset_t nMasks = ToFlag(SIGKILL) |
|
|
||||||
ToFlag(SIGSTOP) |
|
|
||||||
ToFlag(SIGCONT) |
|
|
||||||
ToFlag(SIGSEGV) |
|
|
||||||
ToFlag(SIGBUS) |
|
|
||||||
ToFlag(SIGILL) |
|
|
||||||
ToFlag(SIGFPE);
|
|
||||||
|
|
||||||
const sigset_t lMasks = ToFlag(linux_SIGKILL) |
|
|
||||||
ToFlag(linux_SIGSTOP) |
|
|
||||||
ToFlag(linux_SIGCONT) |
|
|
||||||
ToFlag(linux_SIGSEGV) |
|
|
||||||
ToFlag(linux_SIGBUS) |
|
|
||||||
ToFlag(linux_SIGILL) |
|
|
||||||
ToFlag(linux_SIGFPE);
|
|
||||||
|
|
||||||
void RemoveUnmaskable(sigset_t *sig)
|
|
||||||
{
|
|
||||||
if (LinuxSig())
|
|
||||||
*sig &= ~lMasks;
|
|
||||||
else
|
|
||||||
*sig &= ~nMasks;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CanHaveHandler(sigset_t sig)
|
|
||||||
{
|
|
||||||
switch (sig)
|
|
||||||
{
|
|
||||||
case SIGKILL:
|
|
||||||
case SIGSTOP:
|
|
||||||
case SIGCONT:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void *GetContext() { return ctx; }
|
void *GetContext() { return ctx; }
|
||||||
Signals GetLastSignal() { return LastSignal; }
|
Signals GetLastSignal() { return LastSignal; }
|
||||||
|
|
||||||
int AddWatcher(Signal *who, int sig);
|
int AddWatcher(Signal *who, Signals sig);
|
||||||
int RemoveWatcher(Signal *who, int sig);
|
int RemoveWatcher(Signal *who, Signals sig);
|
||||||
|
|
||||||
int AddSignal(int sig, union sigval val);
|
int AddSignal(Signals sig, union sigval val = {0}, pid_t tid = -1);
|
||||||
int RemoveSignal(int sig);
|
int RemoveSignal(Signals sig);
|
||||||
|
|
||||||
/**
|
bool HandleSignal(CPU::TrapFrame *tf, void *thread);
|
||||||
* For scheduler use only
|
void RestoreHandleSignal(SyscallsFrame *tf, void *thread);
|
||||||
* @return True if there is a signal to handle
|
|
||||||
*/
|
|
||||||
bool HandleSignal(CPU::TrapFrame *tf);
|
|
||||||
void RestoreHandleSignal(SyscallsFrame *tf);
|
|
||||||
|
|
||||||
/**
|
int SetAction(Signals sig, const SignalAction *act);
|
||||||
* Mask a signal
|
int GetAction(Signals sig, SignalAction *act);
|
||||||
*
|
|
||||||
* @param sig The signal to set
|
|
||||||
*
|
|
||||||
* @return Old mask
|
|
||||||
*/
|
|
||||||
sigset_t Block(sigset_t sig);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unmask a signal
|
|
||||||
*
|
|
||||||
* @param sig The signal to set
|
|
||||||
*
|
|
||||||
* @return Old mask
|
|
||||||
*/
|
|
||||||
sigset_t Unblock(sigset_t sig);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the signal mask
|
|
||||||
*
|
|
||||||
* @param sig The signal to set
|
|
||||||
*
|
|
||||||
* @return Old mask
|
|
||||||
*/
|
|
||||||
sigset_t SetMask(sigset_t sig);
|
|
||||||
|
|
||||||
sigset_t GetMask() { return SignalMask.load(); }
|
|
||||||
|
|
||||||
int SetAction(int sig, const sigaction act);
|
|
||||||
int GetAction(int sig, sigaction *act);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a signal to the process
|
* Send a signal to the process
|
||||||
@ -498,39 +434,56 @@ namespace Tasking
|
|||||||
* @param sig The signal to send
|
* @param sig The signal to send
|
||||||
* (compatibility specific)
|
* (compatibility specific)
|
||||||
* @param val The value to send
|
* @param val The value to send
|
||||||
|
* @param tid The thread ID to send the signal to
|
||||||
*
|
*
|
||||||
* @return 0 on success, -errno on error
|
* @return 0 on success, -errno on error
|
||||||
*/
|
*/
|
||||||
int SendSignal(int sig, union sigval val = {0});
|
int SendSignal(Signals sig, sigval val = {0}, pid_t tid = -1);
|
||||||
|
|
||||||
int WaitAnySignal();
|
int WaitAnySignal();
|
||||||
bool HasPendingSignal();
|
bool HasPendingSignal() { return !Queue.empty(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for a signal
|
* Wait for a signal
|
||||||
*
|
*
|
||||||
* @param sig The signal to wait for
|
* @param sig The signal to wait for
|
||||||
* (compatibility specific)
|
|
||||||
* @param val The value to wait for
|
* @param val The value to wait for
|
||||||
*
|
*
|
||||||
* @return 0 on success, -errno on error
|
* @return 0 on success, -errno on error
|
||||||
*/
|
*/
|
||||||
int WaitSignal(int sig, union sigval *val);
|
int WaitSignal(Signals sig, union sigval *val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for a signal with a timeout
|
* Wait for a signal with a timeout
|
||||||
*
|
*
|
||||||
* @param sig The signal to wait for
|
* @param sig The signal to wait for
|
||||||
* (compatibility specific)
|
|
||||||
* @param val The value to wait for
|
* @param val The value to wait for
|
||||||
* @param timeout The timeout to wait for
|
* @param timeout The timeout to wait for
|
||||||
*
|
*
|
||||||
* @return 0 on success, -errno on error
|
* @return 0 on success, -errno on error
|
||||||
*/
|
*/
|
||||||
int WaitSignalTimeout(int sig, union sigval *val, uint64_t timeout);
|
int WaitSignalTimeout(Signals sig, union sigval *val, uint64_t timeout);
|
||||||
|
|
||||||
Signal(void *ctx);
|
Signal(void *ctx);
|
||||||
~Signal();
|
~Signal();
|
||||||
|
|
||||||
|
friend class ThreadSignal;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThreadSignal
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Signal &pSig;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::bitset<64> Mask = 0;
|
||||||
|
|
||||||
|
sigset_t Block(sigset_t sig);
|
||||||
|
sigset_t Unblock(sigset_t sig);
|
||||||
|
sigset_t SetMask(sigset_t sig);
|
||||||
|
sigset_t GetMask();
|
||||||
|
|
||||||
|
ThreadSignal(Signal &sig) : pSig(sig) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +170,8 @@
|
|||||||
#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
|
#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
|
||||||
#define LINUX_REBOOT_CMD_KEXEC 0x45584543
|
#define LINUX_REBOOT_CMD_KEXEC 0x45584543
|
||||||
|
|
||||||
|
#define SA_IMMUTABLE 0x00800000
|
||||||
|
|
||||||
typedef long __kernel_old_time_t;
|
typedef long __kernel_old_time_t;
|
||||||
typedef long __kernel_suseconds_t;
|
typedef long __kernel_suseconds_t;
|
||||||
typedef int clockid_t;
|
typedef int clockid_t;
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
#define linux_NSIG 64
|
||||||
|
|
||||||
#define linux_SIGHUP 1
|
#define linux_SIGHUP 1
|
||||||
#define linux_SIGINT 2
|
#define linux_SIGINT 2
|
||||||
#define linux_SIGQUIT 3
|
#define linux_SIGQUIT 3
|
||||||
@ -53,4 +55,14 @@
|
|||||||
#define linux_SIGSYS 31
|
#define linux_SIGSYS 31
|
||||||
#define linux_SIGUNUSED linux_SIGSYS
|
#define linux_SIGUNUSED linux_SIGSYS
|
||||||
|
|
||||||
|
#define linux_SIGRTMIN 32
|
||||||
|
#define linux_SIGRTMAX linux_NSIG
|
||||||
|
struct k_sigaction
|
||||||
|
{
|
||||||
|
void (*handler)(int);
|
||||||
|
unsigned long flags;
|
||||||
|
void (*restorer)(void);
|
||||||
|
unsigned mask[2];
|
||||||
|
};
|
||||||
|
|
||||||
#endif // !__FENNIX_KERNEL_LINUX_SIGNALS_H__
|
#endif // !__FENNIX_KERNEL_LINUX_SIGNALS_H__
|
||||||
|
@ -333,6 +333,9 @@ namespace Tasking
|
|||||||
Memory::VirtualMemoryArea *vma;
|
Memory::VirtualMemoryArea *vma;
|
||||||
Memory::StackGuard *Stack;
|
Memory::StackGuard *Stack;
|
||||||
|
|
||||||
|
/* Signal */
|
||||||
|
ThreadSignal Signals;
|
||||||
|
|
||||||
/* CPU state */
|
/* CPU state */
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
CPU::x64::TrapFrame Registers{};
|
CPU::x64::TrapFrame Registers{};
|
||||||
@ -361,6 +364,7 @@ namespace Tasking
|
|||||||
{
|
{
|
||||||
int *set_child_tid{};
|
int *set_child_tid{};
|
||||||
int *clear_child_tid{};
|
int *clear_child_tid{};
|
||||||
|
pid_t tgid = 0;
|
||||||
} Linux{};
|
} Linux{};
|
||||||
|
|
||||||
int SendSignal(int sig);
|
int SendSignal(int sig);
|
||||||
@ -437,6 +441,8 @@ namespace Tasking
|
|||||||
uint16_t UserID = UINT16_MAX;
|
uint16_t UserID = UINT16_MAX;
|
||||||
uint16_t GroupID = UINT16_MAX;
|
uint16_t GroupID = UINT16_MAX;
|
||||||
} Real, Effective;
|
} Real, Effective;
|
||||||
|
pid_t ProcessGroupID = 0;
|
||||||
|
pid_t SessionID = 0;
|
||||||
} Security{};
|
} Security{};
|
||||||
TaskInfo Info{};
|
TaskInfo Info{};
|
||||||
ThreadLocalStorage TLS{};
|
ThreadLocalStorage TLS{};
|
||||||
@ -457,7 +463,7 @@ namespace Tasking
|
|||||||
Memory::ProgramBreak *ProgramBreak;
|
Memory::ProgramBreak *ProgramBreak;
|
||||||
|
|
||||||
/* Other */
|
/* Other */
|
||||||
Signal *Signals;
|
Signal Signals;
|
||||||
|
|
||||||
/* Threads & Children */
|
/* Threads & Children */
|
||||||
std::list<TCB *> Threads;
|
std::list<TCB *> Threads;
|
||||||
|
@ -39,13 +39,288 @@
|
|||||||
using Tasking::PCB;
|
using Tasking::PCB;
|
||||||
using Tasking::TCB;
|
using Tasking::TCB;
|
||||||
|
|
||||||
|
static_assert(linux_SIGRTMIN == SIGRTMIN);
|
||||||
|
static_assert(linux_SIGRTMAX == SIGRTMAX);
|
||||||
|
|
||||||
struct SyscallData
|
struct SyscallData
|
||||||
{
|
{
|
||||||
const char *Name;
|
const char *Name;
|
||||||
void *Handler;
|
void *Handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
void linux_fork_return(void *tableAddr)
|
#ifdef DEBUG
|
||||||
|
const char *lSigStr[] = {
|
||||||
|
"INVALID",
|
||||||
|
"SIGHUP",
|
||||||
|
"SIGINT",
|
||||||
|
"SIGQUIT",
|
||||||
|
"SIGILL",
|
||||||
|
"SIGTRAP",
|
||||||
|
"SIGABRT",
|
||||||
|
"SIGBUS",
|
||||||
|
"SIGFPE",
|
||||||
|
"SIGKILL",
|
||||||
|
"SIGUSR1",
|
||||||
|
"SIGSEGV",
|
||||||
|
"SIGUSR2",
|
||||||
|
"SIGPIPE",
|
||||||
|
"SIGALRM",
|
||||||
|
"SIGTERM",
|
||||||
|
"SIGSTKFLT",
|
||||||
|
"SIGCHLD",
|
||||||
|
"SIGCONT",
|
||||||
|
"SIGSTOP",
|
||||||
|
"SIGTSTP",
|
||||||
|
"SIGTTIN",
|
||||||
|
"SIGTTOU",
|
||||||
|
"SIGURG",
|
||||||
|
"SIGXCPU",
|
||||||
|
"SIGXFSZ",
|
||||||
|
"SIGVTALRM",
|
||||||
|
"SIGPROF",
|
||||||
|
"SIGWINCH",
|
||||||
|
"SIGPOLL",
|
||||||
|
"SIGPWR",
|
||||||
|
"SIGSYS",
|
||||||
|
"SIGRTMIN",
|
||||||
|
"SIGRT_1",
|
||||||
|
"SIGRT_2",
|
||||||
|
"SIGRT_3",
|
||||||
|
"SIGRT_4",
|
||||||
|
"SIGRT_5",
|
||||||
|
"SIGRT_6",
|
||||||
|
"SIGRT_7",
|
||||||
|
"SIGRT_8",
|
||||||
|
"SIGRT_9",
|
||||||
|
"SIGRT_10",
|
||||||
|
"SIGRT_11",
|
||||||
|
"SIGRT_12",
|
||||||
|
"SIGRT_13",
|
||||||
|
"SIGRT_14",
|
||||||
|
"SIGRT_15",
|
||||||
|
"SIGRT_16",
|
||||||
|
"SIGRT_17",
|
||||||
|
"SIGRT_18",
|
||||||
|
"SIGRT_19",
|
||||||
|
"SIGRT_20",
|
||||||
|
"SIGRT_21",
|
||||||
|
"SIGRT_22",
|
||||||
|
"SIGRT_23",
|
||||||
|
"SIGRT_24",
|
||||||
|
"SIGRT_25",
|
||||||
|
"SIGRT_26",
|
||||||
|
"SIGRT_27",
|
||||||
|
"SIGRT_28",
|
||||||
|
"SIGRT_29",
|
||||||
|
"SIGRT_30",
|
||||||
|
"SIGRT_31",
|
||||||
|
"SIGRTMAX",
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *rlimitStr[] = {
|
||||||
|
"RLIMIT_CPU",
|
||||||
|
"RLIMIT_FSIZE",
|
||||||
|
"RLIMIT_DATA",
|
||||||
|
"RLIMIT_STACK",
|
||||||
|
"RLIMIT_CORE",
|
||||||
|
"RLIMIT_RSS",
|
||||||
|
"RLIMIT_NPROC",
|
||||||
|
"RLIMIT_NOFILE",
|
||||||
|
"RLIMIT_MEMLOCK",
|
||||||
|
"RLIMIT_AS",
|
||||||
|
"RLIMIT_LOCKS",
|
||||||
|
"RLIMIT_SIGPENDING",
|
||||||
|
"RLIMIT_MSGQUEUE",
|
||||||
|
"RLIMIT_NICE",
|
||||||
|
"RLIMIT_RTPRIO",
|
||||||
|
"RLIMIT_RTTIME",
|
||||||
|
"RLIMIT_NLIMITS",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
int linuxSignal;
|
||||||
|
Signals nativeSignal;
|
||||||
|
SignalDispositions nativeDisposition;
|
||||||
|
} signalMapping[] = {
|
||||||
|
{linux_SIGHUP, SIGHUP, SIG_TERM},
|
||||||
|
{linux_SIGINT, SIGINT, SIG_TERM},
|
||||||
|
{linux_SIGQUIT, SIGQUIT, SIG_TERM},
|
||||||
|
{linux_SIGILL, SIGILL, SIG_CORE},
|
||||||
|
{linux_SIGTRAP, SIGTRAP, SIG_CORE},
|
||||||
|
{linux_SIGABRT, SIGABRT, SIG_CORE},
|
||||||
|
{linux_SIGBUS, SIGBUS, SIG_CORE},
|
||||||
|
{linux_SIGFPE, SIGFPE, SIG_CORE},
|
||||||
|
{linux_SIGKILL, SIGKILL, SIG_TERM},
|
||||||
|
{linux_SIGUSR1, SIGUSR1, SIG_TERM},
|
||||||
|
{linux_SIGSEGV, SIGSEGV, SIG_CORE},
|
||||||
|
{linux_SIGUSR2, SIGUSR2, SIG_TERM},
|
||||||
|
{linux_SIGPIPE, SIGPIPE, SIG_TERM},
|
||||||
|
{linux_SIGALRM, SIGALRM, SIG_TERM},
|
||||||
|
{linux_SIGTERM, SIGTERM, SIG_TERM},
|
||||||
|
{linux_SIGSTKFLT, SIGCOMP1, SIG_IGN},
|
||||||
|
{linux_SIGCHLD, SIGCHLD, SIG_IGN},
|
||||||
|
{linux_SIGCONT, SIGCONT, SIG_CONT},
|
||||||
|
{linux_SIGSTOP, SIGSTOP, SIG_STOP},
|
||||||
|
{linux_SIGTSTP, SIGTSTP, SIG_STOP},
|
||||||
|
{linux_SIGTTIN, SIGTTIN, SIG_STOP},
|
||||||
|
{linux_SIGTTOU, SIGTTOU, SIG_STOP},
|
||||||
|
{linux_SIGURG, SIGURG, SIG_IGN},
|
||||||
|
{linux_SIGXCPU, SIGXCPU, SIG_CORE},
|
||||||
|
{linux_SIGXFSZ, SIGXFSZ, SIG_CORE},
|
||||||
|
{linux_SIGVTALRM, SIGVTALRM, SIG_TERM},
|
||||||
|
{linux_SIGPROF, SIGPROF, SIG_TERM},
|
||||||
|
{linux_SIGWINCH, SIGCOMP2, SIG_IGN},
|
||||||
|
{linux_SIGPOLL, SIGPOLL, SIG_TERM},
|
||||||
|
{linux_SIGPWR, SIGCOMP3, SIG_IGN},
|
||||||
|
{linux_SIGSYS, SIGSYS, SIG_CORE},
|
||||||
|
{linux_SIGRTMIN, SIGRTMIN, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 1, SIGRT_1, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 2, SIGRT_2, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 3, SIGRT_3, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 4, SIGRT_4, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 5, SIGRT_5, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 6, SIGRT_6, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 7, SIGRT_7, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 8, SIGRT_8, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 9, SIGRT_9, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 10, SIGRT_10, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 11, SIGRT_11, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 12, SIGRT_12, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 13, SIGRT_13, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 14, SIGRT_14, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 15, SIGRT_15, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 16, SIGRT_16, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 17, SIGRT_17, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 18, SIGRT_18, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 19, SIGRT_19, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 20, SIGRT_20, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 21, SIGRT_21, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 22, SIGRT_22, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 23, SIGRT_23, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 24, SIGRT_24, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 25, SIGRT_25, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 26, SIGRT_26, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 27, SIGRT_27, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 28, SIGRT_28, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 29, SIGRT_29, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 30, SIGRT_30, SIG_IGN},
|
||||||
|
{linux_SIGRTMIN + 31, SIGRT_31, SIG_IGN},
|
||||||
|
{linux_SIGRTMAX, SIGRTMAX, SIG_IGN}};
|
||||||
|
|
||||||
|
int ConvertSignalToLinux(Signals sig)
|
||||||
|
{
|
||||||
|
if (sig >= SIGRTMIN && sig <= SIGRTMAX)
|
||||||
|
return sig; /* We ignore for now */
|
||||||
|
|
||||||
|
foreach (auto &mapping in signalMapping)
|
||||||
|
{
|
||||||
|
if (mapping.nativeSignal == sig)
|
||||||
|
{
|
||||||
|
// debug("Converted \"%s\"(%d) to \"%s\"(%d)",
|
||||||
|
// sigStr[mapping.nativeSignal], sig,
|
||||||
|
// lSigStr[mapping.linuxSignal], mapping.linuxSignal);
|
||||||
|
return mapping.linuxSignal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug("Unknown signal %d", sig);
|
||||||
|
// assert(!"Unknown signal");
|
||||||
|
return SIG_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Signals ConvertSignalToNative(int sig)
|
||||||
|
{
|
||||||
|
if (sig >= linux_SIGRTMIN && sig <= linux_SIGRTMAX)
|
||||||
|
return (Signals)sig; /* We ignore for now */
|
||||||
|
|
||||||
|
foreach (auto &mapping in signalMapping)
|
||||||
|
{
|
||||||
|
if (mapping.linuxSignal == sig)
|
||||||
|
{
|
||||||
|
// debug("Converted \"%s\"(%d) to \"%s\"(%d)",
|
||||||
|
// lSigStr[mapping.linuxSignal], sig,
|
||||||
|
// sigStr[mapping.nativeSignal], mapping.nativeSignal);
|
||||||
|
return mapping.nativeSignal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug("Unknown signal %d", sig);
|
||||||
|
// assert(!"Unknown signal");
|
||||||
|
return SIG_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ConvertMaskToNative(unsigned long mask)
|
||||||
|
{
|
||||||
|
unsigned long ret = 0;
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (mask & (1ul << i))
|
||||||
|
{
|
||||||
|
int sig = ConvertSignalToNative(i + 1);
|
||||||
|
if (unlikely(sig == SIG_NULL))
|
||||||
|
continue;
|
||||||
|
ret |= 1ul << (sig - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
// std::bitset<SIGNAL_MAX + 1> bitMask(mask);
|
||||||
|
// for (int i = 0; i < SIGNAL_MAX + 1; i++)
|
||||||
|
// {
|
||||||
|
// if (bitMask.test(i))
|
||||||
|
// ret |= 1 << (ConvertSignalToNative(i + 1) - 1);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ConvertMaskToLinux(unsigned long mask)
|
||||||
|
{
|
||||||
|
unsigned long ret = 0;
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (mask & (1ul << i))
|
||||||
|
{
|
||||||
|
int sig = ConvertSignalToLinux((Signals)(i + 1));
|
||||||
|
if (unlikely(sig == SIG_NULL))
|
||||||
|
continue;
|
||||||
|
ret |= 1ul << (sig - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
// std::bitset<linux_SIGUNUSED + 1> bitMask(mask);
|
||||||
|
// for (int i = 0; i < linux_SIGUNUSED + 1; i++)
|
||||||
|
// {
|
||||||
|
// if (bitMask.test(i))
|
||||||
|
// ret |= 1 << (ConvertSignalToLinux(i + 1) - 1);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSigActToNative(const k_sigaction *linux, SignalAction *native)
|
||||||
|
{
|
||||||
|
native->sa_handler.Handler = linux->handler;
|
||||||
|
native->Flags = linux->flags;
|
||||||
|
native->Restorer = linux->restorer;
|
||||||
|
|
||||||
|
unsigned long mask = ((unsigned long)linux->mask[1] << 32) | linux->mask[0];
|
||||||
|
native->Mask = std::bitset<64>(ConvertMaskToNative(mask));
|
||||||
|
debug("m0:%#lx m1:%#lx | n:%#lx", linux->mask[0], linux->mask[1], native->Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSigActToLinux(const SignalAction *native, k_sigaction *linux)
|
||||||
|
{
|
||||||
|
linux->handler = native->sa_handler.Handler;
|
||||||
|
linux->flags = native->Flags;
|
||||||
|
linux->restorer = native->Restorer;
|
||||||
|
|
||||||
|
unsigned long mask = native->Mask.to_ulong();
|
||||||
|
mask = ConvertMaskToLinux(mask);
|
||||||
|
|
||||||
|
linux->mask[0] = mask & 0xFFFFFFFF;
|
||||||
|
linux->mask[1] = (mask >> 32) & 0xFFFFFFFF;
|
||||||
|
debug("m0:%#lx m1:%#lx | n:%#lx", linux->mask[0], linux->mask[1], native->Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __LinuxForkReturn(void *tableAddr)
|
||||||
{
|
{
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
asmv("movq %0, %%cr3" ::"r"(tableAddr)); /* Load process page table */
|
asmv("movq %0, %%cr3" ::"r"(tableAddr)); /* Load process page table */
|
||||||
@ -56,7 +331,7 @@ void linux_fork_return(void *tableAddr)
|
|||||||
asmv("sti\n"); /* Enable interrupts */
|
asmv("sti\n"); /* Enable interrupts */
|
||||||
asmv("sysretq\n"); /* Return to rcx address in user mode */
|
asmv("sysretq\n"); /* Return to rcx address in user mode */
|
||||||
#elif defined(a32)
|
#elif defined(a32)
|
||||||
#warning "linux_fork_return not implemented for i386"
|
#warning "__LinuxForkReturn not implemented for i386"
|
||||||
#endif
|
#endif
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
@ -648,7 +923,7 @@ static int linux_dup2(SysFrm *, int oldfd, int newfd)
|
|||||||
static int linux_pause(SysFrm *)
|
static int linux_pause(SysFrm *)
|
||||||
{
|
{
|
||||||
PCB *pcb = thisProcess;
|
PCB *pcb = thisProcess;
|
||||||
return pcb->Signals->WaitAnySignal();
|
return pcb->Signals.WaitAnySignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://man7.org/linux/man-pages/man2/nanosleep.2.html */
|
/* https://man7.org/linux/man-pages/man2/nanosleep.2.html */
|
||||||
@ -690,7 +965,7 @@ static int linux_nanosleep(SysFrm *,
|
|||||||
|
|
||||||
while (time < sleepTime)
|
while (time < sleepTime)
|
||||||
{
|
{
|
||||||
if (pcb->Signals->HasPendingSignal())
|
if (pcb->Signals.HasPendingSignal())
|
||||||
{
|
{
|
||||||
debug("sleep interrupted by signal");
|
debug("sleep interrupted by signal");
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
@ -739,6 +1014,9 @@ static pid_t linux_fork(SysFrm *sf)
|
|||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NewProcess->Security.ProcessGroupID = Parent->Security.ProcessGroupID;
|
||||||
|
NewProcess->Security.SessionID = Parent->Security.SessionID;
|
||||||
|
|
||||||
NewProcess->PageTable = Parent->PageTable->Fork();
|
NewProcess->PageTable = Parent->PageTable->Fork();
|
||||||
NewProcess->vma->Table = NewProcess->PageTable;
|
NewProcess->vma->Table = NewProcess->PageTable;
|
||||||
NewProcess->vma->Fork(Parent->vma);
|
NewProcess->vma->Fork(Parent->vma);
|
||||||
@ -773,7 +1051,7 @@ static pid_t linux_fork(SysFrm *sf)
|
|||||||
NewThread->Security.IsCritical = Thread->Security.IsCritical;
|
NewThread->Security.IsCritical = Thread->Security.IsCritical;
|
||||||
NewThread->Registers = Thread->Registers;
|
NewThread->Registers = Thread->Registers;
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
NewThread->Registers.rip = (uintptr_t)linux_fork_return;
|
NewThread->Registers.rip = (uintptr_t)__LinuxForkReturn;
|
||||||
/* For sysretq */
|
/* For sysretq */
|
||||||
NewThread->Registers.rdi = (uintptr_t)NewProcess->PageTable;
|
NewThread->Registers.rdi = (uintptr_t)NewProcess->PageTable;
|
||||||
NewThread->Registers.rcx = sf->ReturnAddress;
|
NewThread->Registers.rcx = sf->ReturnAddress;
|
||||||
@ -789,7 +1067,7 @@ static pid_t linux_fork(SysFrm *sf)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug("ret addr: %#lx, stack: %#lx ip: %#lx", sf->ReturnAddress,
|
debug("ret addr: %#lx, stack: %#lx ip: %#lx", sf->ReturnAddress,
|
||||||
sf->StackPointer, (uintptr_t)linux_fork_return);
|
sf->StackPointer, (uintptr_t)__LinuxForkReturn);
|
||||||
debug("Forked thread \"%s\"(%d) to \"%s\"(%d)",
|
debug("Forked thread \"%s\"(%d) to \"%s\"(%d)",
|
||||||
Thread->Name, Thread->ID,
|
Thread->Name, Thread->ID,
|
||||||
NewThread->Name, NewThread->ID);
|
NewThread->Name, NewThread->ID);
|
||||||
@ -1077,7 +1355,9 @@ static pid_t linux_wait4(SysFrm *, pid_t pid, int *wstatus,
|
|||||||
int ExitStatus = child->ExitCode.load();
|
int ExitStatus = child->ExitCode.load();
|
||||||
bool ProcessSignaled = true;
|
bool ProcessSignaled = true;
|
||||||
bool CoreDumped = true;
|
bool CoreDumped = true;
|
||||||
int TermSignal = child->Signals->GetLastSignal();
|
int TermSignal = child->Signals.GetLastSignal();
|
||||||
|
TermSignal = ConvertSignalToLinux((Signals)TermSignal);
|
||||||
|
assert(TermSignal != SIG_NULL);
|
||||||
|
|
||||||
debug("Process returned %d", ExitStatus);
|
debug("Process returned %d", ExitStatus);
|
||||||
|
|
||||||
@ -1234,8 +1514,8 @@ static pid_t linux_wait4(SysFrm *, pid_t pid, int *wstatus,
|
|||||||
/* https://man7.org/linux/man-pages/man2/kill.2.html */
|
/* https://man7.org/linux/man-pages/man2/kill.2.html */
|
||||||
static int linux_kill(SysFrm *, pid_t pid, int sig)
|
static int linux_kill(SysFrm *, pid_t pid, int sig)
|
||||||
{
|
{
|
||||||
PCB *target = thisProcess->GetContext()->GetProcessByID(pid);
|
PCB *pcb = thisProcess->GetContext()->GetProcessByID(pid);
|
||||||
if (!target)
|
if (!pcb)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
/* TODO: Check permissions */
|
/* TODO: Check permissions */
|
||||||
@ -1245,8 +1525,21 @@ static int linux_kill(SysFrm *, pid_t pid, int sig)
|
|||||||
|
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
fixme("Sending signal %d to all processes", sig);
|
bool found = false;
|
||||||
return -ENOSYS;
|
Signals nSig = ConvertSignalToNative(sig);
|
||||||
|
assert(nSig != SIG_NULL);
|
||||||
|
foreach (auto proc in pcb->GetContext()->GetProcessList())
|
||||||
|
{
|
||||||
|
if (proc->Security.ProcessGroupID == thisProcess->Security.ProcessGroupID)
|
||||||
|
{
|
||||||
|
debug("Sending signal %s to %s(%d)", lSigStr[sig], proc->Name, proc->ID);
|
||||||
|
proc->SendSignal(nSig);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return -ESRCH;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
@ -1261,7 +1554,9 @@ static int linux_kill(SysFrm *, pid_t pid, int sig)
|
|||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return target->Signals->SendSignal(sig);
|
Signals nSig = ConvertSignalToNative(sig);
|
||||||
|
assert(nSig != SIG_NULL);
|
||||||
|
return pcb->SendSignal(nSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://man7.org/linux/man-pages/man2/uname.2.html */
|
/* https://man7.org/linux/man-pages/man2/uname.2.html */
|
||||||
@ -1510,17 +1805,13 @@ static pid_t linux_getpgid(SysFrm *, pid_t pid)
|
|||||||
{
|
{
|
||||||
PCB *pcb = thisProcess;
|
PCB *pcb = thisProcess;
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
return pcb->Security.ProcessGroupID;
|
||||||
fixme("pid=0 is stub!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PCB *target = pcb->GetContext()->GetProcessByID(pid);
|
PCB *target = pcb->GetContext()->GetProcessByID(pid);
|
||||||
if (!target)
|
if (!target)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
stub;
|
return target->Security.ProcessGroupID;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://man7.org/linux/man-pages/man2/setpgid.2.html */
|
/* https://man7.org/linux/man-pages/man2/setpgid.2.html */
|
||||||
@ -1529,7 +1820,7 @@ static int linux_setpgid(SysFrm *, pid_t pid, pid_t pgid)
|
|||||||
PCB *pcb = thisProcess;
|
PCB *pcb = thisProcess;
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
fixme("pid=0 is stub!");
|
pcb->Security.ProcessGroupID = pgid;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1537,10 +1828,13 @@ static int linux_setpgid(SysFrm *, pid_t pid, pid_t pgid)
|
|||||||
if (!target)
|
if (!target)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
if (pgid < 0)
|
if (pgid == 0)
|
||||||
return -EINVAL;
|
{
|
||||||
|
target->Security.ProcessGroupID = target->ID;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fixme("setpgid(%d, %d) is stub!", pid, pgid);
|
target->Security.ProcessGroupID = pgid;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1702,16 +1996,22 @@ static int linux_reboot(SysFrm *, int magic, int magic2, int cmd, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* https://man7.org/linux/man-pages/man2/sigaction.2.html */
|
/* https://man7.org/linux/man-pages/man2/sigaction.2.html */
|
||||||
static int linux_sigaction(SysFrm *, int signum,
|
static int linux_sigaction(SysFrm *, int signum, const k_sigaction *act,
|
||||||
const struct sigaction *act,
|
k_sigaction *oldact, size_t sigsetsize)
|
||||||
struct sigaction *oldact)
|
|
||||||
{
|
{
|
||||||
if (signum == linux_SIGKILL || signum == linux_SIGSTOP)
|
if (signum < 1 || signum > linux_SIGRTMAX ||
|
||||||
|
signum == linux_SIGKILL || signum == linux_SIGSTOP)
|
||||||
{
|
{
|
||||||
debug("Invalid signal %d", signum);
|
debug("Invalid signal %d", signum);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sigsetsize != sizeof(sigset_t))
|
||||||
|
{
|
||||||
|
warn("Unsupported sigsetsize %d!", sigsetsize);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
PCB *pcb = thisProcess;
|
PCB *pcb = thisProcess;
|
||||||
Memory::VirtualMemoryArea *vma = pcb->vma;
|
Memory::VirtualMemoryArea *vma = pcb->vma;
|
||||||
|
|
||||||
@ -1727,13 +2027,35 @@ static int linux_sigaction(SysFrm *, int signum,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (pOldact)
|
if (pOldact)
|
||||||
ret = pcb->Signals->GetAction(signum, pOldact);
|
{
|
||||||
|
Signals nSig = ConvertSignalToNative(signum);
|
||||||
|
assert(nSig != SIG_NULL);
|
||||||
|
|
||||||
|
SignalAction nSA{};
|
||||||
|
SetSigActToNative(pOldact, &nSA);
|
||||||
|
ret = pcb->Signals.GetAction(nSig, &nSA);
|
||||||
|
SetSigActToLinux(&nSA, pOldact);
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(ret < 0))
|
if (unlikely(ret < 0))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (pAct)
|
if (pAct)
|
||||||
ret = pcb->Signals->SetAction(signum, *pAct);
|
{
|
||||||
|
if (pAct->flags & SA_IMMUTABLE)
|
||||||
|
{
|
||||||
|
warn("Immutable signal %d", signum);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Signals nSig = ConvertSignalToNative(signum);
|
||||||
|
assert(nSig != SIG_NULL);
|
||||||
|
|
||||||
|
SignalAction nSA{};
|
||||||
|
SetSigActToNative(pAct, &nSA);
|
||||||
|
ret = pcb->Signals.SetAction(nSig, &nSA);
|
||||||
|
SetSigActToLinux(&nSA, (k_sigaction *)pAct);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1750,7 +2072,8 @@ static int linux_sigprocmask(SysFrm *, int how, const sigset_t *set,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCB *pcb = thisProcess;
|
TCB *tcb = thisThread;
|
||||||
|
PCB *pcb = tcb->Parent;
|
||||||
Memory::VirtualMemoryArea *vma = pcb->vma;
|
Memory::VirtualMemoryArea *vma = pcb->vma;
|
||||||
|
|
||||||
if (vma->UserCheck(set) < 0 && set != nullptr)
|
if (vma->UserCheck(set) < 0 && set != nullptr)
|
||||||
@ -1765,21 +2088,25 @@ static int linux_sigprocmask(SysFrm *, int how, const sigset_t *set,
|
|||||||
how, pSet ? *pSet : 0, pOldset ? *pOldset : 0);
|
how, pSet ? *pSet : 0, pOldset ? *pOldset : 0);
|
||||||
|
|
||||||
if (pOldset)
|
if (pOldset)
|
||||||
*pOldset = pcb->Signals->GetMask();
|
{
|
||||||
|
*pOldset = tcb->Signals.GetMask();
|
||||||
|
*pOldset = ConvertMaskToLinux(*pOldset);
|
||||||
|
}
|
||||||
|
|
||||||
if (!pSet)
|
if (!pSet)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
sigset_t nativeSet = ConvertMaskToNative(*pSet);
|
||||||
switch (how)
|
switch (how)
|
||||||
{
|
{
|
||||||
case SIG_BLOCK:
|
case SIG_BLOCK:
|
||||||
pcb->Signals->Block(*pSet);
|
tcb->Signals.Block(nativeSet);
|
||||||
break;
|
break;
|
||||||
case SIG_UNBLOCK:
|
case SIG_UNBLOCK:
|
||||||
pcb->Signals->Unblock(*pSet);
|
tcb->Signals.Unblock(nativeSet);
|
||||||
break;
|
break;
|
||||||
case SIG_SETMASK:
|
case SIG_SETMASK:
|
||||||
pcb->Signals->SetMask(*pSet);
|
tcb->Signals.SetMask(nativeSet);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warn("Invalid how %#x", how);
|
warn("Invalid how %#x", how);
|
||||||
@ -1791,7 +2118,7 @@ static int linux_sigprocmask(SysFrm *, int how, const sigset_t *set,
|
|||||||
/* https://man7.org/linux/man-pages/man2/sigreturn.2.html */
|
/* https://man7.org/linux/man-pages/man2/sigreturn.2.html */
|
||||||
static void linux_sigreturn(SysFrm *sf)
|
static void linux_sigreturn(SysFrm *sf)
|
||||||
{
|
{
|
||||||
thisProcess->Signals->RestoreHandleSignal(sf);
|
thisProcess->Signals.RestoreHandleSignal(sf, thisThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://man7.org/linux/man-pages/man2/gettid.2.html */
|
/* https://man7.org/linux/man-pages/man2/gettid.2.html */
|
||||||
@ -1803,14 +2130,13 @@ static pid_t linux_gettid(SysFrm *)
|
|||||||
/* https://man7.org/linux/man-pages/man2/tkill.2.html */
|
/* https://man7.org/linux/man-pages/man2/tkill.2.html */
|
||||||
static int linux_tkill(SysFrm *, int tid, int sig)
|
static int linux_tkill(SysFrm *, int tid, int sig)
|
||||||
{
|
{
|
||||||
Tasking::PCB *pcb = thisProcess;
|
Tasking::TCB *tcb = thisProcess->GetThread(tid);
|
||||||
Tasking::TCB *tcb = pcb->GetThread(tid);
|
|
||||||
if (!tcb)
|
if (!tcb)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
Signals nSig = ConvertSignalToNative(sig);
|
Signals nSig = ConvertSignalToNative(sig);
|
||||||
assert(nSig != SIG_NULL);
|
assert(nSig != SIG_NULL);
|
||||||
return pcb->Signals.SendSignal(nSig);
|
return tcb->SendSignal(nSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://man7.org/linux/man-pages/man2/set_tid_address.2.html */
|
/* https://man7.org/linux/man-pages/man2/set_tid_address.2.html */
|
||||||
@ -1919,6 +2245,7 @@ static int linux_clock_gettime(SysFrm *, clockid_t clockid, struct timespec *tp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html */
|
||||||
static int linux_clock_nanosleep(SysFrm *, clockid_t clockid, int flags,
|
static int linux_clock_nanosleep(SysFrm *, clockid_t clockid, int flags,
|
||||||
const struct timespec *request,
|
const struct timespec *request,
|
||||||
struct timespec *remain)
|
struct timespec *remain)
|
||||||
@ -1981,12 +2308,29 @@ static __noreturn void linux_exit_group(SysFrm *sf, int status)
|
|||||||
/* https://man7.org/linux/man-pages/man2/tgkill.2.html */
|
/* https://man7.org/linux/man-pages/man2/tgkill.2.html */
|
||||||
static int linux_tgkill(SysFrm *sf, pid_t tgid, pid_t tid, int sig)
|
static int linux_tgkill(SysFrm *sf, pid_t tgid, pid_t tid, int sig)
|
||||||
{
|
{
|
||||||
Tasking::TCB *target = thisProcess->GetContext()->GetThreadByID(tid, thisProcess);
|
Tasking::TCB *tcb = thisProcess->GetThread(tid);
|
||||||
if (!target)
|
if (!tcb || tcb->Linux.tgid != tgid)
|
||||||
return -ESRCH;
|
{
|
||||||
|
debug("Invalid tgid %d tid %d", tgid, tid);
|
||||||
|
|
||||||
fixme("semi-stub: %d %d %d", tgid, tid, sig);
|
tcb = nullptr;
|
||||||
return target->Parent->Signals->SendSignal(sig);
|
foreach (auto t in thisProcess->Threads)
|
||||||
|
{
|
||||||
|
if (t->Linux.tgid == tgid)
|
||||||
|
{
|
||||||
|
debug("Found tgid %d tid %d", tgid, t->ID);
|
||||||
|
tcb = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tcb)
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
Signals nSig = ConvertSignalToNative(sig);
|
||||||
|
assert(nSig != SIG_NULL);
|
||||||
|
return tcb->SendSignal(nSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://man7.org/linux/man-pages/man2/open.2.html */
|
/* https://man7.org/linux/man-pages/man2/open.2.html */
|
||||||
@ -2098,36 +2442,20 @@ static int linux_prlimit64(SysFrm *, pid_t pid, int resource,
|
|||||||
UNUSED(pNewLimit);
|
UNUSED(pNewLimit);
|
||||||
|
|
||||||
if (new_limit)
|
if (new_limit)
|
||||||
debug("new limit: rlim_cur:%ld rlim_max:%ld", pNewLimit->rlim_cur, pNewLimit->rlim_max);
|
debug("new limit: rlim_cur:%#lx rlim_max:%#lx", pNewLimit->rlim_cur, pNewLimit->rlim_max);
|
||||||
if (old_limit)
|
if (old_limit)
|
||||||
debug("old limit: rlim_cur:%ld rlim_max:%ld", pOldLimit->rlim_cur, pOldLimit->rlim_max);
|
debug("old limit: rlim_cur:%#lx rlim_max:%#lx", pOldLimit->rlim_cur, pOldLimit->rlim_max);
|
||||||
|
|
||||||
switch (resource)
|
switch (resource)
|
||||||
{
|
{
|
||||||
case RLIMIT_NOFILE:
|
|
||||||
{
|
|
||||||
fixme("Setting RLIMIT_NOFILE is stub");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case RLIMIT_STACK:
|
|
||||||
{
|
|
||||||
fixme("Setting RLIMIT_STACK is stub");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case RLIMIT_NPROC:
|
|
||||||
{
|
|
||||||
fixme("Setting RLIMIT_NPROC is stub");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case RLIMIT_FSIZE:
|
|
||||||
{
|
|
||||||
fixme("Setting RLIMIT_FSIZE is stub");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case RLIMIT_CPU:
|
case RLIMIT_CPU:
|
||||||
|
case RLIMIT_FSIZE:
|
||||||
case RLIMIT_DATA:
|
case RLIMIT_DATA:
|
||||||
|
case RLIMIT_STACK:
|
||||||
case RLIMIT_CORE:
|
case RLIMIT_CORE:
|
||||||
case RLIMIT_RSS:
|
case RLIMIT_RSS:
|
||||||
|
case RLIMIT_NPROC:
|
||||||
|
case RLIMIT_NOFILE:
|
||||||
case RLIMIT_MEMLOCK:
|
case RLIMIT_MEMLOCK:
|
||||||
case RLIMIT_AS:
|
case RLIMIT_AS:
|
||||||
case RLIMIT_LOCKS:
|
case RLIMIT_LOCKS:
|
||||||
@ -2138,8 +2466,8 @@ static int linux_prlimit64(SysFrm *, pid_t pid, int resource,
|
|||||||
case RLIMIT_RTTIME:
|
case RLIMIT_RTTIME:
|
||||||
case RLIMIT_NLIMITS:
|
case RLIMIT_NLIMITS:
|
||||||
{
|
{
|
||||||
fixme("resource %d is stub", resource);
|
fixme("resource %s(%d) is stub", rlimitStr[resource], resource);
|
||||||
return -ENOSYS;
|
return 0; /* just return 0 */
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <task.hpp>
|
#include <task.hpp>
|
||||||
|
|
||||||
#include <dumper.hpp>
|
#include <dumper.hpp>
|
||||||
|
#include <signal.hpp>
|
||||||
#include <convert.h>
|
#include <convert.h>
|
||||||
#include <lock.hpp>
|
#include <lock.hpp>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
@ -58,7 +59,7 @@ namespace Tasking
|
|||||||
|
|
||||||
int PCB::SendSignal(int sig)
|
int PCB::SendSignal(int sig)
|
||||||
{
|
{
|
||||||
return this->Signals->SendSignal(sig);
|
return this->Signals.SendSignal((enum Signals)sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCB::SetState(TaskState state)
|
void PCB::SetState(TaskState state)
|
||||||
@ -138,7 +139,8 @@ namespace Tasking
|
|||||||
TaskExecutionMode ExecutionMode,
|
TaskExecutionMode ExecutionMode,
|
||||||
bool UseKernelPageTable,
|
bool UseKernelPageTable,
|
||||||
uint16_t UserID, uint16_t GroupID)
|
uint16_t UserID, uint16_t GroupID)
|
||||||
: Node(ProcFS, std::to_string(ctx->NextPID), NodeType::DIRECTORY)
|
: Node(ProcFS, std::to_string(ctx->NextPID), NodeType::DIRECTORY),
|
||||||
|
Signals(this)
|
||||||
{
|
{
|
||||||
debug("+ %#lx", this);
|
debug("+ %#lx", this);
|
||||||
|
|
||||||
@ -214,7 +216,6 @@ namespace Tasking
|
|||||||
|
|
||||||
this->vma = new Memory::VirtualMemoryArea(this->PageTable);
|
this->vma = new Memory::VirtualMemoryArea(this->PageTable);
|
||||||
this->ProgramBreak = new Memory::ProgramBreak(this->PageTable, this->vma);
|
this->ProgramBreak = new Memory::ProgramBreak(this->PageTable, this->vma);
|
||||||
this->Signals = new Signal(this);
|
|
||||||
|
|
||||||
debug("Process page table: %#lx", this->PageTable);
|
debug("Process page table: %#lx", this->PageTable);
|
||||||
debug("Created %s process \"%s\"(%d). Parent \"%s\"(%d)",
|
debug("Created %s process \"%s\"(%d). Parent \"%s\"(%d)",
|
||||||
@ -230,7 +231,6 @@ namespace Tasking
|
|||||||
this->AllocatedMemory += sizeof(Memory::VirtualMemoryArea);
|
this->AllocatedMemory += sizeof(Memory::VirtualMemoryArea);
|
||||||
this->AllocatedMemory += sizeof(Memory::ProgramBreak);
|
this->AllocatedMemory += sizeof(Memory::ProgramBreak);
|
||||||
this->AllocatedMemory += sizeof(SymbolResolver::Symbols);
|
this->AllocatedMemory += sizeof(SymbolResolver::Symbols);
|
||||||
this->AllocatedMemory += sizeof(Signal);
|
|
||||||
|
|
||||||
this->Info.SpawnTime = TimeManager->GetCounter();
|
this->Info.SpawnTime = TimeManager->GetCounter();
|
||||||
|
|
||||||
@ -250,9 +250,6 @@ namespace Tasking
|
|||||||
don't get scheduled anymore */
|
don't get scheduled anymore */
|
||||||
ctx->PopProcess(this);
|
ctx->PopProcess(this);
|
||||||
|
|
||||||
debug("Freeing signals");
|
|
||||||
delete this->Signals;
|
|
||||||
|
|
||||||
debug("Freeing allocated memory");
|
debug("Freeing allocated memory");
|
||||||
delete this->ProgramBreak;
|
delete this->ProgramBreak;
|
||||||
delete this->vma;
|
delete this->vma;
|
||||||
|
@ -678,7 +678,7 @@ namespace Tasking::Scheduler
|
|||||||
CPU::x32::wrmsr(CPU::x32::MSR_FS_BASE, CurrentCPU->CurrentThread->FSBase);
|
CPU::x32::wrmsr(CPU::x32::MSR_FS_BASE, CurrentCPU->CurrentThread->FSBase);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CurrentCPU->CurrentProcess->Signals->HandleSignal(Frame);
|
CurrentCPU->CurrentProcess->Signals.HandleSignal(Frame, CurrentCPU->CurrentThread.load());
|
||||||
|
|
||||||
if (!ProcessNotChanged)
|
if (!ProcessNotChanged)
|
||||||
(&CurrentCPU->CurrentProcess->Info)->LastUpdateTime = TimeManager->GetCounter();
|
(&CurrentCPU->CurrentProcess->Info)->LastUpdateTime = TimeManager->GetCounter();
|
||||||
|
@ -30,73 +30,72 @@
|
|||||||
#include "../kernel.h"
|
#include "../kernel.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
const char *lSigStr[] = {
|
|
||||||
"SIGHUP",
|
|
||||||
"SIGINT",
|
|
||||||
"SIGQUIT",
|
|
||||||
"SIGILL",
|
|
||||||
"SIGTRAP",
|
|
||||||
"SIGABRT",
|
|
||||||
"SIGBUS",
|
|
||||||
"SIGFPE",
|
|
||||||
"SIGKILL",
|
|
||||||
"SIGUSR1",
|
|
||||||
"SIGSEGV",
|
|
||||||
"SIGUSR2",
|
|
||||||
"SIGPIPE",
|
|
||||||
"SIGALRM",
|
|
||||||
"SIGTERM",
|
|
||||||
"SIGSTKFLT",
|
|
||||||
"SIGCHLD",
|
|
||||||
"SIGCONT",
|
|
||||||
"SIGSTOP",
|
|
||||||
"SIGTSTP",
|
|
||||||
"SIGTTIN",
|
|
||||||
"SIGTTOU",
|
|
||||||
"SIGURG",
|
|
||||||
"SIGXCPU",
|
|
||||||
"SIGXFSZ",
|
|
||||||
"SIGVTALRM",
|
|
||||||
"SIGPROF",
|
|
||||||
"SIGWINCH",
|
|
||||||
"SIGPOLL",
|
|
||||||
"SIGPWR",
|
|
||||||
"SIGSYS",
|
|
||||||
"SIGUNUSED",
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *sigStr[] = {
|
const char *sigStr[] = {
|
||||||
"INVALID ",
|
/* 0 */ "INVALID",
|
||||||
"SIGABRT ",
|
/* 1 */ "SIGABRT",
|
||||||
"SIGALRM ",
|
/* 2 */ "SIGALRM",
|
||||||
"SIGBUS ",
|
/* 3 */ "SIGBUS",
|
||||||
"SIGCHLD ",
|
/* 4 */ "SIGCHLD",
|
||||||
"SIGCONT ",
|
/* 5 */ "SIGCONT",
|
||||||
"SIGFPE ",
|
/* 6 */ "SIGFPE",
|
||||||
"SIGHUP ",
|
/* 7 */ "SIGHUP",
|
||||||
"SIGILL ",
|
/* 8 */ "SIGILL",
|
||||||
"SIGINT ",
|
/* 9 */ "SIGINT",
|
||||||
"SIGKILL ",
|
/* 10 */ "SIGKILL",
|
||||||
"SIGPIPE ",
|
/* 11 */ "SIGPIPE",
|
||||||
"SIGQUIT ",
|
/* 12 */ "SIGQUIT",
|
||||||
"SIGSEGV ",
|
/* 13 */ "SIGSEGV",
|
||||||
"SIGSTOP ",
|
/* 14 */ "SIGSTOP",
|
||||||
"SIGTERM ",
|
/* 15 */ "SIGTERM",
|
||||||
"SIGTSTP ",
|
/* 16 */ "SIGTSTP",
|
||||||
"SIGTTIN ",
|
/* 17 */ "SIGTTIN",
|
||||||
"SIGTTOU ",
|
/* 18 */ "SIGTTOU",
|
||||||
"SIGUSR1 ",
|
/* 19 */ "SIGUSR1",
|
||||||
"SIGUSR2 ",
|
/* 20 */ "SIGUSR2",
|
||||||
"SIGPOLL ",
|
/* 21 */ "SIGPOLL",
|
||||||
"SIGPROF ",
|
/* 22 */ "SIGPROF",
|
||||||
"SIGSYS ",
|
/* 23 */ "SIGSYS",
|
||||||
"SIGTRAP ",
|
/* 24 */ "SIGTRAP",
|
||||||
"SIGURG ",
|
/* 25 */ "SIGURG",
|
||||||
"SIGVTALRM",
|
/* 26 */ "SIGVTALRM",
|
||||||
"SIGXCPU ",
|
/* 27 */ "SIGXCPU",
|
||||||
"SIGXFSZ ",
|
/* 28 */ "SIGXFSZ",
|
||||||
"SIGRSV1 ",
|
/* 29 */ "SIGCOMP1",
|
||||||
"SIGRSV2 ",
|
/* 30 */ "SIGCOMP2",
|
||||||
|
/* 31 */ "SIGCOMP3",
|
||||||
|
/* 32 */ "SIGRTMIN",
|
||||||
|
/* 33 */ "SIGRT_1",
|
||||||
|
/* 34 */ "SIGRT_2",
|
||||||
|
/* 35 */ "SIGRT_3",
|
||||||
|
/* 36 */ "SIGRT_4",
|
||||||
|
/* 37 */ "SIGRT_5",
|
||||||
|
/* 38 */ "SIGRT_6",
|
||||||
|
/* 39 */ "SIGRT_7",
|
||||||
|
/* 40 */ "SIGRT_8",
|
||||||
|
/* 41 */ "SIGRT_9",
|
||||||
|
/* 42 */ "SIGRT_10",
|
||||||
|
/* 43 */ "SIGRT_11",
|
||||||
|
/* 44 */ "SIGRT_12",
|
||||||
|
/* 45 */ "SIGRT_13",
|
||||||
|
/* 46 */ "SIGRT_14",
|
||||||
|
/* 47 */ "SIGRT_15",
|
||||||
|
/* 48 */ "SIGRT_16",
|
||||||
|
/* 49 */ "SIGRT_17",
|
||||||
|
/* 50 */ "SIGRT_18",
|
||||||
|
/* 51 */ "SIGRT_19",
|
||||||
|
/* 52 */ "SIGRT_20",
|
||||||
|
/* 53 */ "SIGRT_21",
|
||||||
|
/* 54 */ "SIGRT_22",
|
||||||
|
/* 55 */ "SIGRT_23",
|
||||||
|
/* 56 */ "SIGRT_24",
|
||||||
|
/* 57 */ "SIGRT_25",
|
||||||
|
/* 58 */ "SIGRT_26",
|
||||||
|
/* 59 */ "SIGRT_27",
|
||||||
|
/* 60 */ "SIGRT_28",
|
||||||
|
/* 61 */ "SIGRT_29",
|
||||||
|
/* 62 */ "SIGRT_30",
|
||||||
|
/* 63 */ "SIGRT_31",
|
||||||
|
/* 64 */ "SIGRTMAX",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *dispStr[] = {
|
const char *dispStr[] = {
|
||||||
@ -113,50 +112,89 @@ extern "C" uintptr_t _sig_linux_trampoline_start, _sig_linux_trampoline_end;
|
|||||||
|
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
int linuxSignal;
|
Signals Signal;
|
||||||
int nativeSignal;
|
SignalDispositions Disposition;
|
||||||
} signalMapping[] = {
|
} SignalDisposition[] = {
|
||||||
{linux_SIGHUP, SIGHUP},
|
{SIGHUP, SIG_TERM},
|
||||||
{linux_SIGINT, SIGINT},
|
{SIGINT, SIG_TERM},
|
||||||
{linux_SIGQUIT, SIGQUIT},
|
{SIGQUIT, SIG_TERM},
|
||||||
{linux_SIGILL, SIGILL},
|
{SIGILL, SIG_CORE},
|
||||||
{linux_SIGTRAP, SIGTRAP},
|
{SIGTRAP, SIG_CORE},
|
||||||
{linux_SIGABRT, SIGABRT},
|
{SIGABRT, SIG_CORE},
|
||||||
{linux_SIGBUS, SIGBUS},
|
{SIGBUS, SIG_CORE},
|
||||||
{linux_SIGFPE, SIGFPE},
|
{SIGFPE, SIG_CORE},
|
||||||
{linux_SIGKILL, SIGKILL},
|
{SIGKILL, SIG_TERM},
|
||||||
{linux_SIGUSR1, SIGUSR1},
|
{SIGUSR1, SIG_TERM},
|
||||||
{linux_SIGSEGV, SIGSEGV},
|
{SIGSEGV, SIG_CORE},
|
||||||
{linux_SIGUSR2, SIGUSR2},
|
{SIGUSR2, SIG_TERM},
|
||||||
{linux_SIGPIPE, SIGPIPE},
|
{SIGPIPE, SIG_TERM},
|
||||||
{linux_SIGALRM, SIGALRM},
|
{SIGALRM, SIG_TERM},
|
||||||
{linux_SIGTERM, SIGTERM},
|
{SIGTERM, SIG_TERM},
|
||||||
{linux_SIGSTKFLT, SIGRSV1},
|
{SIGCOMP1, SIG_IGN},
|
||||||
{linux_SIGCHLD, SIGCHLD},
|
{SIGCHLD, SIG_IGN},
|
||||||
{linux_SIGCONT, SIGCONT},
|
{SIGCONT, SIG_CONT},
|
||||||
{linux_SIGSTOP, SIGSTOP},
|
{SIGSTOP, SIG_STOP},
|
||||||
{linux_SIGTSTP, SIGTSTP},
|
{SIGTSTP, SIG_STOP},
|
||||||
{linux_SIGTTIN, SIGTTIN},
|
{SIGTTIN, SIG_STOP},
|
||||||
{linux_SIGTTOU, SIGTTOU},
|
{SIGTTOU, SIG_STOP},
|
||||||
{linux_SIGURG, SIGURG},
|
{SIGURG, SIG_IGN},
|
||||||
{linux_SIGXCPU, SIGXCPU},
|
{SIGXCPU, SIG_CORE},
|
||||||
{linux_SIGXFSZ, SIGXFSZ},
|
{SIGXFSZ, SIG_CORE},
|
||||||
{linux_SIGVTALRM, SIGVTALRM},
|
{SIGVTALRM, SIG_TERM},
|
||||||
{linux_SIGPROF, SIGPROF},
|
{SIGPROF, SIG_TERM},
|
||||||
{linux_SIGPOLL, SIGPOLL},
|
{SIGCOMP2, SIG_IGN},
|
||||||
{linux_SIGPWR, SIGRSV2},
|
{SIGPOLL, SIG_TERM},
|
||||||
{linux_SIGSYS, SIGSYS},
|
{SIGCOMP3, SIG_IGN},
|
||||||
{linux_SIGUNUSED, SIGSYS},
|
{SIGSYS, SIG_CORE},
|
||||||
|
{SIGRTMIN, SIG_IGN},
|
||||||
|
{SIGRT_1, SIG_IGN},
|
||||||
|
{SIGRT_2, SIG_IGN},
|
||||||
|
{SIGRT_3, SIG_IGN},
|
||||||
|
{SIGRT_4, SIG_IGN},
|
||||||
|
{SIGRT_5, SIG_IGN},
|
||||||
|
{SIGRT_6, SIG_IGN},
|
||||||
|
{SIGRT_7, SIG_IGN},
|
||||||
|
{SIGRT_8, SIG_IGN},
|
||||||
|
{SIGRT_9, SIG_IGN},
|
||||||
|
{SIGRT_10, SIG_IGN},
|
||||||
|
{SIGRT_11, SIG_IGN},
|
||||||
|
{SIGRT_12, SIG_IGN},
|
||||||
|
{SIGRT_13, SIG_IGN},
|
||||||
|
{SIGRT_14, SIG_IGN},
|
||||||
|
{SIGRT_15, SIG_IGN},
|
||||||
|
{SIGRT_16, SIG_IGN},
|
||||||
|
{SIGRT_17, SIG_IGN},
|
||||||
|
{SIGRT_18, SIG_IGN},
|
||||||
|
{SIGRT_19, SIG_IGN},
|
||||||
|
{SIGRT_20, SIG_IGN},
|
||||||
|
{SIGRT_21, SIG_IGN},
|
||||||
|
{SIGRT_22, SIG_IGN},
|
||||||
|
{SIGRT_23, SIG_IGN},
|
||||||
|
{SIGRT_24, SIG_IGN},
|
||||||
|
{SIGRT_25, SIG_IGN},
|
||||||
|
{SIGRT_26, SIG_IGN},
|
||||||
|
{SIGRT_27, SIG_IGN},
|
||||||
|
{SIGRT_28, SIG_IGN},
|
||||||
|
{SIGRT_29, SIG_IGN},
|
||||||
|
{SIGRT_30, SIG_IGN},
|
||||||
|
{SIGRT_31, SIG_IGN},
|
||||||
|
{SIGRTMAX, SIG_IGN},
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(linux_SIGUNUSED == SIGNAL_MAX);
|
SignalDispositions GetDefaultSignalDisposition(Signals sig)
|
||||||
|
{
|
||||||
|
foreach (auto var in SignalDisposition)
|
||||||
|
{
|
||||||
|
if (var.Signal == sig)
|
||||||
|
return var.Disposition;
|
||||||
|
}
|
||||||
|
|
||||||
#define CTLif(x) ConvertToLinuxIfNecessary(x)
|
error("Invalid signal: %d", sig);
|
||||||
#define CTNif(x) ConvertToNativeIfNecessary(x)
|
return SIG_TERM;
|
||||||
#define CSigTLif(x) ConvertSigsetToLinuxIfNecessary(x)
|
}
|
||||||
#define CSigTNif(x) ConvertSigsetToNativeIfNecessary(x)
|
|
||||||
|
|
||||||
/* TODO: CTLif & CTNif may need optimization */
|
/* syscalls/linux.cpp */
|
||||||
|
extern int ConvertSignalToLinux(Signals sig);
|
||||||
|
|
||||||
namespace Tasking
|
namespace Tasking
|
||||||
{
|
{
|
||||||
@ -165,86 +203,10 @@ namespace Tasking
|
|||||||
return ((PCB *)ctx)->Info.Compatibility == Linux;
|
return ((PCB *)ctx)->Info.Compatibility == Linux;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Signal::ConvertToLinuxIfNecessary(int sig)
|
int Signal::MakeExitCode(Signals sig)
|
||||||
{
|
|
||||||
if (!LinuxSig())
|
|
||||||
{
|
|
||||||
debug("Not linux sig: %d", sig);
|
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (auto &mapping in signalMapping)
|
|
||||||
{
|
|
||||||
if (mapping.nativeSignal == sig)
|
|
||||||
{
|
|
||||||
// debug("Converted %d to %d", sig, mapping.linuxSignal);
|
|
||||||
return mapping.linuxSignal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Signal::ConvertToNativeIfNecessary(int sig)
|
|
||||||
{
|
|
||||||
if (!LinuxSig())
|
|
||||||
{
|
|
||||||
debug("Not native sig: %d", sig);
|
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (auto &mapping in signalMapping)
|
|
||||||
{
|
|
||||||
if (mapping.linuxSignal == sig)
|
|
||||||
{
|
|
||||||
// debug("Converted %d to %d", sig, mapping.nativeSignal);
|
|
||||||
return mapping.nativeSignal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sigset_t Signal::ConvertSigsetToLinuxIfNecessary(sigset_t sig)
|
|
||||||
{
|
|
||||||
if (!LinuxSig())
|
|
||||||
{
|
|
||||||
debug("Not linux sigset: %#lx", sig);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sigset_t ret = 0;
|
|
||||||
for (int i = 0; i < SIGNAL_MAX; i++)
|
|
||||||
{
|
|
||||||
if (sig & ToFlag(i))
|
|
||||||
ret |= ToFlag(CTLif(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
sigset_t Signal::ConvertSigsetToNativeIfNecessary(sigset_t sig)
|
|
||||||
{
|
|
||||||
if (!LinuxSig())
|
|
||||||
{
|
|
||||||
debug("Not native sigset: %#lx", sig);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sigset_t ret = 0;
|
|
||||||
for (int i = 0; i < linux_SIGUNUSED; i++)
|
|
||||||
{
|
|
||||||
if (sig & ToFlag(i))
|
|
||||||
ret |= ToFlag(CTNif(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Signal::MakeExitCode(int sig)
|
|
||||||
{
|
{
|
||||||
if (this->LinuxSig())
|
if (this->LinuxSig())
|
||||||
return 128 + sig;
|
return 128 + ConvertSignalToLinux(sig);
|
||||||
else
|
else
|
||||||
return 100 + sig;
|
return 100 + sig;
|
||||||
}
|
}
|
||||||
@ -293,7 +255,7 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
case Windows:
|
case Windows:
|
||||||
{
|
{
|
||||||
fixme("Windows compatibility");
|
assert(!"Windows compatibility not implemented");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -304,18 +266,18 @@ namespace Tasking
|
|||||||
|
|
||||||
/* ------------------------------------------------------ */
|
/* ------------------------------------------------------ */
|
||||||
|
|
||||||
int Signal::AddWatcher(Signal *who, int sig)
|
int Signal::AddWatcher(Signal *who, Signals sig)
|
||||||
{
|
{
|
||||||
SmartLock(SignalLock);
|
|
||||||
SignalInfo info;
|
SignalInfo info;
|
||||||
info.sig = sig;
|
info.sig = sig;
|
||||||
info.val.sival_ptr = who;
|
info.val.sival_ptr = who;
|
||||||
|
|
||||||
|
SmartLock(SignalLock);
|
||||||
Watchers.push_back(info);
|
Watchers.push_back(info);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Signal::RemoveWatcher(Signal *who, int sig)
|
int Signal::RemoveWatcher(Signal *who, Signals sig)
|
||||||
{
|
{
|
||||||
SmartLock(SignalLock);
|
SmartLock(SignalLock);
|
||||||
forItr(itr, Watchers)
|
forItr(itr, Watchers)
|
||||||
@ -330,42 +292,73 @@ namespace Tasking
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Signal::AddSignal(int sig, union sigval val)
|
int Signal::AddSignal(Signals sig, union sigval val, pid_t tid)
|
||||||
{
|
{
|
||||||
SmartLock(SignalLock);
|
SignalInfo info{.sig = sig, .val = val, .tid = tid};
|
||||||
SignalInfo info{.sig = sig, .val = val};
|
Queue.push_back(info);
|
||||||
SignalQueue.push_back(info);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Signal::RemoveSignal(int sig)
|
int Signal::RemoveSignal(Signals sig)
|
||||||
{
|
{
|
||||||
SmartLock(SignalLock);
|
size_t n = Queue.remove_if([sig](SignalInfo &info)
|
||||||
forItr(itr, SignalQueue)
|
{ return info.sig == sig; });
|
||||||
{
|
debug("Removed %d signals", n);
|
||||||
if (itr->sig == sig)
|
return n ? 0 : -ENOENT;
|
||||||
{
|
|
||||||
SignalQueue.erase(itr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Signal::HandleSignal(CPU::TrapFrame *tf)
|
Signal::SignalInfo Signal::GetAvailableSignal(void *thread)
|
||||||
{
|
{
|
||||||
SmartLock(SignalLock);
|
forItr(itr, Queue)
|
||||||
if (SignalQueue.empty())
|
{
|
||||||
return false;
|
// if (GlobalMask.test(itr->sig - 1))
|
||||||
|
// {
|
||||||
|
// debug("Signal %s is blocked by global mask",
|
||||||
|
// sigStr[itr->sig]);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (((TCB *)thread)->Signals.Mask.test(itr->sig - 1))
|
||||||
|
{
|
||||||
|
debug("Signal %s is blocked by thread mask",
|
||||||
|
sigStr[itr->sig]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((TCB *)thread)->ID != itr->tid && itr->tid != -1)
|
||||||
|
{
|
||||||
|
debug("Signal %s is not for this thread",
|
||||||
|
sigStr[itr->sig]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(sa[itr->sig].sa_handler.Disposition != SAD_IGN);
|
||||||
|
assert(sa[itr->sig].sa_handler.Disposition != SAD_DFL);
|
||||||
|
|
||||||
|
Queue.erase(itr);
|
||||||
|
debug("Signal %s is available", sigStr[itr->sig]);
|
||||||
|
return *itr;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("No signal available");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Signal::HandleSignal(CPU::TrapFrame *tf, void *thread)
|
||||||
|
{
|
||||||
/* We don't want to do this in kernel mode */
|
/* We don't want to do this in kernel mode */
|
||||||
if (unlikely(tf->cs != GDT_USER_CODE))
|
if (tf->cs != GDT_USER_CODE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
debug("We have %d signals to handle", SignalQueue.size());
|
if (Queue.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
SignalInfo sigI = SignalQueue.front();
|
debug("We have %d signals to handle", Queue.size());
|
||||||
SignalQueue.erase(SignalQueue.begin());
|
|
||||||
|
SmartLock(SignalLock);
|
||||||
|
SignalInfo sigI = GetAvailableSignal(thread);
|
||||||
|
if (sigI.sig == SIG_NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
uintptr_t _p_rsp = ((PCB *)ctx)->PageTable->Get(tf->rsp);
|
uintptr_t _p_rsp = ((PCB *)ctx)->PageTable->Get(tf->rsp);
|
||||||
uint64_t paRsp = _p_rsp;
|
uint64_t paRsp = _p_rsp;
|
||||||
@ -388,10 +381,11 @@ namespace Tasking
|
|||||||
si.GSBase = CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
|
si.GSBase = CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
|
||||||
si.FSBase = CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE);
|
si.FSBase = CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE);
|
||||||
si.ShadowGSBase = CPU::x64::rdmsr(CPU::x64::MSR_SHADOW_GS_BASE);
|
si.ShadowGSBase = CPU::x64::rdmsr(CPU::x64::MSR_SHADOW_GS_BASE);
|
||||||
|
si.SignalMask = ((TCB *)thread)->Signals.Mask.to_ulong();
|
||||||
|
si.Compatibility = ((PCB *)ctx)->Info.Compatibility;
|
||||||
|
|
||||||
debug("gs: %#lx fs: %#lx shadow: %#lx",
|
debug("gs: %#lx fs: %#lx shadow: %#lx",
|
||||||
si.GSBase, si.FSBase, si.ShadowGSBase);
|
si.GSBase, si.FSBase, si.ShadowGSBase);
|
||||||
si.SignalMask = SignalMask.load();
|
|
||||||
si.Compatibility = ((PCB *)ctx)->Info.Compatibility;
|
|
||||||
|
|
||||||
/* Copy the stack info */
|
/* Copy the stack info */
|
||||||
uint64_t *pRsp = (uint64_t *)(paRsp - sizeof(StackInfo));
|
uint64_t *pRsp = (uint64_t *)(paRsp - sizeof(StackInfo));
|
||||||
@ -400,31 +394,56 @@ namespace Tasking
|
|||||||
/* Set the handler address */
|
/* Set the handler address */
|
||||||
pRsp--; /* Alignment */
|
pRsp--; /* Alignment */
|
||||||
pRsp--;
|
pRsp--;
|
||||||
*pRsp = uint64_t(SignalAction[sigI.sig].__sa_handler.sa_handler);
|
*pRsp = uint64_t(sa[sigI.sig].sa_handler.Handler);
|
||||||
|
|
||||||
assert(!((uintptr_t)pRsp & 0xF));
|
assert(!((uintptr_t)pRsp & 0xF));
|
||||||
|
|
||||||
|
int cSig = LinuxSig() ? ConvertSignalToLinux((Signals)sigI.sig) : sigI.sig;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpData("Stack Data", (void *)pRsp,
|
DumpData("Stack Data", (void *)pRsp,
|
||||||
paRsp - uint64_t(pRsp));
|
paRsp - uint64_t(pRsp));
|
||||||
debug("initial stack tf->rsp: %#lx after: %#lx",
|
debug("initial stack tf->rsp: %#lx after: %#lx",
|
||||||
tf->rsp, uint64_t(vRsp));
|
tf->rsp, uint64_t(vRsp));
|
||||||
debug("sig: %d -> %d", sigI.sig, CTLif(sigI.sig));
|
debug("sig: %d -> %d", sigI.sig, cSig);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tf->rsp = uint64_t(vRsp);
|
tf->rsp = uint64_t(vRsp);
|
||||||
tf->rip = uint64_t(TrampAddr);
|
tf->rip = uint64_t(TrampAddr);
|
||||||
tf->rdi = CTLif(sigI.sig);
|
|
||||||
tf->rsi = uint64_t(sigI.val.sival_ptr);
|
|
||||||
|
|
||||||
|
/* void func(int signo); */
|
||||||
|
/* void func(int signo, siginfo_t *info, void *context); */
|
||||||
|
tf->rdi = cSig;
|
||||||
|
if (sa[sigI.sig].Flags & SA_SIGINFO)
|
||||||
|
{
|
||||||
|
fixme("SA_SIGINFO not implemented");
|
||||||
|
siginfo_t *info = 0;
|
||||||
|
void *context = 0;
|
||||||
|
tf->rsi = uint64_t(info);
|
||||||
|
tf->rdx = uint64_t(context);
|
||||||
|
tf->rcx = 0;
|
||||||
|
tf->r8 = 0;
|
||||||
|
tf->r9 = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tf->rsi = 0;
|
||||||
|
tf->rdx = 0;
|
||||||
|
tf->rcx = 0;
|
||||||
|
tf->r8 = 0;
|
||||||
|
tf->r9 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
((TCB *)thread)->Signals.Mask = sa[sigI.sig].Mask;
|
||||||
assert(TrampAddr != nullptr);
|
assert(TrampAddr != nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Signal::RestoreHandleSignal(SyscallsFrame *sf)
|
void Signal::RestoreHandleSignal(SyscallsFrame *sf, void *thread)
|
||||||
{
|
{
|
||||||
SmartLock(SignalLock);
|
|
||||||
debug("Restoring signal handler");
|
debug("Restoring signal handler");
|
||||||
|
SmartLock(SignalLock);
|
||||||
|
|
||||||
gsTCB *gs = (gsTCB *)CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
|
gsTCB *gs = (gsTCB *)CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
|
||||||
uint64_t *sp = (uint64_t *)((PCB *)ctx)->PageTable->Get(gs->TempStack);
|
uint64_t *sp = (uint64_t *)((PCB *)ctx)->PageTable->Get(gs->TempStack);
|
||||||
sp++; /* Alignment */
|
sp++; /* Alignment */
|
||||||
@ -454,7 +473,7 @@ namespace Tasking
|
|||||||
sf->ReturnAddress = si->tf.rip;
|
sf->ReturnAddress = si->tf.rip;
|
||||||
gs->TempStack = (void *)si->tf.rsp;
|
gs->TempStack = (void *)si->tf.rsp;
|
||||||
|
|
||||||
SignalMask.store(si->SignalMask);
|
((TCB *)thread)->Signals.Mask = si->SignalMask;
|
||||||
|
|
||||||
CPU::x64::fxrstor(&si->fx);
|
CPU::x64::fxrstor(&si->fx);
|
||||||
CPU::x64::wrmsr(CPU::x64::MSR_GS_BASE, si->ShadowGSBase);
|
CPU::x64::wrmsr(CPU::x64::MSR_GS_BASE, si->ShadowGSBase);
|
||||||
@ -468,86 +487,83 @@ namespace Tasking
|
|||||||
/* Return because we will restore at sysretq */
|
/* Return because we will restore at sysretq */
|
||||||
}
|
}
|
||||||
|
|
||||||
sigset_t Signal::Block(sigset_t sig)
|
int Signal::SetAction(Signals sig, const SignalAction *act)
|
||||||
{
|
{
|
||||||
SmartLock(SignalLock);
|
SmartLock(SignalLock);
|
||||||
sig = CSigTNif(sig);
|
if ((size_t)sig > sizeof(sa) / sizeof(sa[0]))
|
||||||
sigset_t oldMask = SignalMask.fetch_or(sig);
|
|
||||||
debug("%#lx -> %#lx", oldMask, SignalMask);
|
|
||||||
return CSigTLif(oldMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
sigset_t Signal::Unblock(sigset_t sig)
|
|
||||||
{
|
|
||||||
SmartLock(SignalLock);
|
|
||||||
sig = CSigTNif(sig);
|
|
||||||
sigset_t oldMask = SignalMask.fetch_and(~sig);
|
|
||||||
debug("%#lx -> %#lx", oldMask, SignalMask);
|
|
||||||
return CSigTLif(oldMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
sigset_t Signal::SetMask(sigset_t sig)
|
|
||||||
{
|
|
||||||
SmartLock(SignalLock);
|
|
||||||
sig = CSigTNif(sig);
|
|
||||||
sigset_t oldMask = SignalMask.exchange(sig);
|
|
||||||
debug("%#lx -> %#lx", oldMask, SignalMask);
|
|
||||||
return CSigTLif(oldMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Signal::SetAction(int sig, const sigaction act)
|
|
||||||
{
|
|
||||||
SmartLock(SignalLock);
|
|
||||||
int nSig = CTNif(sig);
|
|
||||||
if ((size_t)nSig > sizeof(SignalAction) / sizeof(SignalAction[0]))
|
|
||||||
{
|
{
|
||||||
debug("Invalid signal: %d (req %d)", nSig, sig);
|
debug("Invalid signal: %d", sig);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalAction[nSig].__sa_handler.sa_handler = act.__sa_handler.sa_handler;
|
if ((long)act->sa_handler.Disposition == SAD_IGN)
|
||||||
SignalAction[nSig].sa_mask = act.sa_mask;
|
{
|
||||||
SignalAction[nSig].sa_flags = act.sa_flags;
|
Disposition[sig] = SIG_IGN;
|
||||||
|
debug("Set disposition for %s to SIG_IGN", sigStr[sig]);
|
||||||
|
debug("Discarding pending signals %s", sigStr[sig]);
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
forItr(itr, Queue)
|
||||||
|
{
|
||||||
|
if (itr->sig == sig)
|
||||||
|
{
|
||||||
|
Queue.erase(itr);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
debug("No pending signal %s", sigStr[sig]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((long)act->sa_handler.Disposition == SAD_DFL)
|
||||||
|
{
|
||||||
|
Disposition[sig] = GetDefaultSignalDisposition(sig);
|
||||||
|
debug("Set disposition for %s to %s (default)", sigStr[sig],
|
||||||
|
dispStr[Disposition[sig]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sa[sig].sa_handler.Handler = act->sa_handler.Handler;
|
||||||
|
sa[sig].Mask = act->Mask;
|
||||||
|
sa[sig].Flags = act->Flags;
|
||||||
|
sa[sig].Restorer = act->Restorer;
|
||||||
|
|
||||||
debug("Set action for %s with handler %#lx, mask %#lx and flags %#lx",
|
debug("Set action for %s with handler %#lx, mask %#lx and flags %#lx",
|
||||||
LinuxSig() ? lSigStr[nSig] : sigStr[nSig],
|
sigStr[sig], sa[sig].sa_handler.Handler, sa[sig].Mask, sa[sig].Flags);
|
||||||
SignalAction[nSig].__sa_handler.sa_handler,
|
|
||||||
SignalAction[nSig].sa_mask,
|
|
||||||
SignalAction[nSig].sa_flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Signal::GetAction(int sig, sigaction *act)
|
int Signal::GetAction(Signals sig, SignalAction *act)
|
||||||
{
|
{
|
||||||
SmartLock(SignalLock);
|
SmartLock(SignalLock);
|
||||||
|
if ((size_t)sig > sizeof(sa) / sizeof(sa[0]))
|
||||||
int nSig = CTNif(sig);
|
|
||||||
if ((size_t)nSig > sizeof(SignalAction) / sizeof(SignalAction[0]))
|
|
||||||
{
|
{
|
||||||
debug("Invalid signal: %d (req %d)", nSig, sig);
|
debug("Invalid signal: %d", sig);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
act->__sa_handler.sa_handler = SignalAction[nSig].__sa_handler.sa_handler;
|
act->sa_handler.Handler = sa[sig].sa_handler.Handler;
|
||||||
act->sa_mask = SignalAction[nSig].sa_mask;
|
act->Mask = sa[sig].Mask;
|
||||||
act->sa_flags = SignalAction[nSig].sa_flags;
|
act->Flags = sa[sig].Flags;
|
||||||
|
act->Restorer = sa[sig].Restorer;
|
||||||
debug("Got action for %s with handler %#lx, mask %#lx and flags %#lx",
|
debug("Got action for %s with handler %#lx, mask %#lx and flags %#lx",
|
||||||
LinuxSig() ? lSigStr[nSig] : sigStr[nSig],
|
sigStr[sig], sa[sig].sa_handler.Handler, sa[sig].Mask, sa[sig].Flags);
|
||||||
SignalAction[nSig].__sa_handler.sa_handler,
|
|
||||||
SignalAction[nSig].sa_mask,
|
|
||||||
SignalAction[nSig].sa_flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Signal::SendSignal(int sig, union sigval val)
|
int Signal::SendSignal(Signals sig, sigval val, pid_t tid)
|
||||||
{
|
{
|
||||||
|
SmartLock(SignalLock);
|
||||||
PCB *pcb = (PCB *)ctx;
|
PCB *pcb = (PCB *)ctx;
|
||||||
int nSig = CTNif(sig);
|
LastSignal = sig;
|
||||||
LastSignal = (Signals)nSig;
|
|
||||||
|
|
||||||
debug("Sending signal %s to %s(%d)",
|
debug("Sending signal %s to %s(%d)",
|
||||||
sigStr[nSig], pcb->Name, pcb->ID);
|
sigStr[sig], pcb->Name, pcb->ID);
|
||||||
|
|
||||||
if (SignalAction[nSig].__sa_handler.sa_handler)
|
if (sa[sig].sa_handler.Handler)
|
||||||
{
|
{
|
||||||
if (pcb->Security.ExecutionMode == Kernel)
|
if (pcb->Security.ExecutionMode == Kernel)
|
||||||
{
|
{
|
||||||
@ -555,35 +571,51 @@ namespace Tasking
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("sa_handler: %#lx",
|
if (sa[sig].sa_handler.Disposition == SAD_IGN)
|
||||||
SignalAction[nSig].__sa_handler.sa_handler);
|
{
|
||||||
debug("Adding signal %s to queue", sigStr[nSig]);
|
debug("Ignoring signal %s", sigStr[sig]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("sa_handler: %#lx", sa[sig].sa_handler.Handler);
|
||||||
|
debug("Adding signal %s to queue", sigStr[sig]);
|
||||||
goto CompleteSignal;
|
goto CompleteSignal;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug("No handler for signal %s", sigStr[sig]);
|
||||||
|
}
|
||||||
|
|
||||||
debug("Signal disposition: %s", dispStr[sigDisp[nSig]]);
|
if (thisThread->Signals.Mask.test(sig - 1))
|
||||||
switch (sigDisp[nSig])
|
{
|
||||||
|
debug("Signal %s is blocked by thread mask",
|
||||||
|
sigStr[sig]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("Signal disposition: %s", dispStr[Disposition[sig]]);
|
||||||
|
switch (Disposition[sig])
|
||||||
{
|
{
|
||||||
case SIG_TERM:
|
case SIG_TERM:
|
||||||
{
|
{
|
||||||
if (unlikely(pcb->Security.IsCritical))
|
if (unlikely(pcb->Security.IsCritical))
|
||||||
{
|
{
|
||||||
debug("Critical process %s received signal %s(%d): Terminated",
|
debug("Critical process %s received signal %s(%d): Terminated",
|
||||||
pcb->Name, sigStr[nSig], nSig);
|
pcb->Name, sigStr[sig], sig);
|
||||||
// int3;
|
// int3;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcb->SetExitCode(MakeExitCode(nSig));
|
pcb->SetExitCode(MakeExitCode(sig));
|
||||||
debug("We have %d watchers", this->Watchers.size());
|
debug("We have %d watchers", this->Watchers.size());
|
||||||
if (this->Watchers.size() > 0)
|
if (this->Watchers.size() > 0)
|
||||||
pcb->SetState(Zombie);
|
pcb->SetState(Zombie);
|
||||||
else
|
else
|
||||||
pcb->SetState(Terminated);
|
pcb->SetState(Terminated);
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
case SIG_IGN:
|
case SIG_IGN:
|
||||||
{
|
{
|
||||||
debug("Ignoring signal %d", nSig);
|
debug("Ignoring signal %d", sig);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SIG_CORE:
|
case SIG_CORE:
|
||||||
@ -593,27 +625,31 @@ namespace Tasking
|
|||||||
if (unlikely(pcb->Security.IsCritical))
|
if (unlikely(pcb->Security.IsCritical))
|
||||||
{
|
{
|
||||||
debug("Critical process %s received signal %s(%d): Core dumped",
|
debug("Critical process %s received signal %s(%d): Core dumped",
|
||||||
pcb->Name, sigStr[nSig], nSig);
|
pcb->Name, sigStr[sig], sig);
|
||||||
// int3;
|
// int3;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcb->SetExitCode(MakeExitCode(nSig));
|
pcb->SetExitCode(MakeExitCode(sig));
|
||||||
debug("We have %d watchers", this->Watchers.size());
|
debug("We have %d watchers", this->Watchers.size());
|
||||||
if (this->Watchers.size() > 0)
|
if (this->Watchers.size() > 0)
|
||||||
pcb->SetState(CoreDump);
|
pcb->SetState(CoreDump);
|
||||||
else
|
else
|
||||||
pcb->SetState(Terminated);
|
pcb->SetState(Terminated);
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
case SIG_STOP:
|
case SIG_STOP:
|
||||||
{
|
{
|
||||||
|
debug("Stopping process %s(%d) with signal %s(%d)",
|
||||||
|
pcb->Name, pcb->ID, sigStr[sig], sig);
|
||||||
pcb->SetState(Stopped);
|
pcb->SetState(Stopped);
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
case SIG_CONT:
|
case SIG_CONT:
|
||||||
{
|
{
|
||||||
|
debug("Continuing process %s(%d) with signal %s(%d)",
|
||||||
|
pcb->Name, pcb->ID, sigStr[sig], sig);
|
||||||
pcb->SetState(Ready);
|
pcb->SetState(Ready);
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
assert(!"Invalid signal disposition");
|
assert(!"Invalid signal disposition");
|
||||||
@ -624,14 +660,14 @@ namespace Tasking
|
|||||||
if (pcb->Security.ExecutionMode == Kernel)
|
if (pcb->Security.ExecutionMode == Kernel)
|
||||||
{
|
{
|
||||||
debug("Kernel process %s received signal %s(%d)! Ignoring... (with exceptions)",
|
debug("Kernel process %s received signal %s(%d)! Ignoring... (with exceptions)",
|
||||||
pcb->Name, sigStr[nSig], nSig);
|
pcb->Name, sigStr[sig], sig);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->InitTrampoline();
|
this->InitTrampoline();
|
||||||
|
|
||||||
debug("Signal %s(%d) completed", sigStr[nSig], nSig);
|
debug("Signal %s(%d) completed", sigStr[sig], sig);
|
||||||
if (sigDisp[nSig] != SIG_IGN)
|
if (Disposition[sig] != SIG_IGN)
|
||||||
{
|
{
|
||||||
foreach (auto info in Watchers)
|
foreach (auto info in Watchers)
|
||||||
{
|
{
|
||||||
@ -645,27 +681,24 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug("Adding signal to queue");
|
debug("Adding signal to queue");
|
||||||
SignalQueue.push_back({.sig = nSig, .val = val});
|
Queue.push_back({.sig = sig, .val = val, .tid = tid});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Signal::WaitAnySignal()
|
int Signal::WaitAnySignal()
|
||||||
{
|
{
|
||||||
/* Sleep until a signal that terminated or invokes
|
|
||||||
the signal catch function */
|
|
||||||
|
|
||||||
debug("Waiting for any signal");
|
debug("Waiting for any signal");
|
||||||
|
|
||||||
size_t oldSize = SignalQueue.size();
|
size_t oldSize = Queue.size();
|
||||||
Reset:
|
Reset:
|
||||||
while (SignalQueue.size() == oldSize)
|
while (Queue.size() == oldSize)
|
||||||
TaskManager->Yield();
|
TaskManager->Yield();
|
||||||
|
|
||||||
if (SignalQueue.size() > oldSize)
|
if (Queue.size() > oldSize)
|
||||||
{
|
{
|
||||||
debug("Added signal to queue %d > %d",
|
debug("Added signal to queue %d > %d",
|
||||||
SignalQueue.size(), oldSize);
|
Queue.size(), oldSize);
|
||||||
oldSize = SignalQueue.size();
|
oldSize = Queue.size();
|
||||||
goto Reset;
|
goto Reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,77 +706,66 @@ namespace Tasking
|
|||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Signal::HasPendingSignal()
|
int Signal::WaitSignal(Signals sig, union sigval *val)
|
||||||
{
|
|
||||||
return !SignalQueue.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Signal::WaitSignal(int sig, union sigval *val)
|
|
||||||
{
|
{
|
||||||
|
assert(!"WaitSignal not implemented");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Signal::WaitSignalTimeout(int sig, union sigval *val, uint64_t timeout)
|
int Signal::WaitSignalTimeout(Signals sig, union sigval *val, uint64_t timeout)
|
||||||
{
|
{
|
||||||
|
assert(!"WaitSignalTimeout not implemented");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Signal::Signal(void *ctx)
|
Signal::Signal(void *_ctx)
|
||||||
{
|
{
|
||||||
assert(ctx != nullptr);
|
assert(_ctx != nullptr);
|
||||||
this->ctx = ctx;
|
this->ctx = _ctx;
|
||||||
|
|
||||||
sigDisp[SIG_NULL] = SIG_IGN;
|
// for (int i = 1; i < SIGNAL_MAX; i++)
|
||||||
sigDisp[SIGABRT] = SIG_CORE;
|
// Disposition[i] = GetDefaultSignalDisposition(i);
|
||||||
sigDisp[SIGALRM] = SIG_TERM;
|
|
||||||
sigDisp[SIGBUS] = SIG_CORE;
|
|
||||||
sigDisp[SIGCHLD] = SIG_IGN;
|
|
||||||
sigDisp[SIGCONT] = SIG_CONT;
|
|
||||||
sigDisp[SIGFPE] = SIG_CORE;
|
|
||||||
sigDisp[SIGHUP] = SIG_TERM;
|
|
||||||
sigDisp[SIGILL] = SIG_CORE;
|
|
||||||
sigDisp[SIGINT] = SIG_TERM;
|
|
||||||
sigDisp[SIGKILL] = SIG_TERM;
|
|
||||||
sigDisp[SIGPIPE] = SIG_TERM;
|
|
||||||
sigDisp[SIGQUIT] = SIG_TERM;
|
|
||||||
sigDisp[SIGSEGV] = SIG_CORE;
|
|
||||||
sigDisp[SIGSTOP] = SIG_STOP;
|
|
||||||
sigDisp[SIGTERM] = SIG_TERM;
|
|
||||||
sigDisp[SIGTSTP] = SIG_STOP;
|
|
||||||
sigDisp[SIGTTIN] = SIG_STOP;
|
|
||||||
sigDisp[SIGTTOU] = SIG_STOP;
|
|
||||||
sigDisp[SIGUSR1] = SIG_TERM;
|
|
||||||
sigDisp[SIGUSR2] = SIG_TERM;
|
|
||||||
sigDisp[SIGPOLL] = SIG_TERM;
|
|
||||||
sigDisp[SIGPROF] = SIG_TERM;
|
|
||||||
sigDisp[SIGSYS] = SIG_CORE;
|
|
||||||
sigDisp[SIGTRAP] = SIG_CORE;
|
|
||||||
sigDisp[SIGURG] = SIG_IGN;
|
|
||||||
sigDisp[SIGVTALRM] = SIG_TERM;
|
|
||||||
sigDisp[SIGXCPU] = SIG_CORE;
|
|
||||||
sigDisp[SIGXFSZ] = SIG_CORE;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int once = 0;
|
static int once = 0;
|
||||||
if (!once++)
|
if (!once++)
|
||||||
{
|
{
|
||||||
if (LinuxSig())
|
for (int i = 1; i < SIGNAL_MAX; i++)
|
||||||
{
|
debug("%s: %s",
|
||||||
for (int i = 0; i <= linux_SIGUNUSED; i++)
|
sigStr[i],
|
||||||
debug("%s: %s",
|
dispStr[Disposition[(Signals)i]]);
|
||||||
lSigStr[i],
|
|
||||||
dispStr[sigDisp[i]]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < SIGNAL_MAX; i++)
|
|
||||||
debug("%s: %s",
|
|
||||||
sigStr[i],
|
|
||||||
dispStr[sigDisp[i]]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Signal::~Signal() {}
|
Signal::~Signal() {}
|
||||||
|
|
||||||
|
sigset_t ThreadSignal::Block(sigset_t sig)
|
||||||
|
{
|
||||||
|
sigset_t oldMask = Mask.to_ulong();
|
||||||
|
Mask |= sig;
|
||||||
|
debug("%#lx -> %#lx", oldMask, Mask);
|
||||||
|
return oldMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigset_t ThreadSignal::Unblock(sigset_t sig)
|
||||||
|
{
|
||||||
|
sigset_t oldMask = Mask.to_ulong();
|
||||||
|
Mask &= ~sig;
|
||||||
|
debug("%#lx -> %#lx", oldMask, Mask);
|
||||||
|
return oldMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigset_t ThreadSignal::SetMask(sigset_t sig)
|
||||||
|
{
|
||||||
|
sigset_t oldMask = Mask.to_ulong();
|
||||||
|
Mask = sig;
|
||||||
|
debug("%#lx -> %#lx", oldMask, Mask);
|
||||||
|
return oldMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigset_t ThreadSignal::GetMask()
|
||||||
|
{
|
||||||
|
return Mask.to_ulong();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ namespace Tasking
|
|||||||
{
|
{
|
||||||
int TCB::SendSignal(int sig)
|
int TCB::SendSignal(int sig)
|
||||||
{
|
{
|
||||||
return this->Parent->Signals->SendSignal(sig);
|
return this->Parent->Signals.SendSignal((enum Signals)sig, {0}, this->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCB::SetState(TaskState state)
|
void TCB::SetState(TaskState state)
|
||||||
@ -420,6 +420,7 @@ namespace Tasking
|
|||||||
TaskArchitecture Architecture,
|
TaskArchitecture Architecture,
|
||||||
TaskCompatibility Compatibility,
|
TaskCompatibility Compatibility,
|
||||||
bool ThreadNotReady)
|
bool ThreadNotReady)
|
||||||
|
: Signals(Parent->Signals)
|
||||||
{
|
{
|
||||||
debug("+ %#lx", this);
|
debug("+ %#lx", this);
|
||||||
|
|
||||||
@ -440,6 +441,14 @@ namespace Tasking
|
|||||||
this->ctx = ctx;
|
this->ctx = ctx;
|
||||||
this->ID = (TID)this->Parent->ID + (TID)this->Parent->Threads.size();
|
this->ID = (TID)this->Parent->ID + (TID)this->Parent->Threads.size();
|
||||||
|
|
||||||
|
if (Compatibility == TaskCompatibility::Linux)
|
||||||
|
{
|
||||||
|
if (Parent->Threads.size() == 0)
|
||||||
|
this->Linux.tgid = Parent->ID;
|
||||||
|
else
|
||||||
|
this->Linux.tgid = Parent->Threads.front()->Linux.tgid;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->Name)
|
if (this->Name)
|
||||||
delete[] this->Name;
|
delete[] this->Name;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user