首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Posix信号实现

Posix信号实现
EN

Code Review用户
提问于 2021-06-27 21:04:44
回答 1查看 107关注 0票数 3

我的爱好是类似Unix的操作系统。

最近,我开始编写自己的基于sel4的Posix兼容操作系统。下面是内部信号处理函数的代码,它提供了一种后端来帮助实现诸如do_killdo_sigsuspend之类的函数。

我想知道您对代码质量的看法,以及我忽略的任何可能的错误。

代码语言:javascript
运行
复制
#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;
                }

        };
EN

回答 1

Code Review用户

发布于 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。但是,为什么不定义函数来返回引用,而不是指针呢?

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/263526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档