我的爱好是类似Unix的操作系统。
最近,我开始编写自己的基于sel4的Posix兼容操作系统。下面是内部信号处理函数的代码,它提供了一种后端来帮助实现诸如do_kill或do_sigsuspend之类的函数。
我想知道您对代码质量的看法,以及我忽略的任何可能的错误。
#include "process_definitions.hxx"
#include <signal.h>
#include <array>
#include "signal_definitions.hxx"
#include <sys/types.h>
#include <unistd.h>
#include <kernel_glue.hxx>
using namespace process_methods;
std::array<int, 256> signal_num ;
std::array<pid_t, 256> receiver ;
sigset_t signals_methods::signal_queue::dump_pending(pid_t pid)
{
sigset_t retval;
for (int init = 256; init-- ;)
{
if (receiver[init] == pid )
{
int index = (signal_num[init] / sizeof(sigset_t));
*(retval.__val) = *(retval.__val) & (1 << signal_num[init]);
}
}
return retval;
}
void signals_methods::signal_queue::aggregate_signal_queue()
{
for (int init = 256 ; init--;)
{
send_signal(receiver[init], signal_num[init]);
receiver[init] = 0 ;
signal_num[init] = 0;
}
}
void signals_methods::signal_queue::put_signal_to_queue(pid_t pid, int signal)
{
for (int init = 256; init--;)
{
if (signal_num[init] == 0 && receiver[init] == 0)
{
signal_num[init] = signal;
receiver[init] = pid;
}
}
};
signal_data_struct *signals_methods::get_signal_info(pid_t pid)
{
return &get_process_info(pid)->signal_data;
}
signal_data_struct *signals_methods::get_signal_info()
{
return &get_process_info()->signal_data;
}
void signals_methods::send_signal(pid_t pid, int signal)
{
if (!(get_signal_info(pid)->signal_flags[signal] & (1 << SA_NOMASK)))
{
if (*(get_signal_info(pid)->blocked_mask.__val) & (1 << signal))
{
signals_methods::signal_queue::put_signal_to_queue(pid, signal); //signal is blocked so wait while it will be unblocked
return;
}
}
get_signal_info(pid)->blocked_mask = get_signal_info(pid)->signal_mask[signal];
if (get_signal_info(pid)->handler[signal] == SIG_DFL )
{
exec_default_signal_handler( pid, signal);
return;
}
if (get_signal_info(pid)->handler[signal] == SIG_IGN)
{
return;
}
if(get_signal_info(pid)->thread_suspend_lock)
{
thread_restore(pid);
}
if (get_signal_info(pid)->signal_flags[signal] & SA_SIGINFO)
{
exec_signal_handler_siginfo(pid, &get_signal_info(pid)->handler[signal], signal, &(get_signal_info(pid)->siginfo[signal]));
}
else
{
exec_signal_handler(pid, signal, &get_signal_info(pid)->handler[signal]);
}
}
void signals_methods::exec_default_signal_handler(pid_t pid, int signal)
{
#define dump 0
#define revoke 1
#define stop 2
#define cont 3
#define ign 4
int sigmode [] = {
[SIGABRT] = dump,
[SIGBUS] = dump,
[SIGFPE] = dump,
[SIGILL] = dump,
[SIGQUIT] = dump,
[SIGSEGV] = dump ,
[SIGSYS] = dump ,
[SIGTRAP] = dump ,
[SIGXCPU] = dump ,
[SIGXFSZ] = dump ,
[SIGALRM] = revoke,
[SIGHUP] = revoke,
[SIGINT] = revoke,
[SIGKILL] = revoke,
[SIGPIPE] = revoke,
[SIGTERM] = revoke,
[SIGUSR1] = revoke,
[SIGUSR2] = revoke,
[SIGPOLL] = revoke,
[SIGPROF] = revoke,
[SIGVTALRM] = revoke,
[SIGSTOP] = stop,
[SIGTSTP] = stop ,
[SIGTTIN] = stop,
[SIGTTOU] = stop,
[SIGCONT ] = cont,
[SIGURG] = ign
};
if (!(get_signal_info(pid)->signal_flags[signal] & SA_NOCLDSTOP))
{
signals_methods::signal_queue::put_signal_to_queue(SIGCHLD, get_process_info(pid)->parent_pid);
//get_signal_info(get_process_info(pid)->parent_pid)->siginfo[SIGCHLD]._sifields)
}
switch (sigmode[signal])
{
case dump:
thread_dump(pid);
break;
case revoke:
thread_revoke(pid);
break;
case stop:
thread_stop(pid);
break;
case cont:
thread_restore(pid);
default:
return;
break;
}
};发布于 2021-06-28 16:12:26
托比的回答提到了神奇常数256的高度使用。
我认为您至少应该使用signal_num.size()等,以便数字只出现在数组定义中。即使这样,由于您有多个大小相同的数组,所以应该给一个常量命名为signal_count。
在遍历整个数组时,最好使用基于范围的for语句。将测试和减量与测试结合起来是很奇怪的。既然您似乎总是向后迭代,那么您应该将它们按相反的顺序存储吗?然后,只需根据信号号转换获取/设置值的调用的参数即可。
signal_data_struct *signals_methods::get_signal_info(pid_t pid)
在C++中,与C不同的是,将类型为非变量(在本例中为函数名)的*放在常规位置。写signal_data_struct* foo。但是,为什么不定义函数来返回引用,而不是指针呢?
https://codereview.stackexchange.com/questions/263526
复制相似问题