mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 16:26:48 +00:00
new:在fork时拷贝signal和sighand (#91)
* refcount初始化 * new: 实现copy_sighand del: 删除sighand_struct的wqh, 待将来有需要时,替换成rust版本的 * new: 拷贝signal bugfix: 解决拷贝sighand时的uaf问题
This commit is contained in:
parent
66f67c6a95
commit
c8025a8879
@ -108,13 +108,12 @@ struct signal_struct
|
||||
|
||||
/**
|
||||
* @brief 信号处理结构体,位于pcb之中。
|
||||
*
|
||||
* 请注意,该结构体需要与rust的版本一致,且以rust的为准
|
||||
*/
|
||||
struct sighand_struct
|
||||
{
|
||||
spinlock_t siglock;
|
||||
refcount_t count;
|
||||
wait_queue_head_t signal_fd_wqh;
|
||||
// 为每个信号注册的处理函数的结构体
|
||||
struct sigaction action[MAX_SIG_NUM];
|
||||
};
|
||||
|
@ -4,7 +4,6 @@
|
||||
// todo: 将这里更换为手动编写的ffi绑定
|
||||
use crate::include::bindings::bindings::atomic_t;
|
||||
use crate::include::bindings::bindings::spinlock_t;
|
||||
use crate::include::bindings::bindings::wait_queue_head_t;
|
||||
use crate::libs::ffi_convert::FFIBind2Rust;
|
||||
use crate::libs::ffi_convert::__convert_mut;
|
||||
use crate::libs::ffi_convert::__convert_ref;
|
||||
@ -27,6 +26,12 @@ pub struct signal_struct {
|
||||
pub sig_cnt: atomic_t,
|
||||
}
|
||||
|
||||
impl Default for signal_struct{
|
||||
fn default() -> Self {
|
||||
Self { sig_cnt: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sigaction中的信号处理函数结构体
|
||||
* 分为两种处理函数
|
||||
@ -50,6 +55,13 @@ impl core::fmt::Debug for sigaction__union_u{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Default for sigaction__union_u {
|
||||
fn default() -> Self {
|
||||
Self{_sa_handler:None}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 信号处理结构体
|
||||
*/
|
||||
@ -62,6 +74,13 @@ pub struct sigaction {
|
||||
pub sa_restorer: ::core::option::Option<unsafe extern "C" fn()>, // 暂时未实现该函数
|
||||
}
|
||||
|
||||
impl Default for sigaction{
|
||||
fn default() -> Self {
|
||||
Self { _u: Default::default(), sa_flags: Default::default(), sa_mask: Default::default(), sa_restorer: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 信号消息的结构体,作为参数传入sigaction结构体中指向的处理函数
|
||||
@ -115,10 +134,15 @@ pub struct __sifields__kill {
|
||||
pub struct sighand_struct {
|
||||
pub siglock: spinlock_t,
|
||||
pub count: RefCount,
|
||||
pub signal_fd_wqh: wait_queue_head_t,
|
||||
pub action: [sigaction; MAX_SIG_NUM as usize],
|
||||
}
|
||||
|
||||
impl Default for sighand_struct{
|
||||
fn default() -> Self {
|
||||
Self { siglock: Default::default(), count: Default::default(), action: [Default::default();MAX_SIG_NUM as usize] }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 正在等待的信号的标志位
|
||||
*/
|
||||
@ -319,4 +343,18 @@ impl FFIBind2Rust<crate::include::bindings::bindings::sighand_struct> for sighan
|
||||
) -> Option<&'a Self> {
|
||||
return __convert_ref(src)
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 将给定的来自bindgen的sigaction解析为Rust的signal.rs中定义的sigaction的引用
|
||||
impl FFIBind2Rust<crate::include::bindings::bindings::sigaction> for sigaction{
|
||||
fn convert_mut<'a>(
|
||||
src: *mut crate::include::bindings::bindings::sigaction,
|
||||
) -> Option<&'a mut Self> {
|
||||
return __convert_mut(src);
|
||||
}
|
||||
fn convert_ref<'a>(
|
||||
src: *const crate::include::bindings::bindings::sigaction,
|
||||
) -> Option<&'a Self> {
|
||||
return __convert_ref(src)
|
||||
}
|
||||
}
|
@ -7,8 +7,8 @@ use crate::{
|
||||
ENOTSUP, ESRCH, PF_EXITING, PF_KTHREAD, PF_WAKEKILL, PROC_INTERRUPTIBLE,
|
||||
},
|
||||
DragonOS::signal::{
|
||||
si_code_val, sighand_struct, siginfo, signal_struct, sigpending, sigset_t,
|
||||
SignalNumber, MAX_SIG_NUM, sigaction, sigaction__union_u,
|
||||
si_code_val, sigaction, sigaction__union_u, sighand_struct, siginfo, signal_struct,
|
||||
sigpending, sigset_t, SignalNumber, MAX_SIG_NUM,
|
||||
},
|
||||
},
|
||||
kBUG, kdebug, kwarn,
|
||||
@ -26,13 +26,11 @@ use crate::{
|
||||
use crate::include::DragonOS::signal::{__siginfo_union, __siginfo_union_data};
|
||||
|
||||
/// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
|
||||
pub static DEFAULT_SIGACTION: sigaction = sigaction{
|
||||
_u: sigaction__union_u{
|
||||
_sa_handler: None,
|
||||
},
|
||||
sa_flags:0,
|
||||
sa_mask:0,
|
||||
sa_restorer:None
|
||||
pub static DEFAULT_SIGACTION: sigaction = sigaction {
|
||||
_u: sigaction__union_u { _sa_handler: None },
|
||||
sa_flags: 0,
|
||||
sa_mask: 0,
|
||||
sa_restorer: None,
|
||||
};
|
||||
|
||||
/// @brief kill系统调用,向指定的进程发送信号
|
||||
@ -142,7 +140,7 @@ fn signal_send_sig_info(
|
||||
if !lock_process_sighand(target_pcb, &mut flags).is_none() {
|
||||
// 发送信号
|
||||
retval = send_signal_locked(sig, info, target_pcb, PidType::PID);
|
||||
|
||||
|
||||
kdebug!("flags=0x{:016x}", flags);
|
||||
// 对sighand放锁
|
||||
unlock_process_sighand(target_pcb, &flags);
|
||||
@ -159,22 +157,20 @@ fn lock_process_sighand<'a>(
|
||||
flags: &mut u64,
|
||||
) -> Option<&'a mut sighand_struct> {
|
||||
kdebug!("lock_process_sighand");
|
||||
let x = unsafe { &mut *pcb.sighand };
|
||||
|
||||
let sighand_ptr = sighand_struct::convert_mut(unsafe { &mut *pcb.sighand });
|
||||
// kdebug!("sighand_ptr={:?}", &sighand_ptr);
|
||||
if !sighand_ptr.is_some() {
|
||||
kBUG!("Sighand ptr of process {pid} is NULL!", pid = pcb.pid);
|
||||
return None;
|
||||
}else{
|
||||
|
||||
} else {
|
||||
kdebug!("7777");
|
||||
}
|
||||
let lock = {&mut sighand_ptr.unwrap().siglock};
|
||||
let lock = { &mut sighand_ptr.unwrap().siglock };
|
||||
kdebug!("123");
|
||||
kdebug!("lock={}", unsafe{*(lock as *mut spinlock_t as *mut i8)});
|
||||
kdebug!("lock={}", unsafe { *(lock as *mut spinlock_t as *mut i8) });
|
||||
spin_lock_irqsave(lock, flags);
|
||||
kdebug!("lock={}", unsafe{*(lock as *mut spinlock_t as *mut i8)});
|
||||
kdebug!("lock={}", unsafe { *(lock as *mut spinlock_t as *mut i8) });
|
||||
kdebug!("locked");
|
||||
let ret = unsafe { ((*pcb).sighand as *mut sighand_struct).as_mut() };
|
||||
|
||||
@ -186,10 +182,10 @@ fn lock_process_sighand<'a>(
|
||||
/// @param flags 用来保存rflags的变量,将这个值恢复到rflags寄存器中
|
||||
fn unlock_process_sighand(pcb: &mut process_control_block, flags: &u64) {
|
||||
kdebug!("unlock_process_sighand");
|
||||
let lock = unsafe{&mut (*pcb.sighand).siglock};
|
||||
let lock = unsafe { &mut (*pcb.sighand).siglock };
|
||||
kdebug!("lock={:?}", lock);
|
||||
spin_unlock_irqrestore(lock, flags);
|
||||
kdebug!("lock={}", unsafe{*(lock as *mut spinlock_t as *mut i8)});
|
||||
kdebug!("lock={}", unsafe { *(lock as *mut spinlock_t as *mut i8) });
|
||||
kdebug!("123443");
|
||||
}
|
||||
|
||||
@ -238,7 +234,10 @@ fn __send_signal_locked(
|
||||
let mut retval = 0;
|
||||
|
||||
// 判断该进入该函数时,是否已经持有了锁
|
||||
println!("locked={}",spin_is_locked(unsafe { &(*pcb.sighand).siglock }));
|
||||
println!(
|
||||
"locked={}",
|
||||
spin_is_locked(unsafe { &(*pcb.sighand).siglock })
|
||||
);
|
||||
kdebug!("1234");
|
||||
let _pending: Option<&mut sigpending> = sigpending::convert_mut(&mut pcb.sig_pending);
|
||||
kdebug!("567");
|
||||
@ -399,4 +398,3 @@ fn signal_wake_up_state(pcb: &mut process_control_block, state: u64) {
|
||||
process_kick(pcb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,26 @@
|
||||
use core::ptr::read_volatile;
|
||||
#![allow(dead_code)]
|
||||
use core::ptr::{read_volatile, write_volatile};
|
||||
|
||||
use crate::include::bindings::bindings::atomic_t;
|
||||
|
||||
/// @brief 原子的读取指定的原子变量的值
|
||||
#[inline]
|
||||
pub fn atomic_read(ato:*const atomic_t)-> i64{
|
||||
unsafe{
|
||||
pub fn atomic_read(ato: *const atomic_t) -> i64 {
|
||||
unsafe {
|
||||
return read_volatile(&(*ato).value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 原子的设置原子变量的值
|
||||
#[inline]
|
||||
pub fn atomic_set(ato: *mut atomic_t, value:i64) {
|
||||
unsafe{
|
||||
write_volatile(&mut (*ato).value, value);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for atomic_t {
|
||||
fn default() -> Self {
|
||||
Self { value: 0 }
|
||||
}
|
||||
}
|
||||
|
15
kernel/src/libs/list.rs
Normal file
15
kernel/src/libs/list.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use crate::include::bindings::bindings::List;
|
||||
|
||||
/// @brief 初始化链表
|
||||
#[inline]
|
||||
pub fn list_init(list: *mut List) {
|
||||
unsafe{*list}.prev = list;
|
||||
unsafe{*list}.next = list;
|
||||
}
|
||||
|
||||
impl Default for List{
|
||||
fn default() -> Self {
|
||||
let x= Self { prev: 0 as *mut List, next: 0 as *mut List };
|
||||
return x;
|
||||
}
|
||||
}
|
@ -3,4 +3,6 @@ pub mod spinlock;
|
||||
pub mod ffi_convert;
|
||||
#[macro_use]
|
||||
pub mod refcount;
|
||||
pub mod atomic;
|
||||
pub mod atomic;
|
||||
pub mod wait_queue;
|
||||
pub mod list;
|
@ -7,6 +7,12 @@ pub struct RefCount {
|
||||
pub refs: atomic_t,
|
||||
}
|
||||
|
||||
impl Default for RefCount{
|
||||
fn default() -> Self {
|
||||
Self { refs: atomic_t { value: 1 }}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 将给定的来自bindgen的refcount_t解析为Rust的RefCount的引用
|
||||
impl FFIBind2Rust<crate::include::bindings::bindings::refcount_struct> for RefCount{
|
||||
fn convert_mut<'a>(
|
||||
@ -21,10 +27,11 @@ impl FFIBind2Rust<crate::include::bindings::bindings::refcount_struct> for RefCo
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 以指定的值初始化refcount
|
||||
macro_rules! REFCOUNT_INIT {
|
||||
($x:expr) => {
|
||||
$crate::libs::refcount::RefCount {
|
||||
refs: atomic_t { value: 0 },
|
||||
refs: $crate::include::bindings::bindings::atomic_t { value: $x },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -28,3 +28,9 @@ pub fn spin_is_locked(lock: &spinlock_t) -> bool {
|
||||
|
||||
return if val == 0 { true } else { false };
|
||||
}
|
||||
|
||||
impl Default for spinlock_t {
|
||||
fn default() -> Self {
|
||||
Self { lock: 1 }
|
||||
}
|
||||
}
|
12
kernel/src/libs/wait_queue.rs
Normal file
12
kernel/src/libs/wait_queue.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::include::bindings::bindings::{wait_queue_head_t};
|
||||
|
||||
use super::{list::list_init};
|
||||
|
||||
|
||||
impl Default for wait_queue_head_t{
|
||||
fn default() -> Self {
|
||||
let mut x = Self { wait_list: Default::default(), lock: Default::default() };
|
||||
list_init(&mut x.wait_list);
|
||||
return x;
|
||||
}
|
||||
}
|
@ -12,11 +12,12 @@ int process_copy_files(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
int process_copy_flags(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
int process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
int process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
|
||||
uint64_t stack_size, struct pt_regs *current_regs);
|
||||
|
||||
extern int process_copy_sighand(uint64_t clone_flags, struct process_control_block * pcb);
|
||||
extern int process_copy_signal(uint64_t clone_flags, struct process_control_block * pcb);
|
||||
uint64_t stack_size, struct pt_regs *current_regs);
|
||||
|
||||
extern int process_copy_sighand(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
extern int process_copy_signal(uint64_t clone_flags, struct process_control_block *pcb);
|
||||
extern void process_exit_sighand(struct process_control_block *pcb);
|
||||
extern void process_exit_signal(struct process_control_block *pcb);
|
||||
|
||||
/**
|
||||
* @brief fork当前进程
|
||||
@ -111,14 +112,14 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
retval = process_copy_files(clone_flags, tsk);
|
||||
if (retval)
|
||||
goto copy_files_failed;
|
||||
|
||||
|
||||
// 拷贝信号处理函数
|
||||
retval = process_copy_sighand(clone_flags, tsk);
|
||||
if(retval)
|
||||
if (retval)
|
||||
goto copy_sighand_failed;
|
||||
|
||||
|
||||
retval = process_copy_signal(clone_flags, tsk);
|
||||
if(retval)
|
||||
if (retval)
|
||||
goto copy_signal_failed;
|
||||
|
||||
// 拷贝线程结构体
|
||||
@ -338,7 +339,7 @@ static int process_rewrite_rbp(struct pt_regs *new_regs, struct process_control_
|
||||
* @return uint64_t
|
||||
*/
|
||||
int process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
|
||||
uint64_t stack_size, struct pt_regs *current_regs)
|
||||
uint64_t stack_size, struct pt_regs *current_regs)
|
||||
{
|
||||
// 将线程结构体放置在pcb后方
|
||||
struct thread_struct *thd = (struct thread_struct *)(pcb + 1);
|
||||
|
@ -1,27 +1,102 @@
|
||||
use crate::{include::bindings::bindings::{process_control_block, CLONE_SIGHAND}, kdebug, libs::{refcount::{refcount_inc, RefCount}, ffi_convert::FFIBind2Rust}, arch::x86_64::asm::current::current_pcb};
|
||||
use core::ptr::null_mut;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use crate::{
|
||||
arch::x86_64::asm::current::current_pcb,
|
||||
include::{
|
||||
bindings::bindings::{
|
||||
process_control_block, CLONE_CLEAR_SIGHAND, CLONE_SIGHAND, CLONE_THREAD, ENOMEM,
|
||||
},
|
||||
DragonOS::signal::{sigaction, sighand_struct, signal_struct},
|
||||
},
|
||||
ipc::signal::DEFAULT_SIGACTION,
|
||||
kdebug,
|
||||
libs::{
|
||||
ffi_convert::FFIBind2Rust,
|
||||
refcount::{refcount_inc, RefCount},
|
||||
spinlock::{spin_lock_irqsave, spin_unlock_irqrestore}, atomic::atomic_set,
|
||||
},
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
|
||||
kdebug!("process_copy_sighand");
|
||||
if(clone_flags & (CLONE_SIGHAND as u64)) != 0{
|
||||
let r = RefCount::convert_mut(unsafe{&mut (*((current_pcb().sighand))).count}).unwrap();
|
||||
refcount_inc(r);
|
||||
if (clone_flags & (CLONE_SIGHAND as u64)) != 0 {
|
||||
let r = RefCount::convert_mut(unsafe { &mut (*(current_pcb().sighand)).count }).unwrap();
|
||||
refcount_inc(r);
|
||||
}
|
||||
0
|
||||
// 在这里使用Box::leak将动态申请的内存的生命周期转换为static的
|
||||
let mut sig: &mut sighand_struct = Box::leak(Box::new(sighand_struct::default()));
|
||||
if (sig as *mut sighand_struct) == null_mut() {
|
||||
return -(ENOMEM as i32);
|
||||
}
|
||||
// 将新的sighand赋值给pcb
|
||||
unsafe {
|
||||
(*pcb).sighand = sig as *mut sighand_struct as usize
|
||||
as *mut crate::include::bindings::bindings::sighand_struct;
|
||||
}
|
||||
|
||||
// 拷贝sigaction
|
||||
let mut flags: u64 = 0;
|
||||
spin_lock_irqsave(unsafe { &mut (*current_pcb().sighand).siglock }, &mut flags);
|
||||
for (index, x) in unsafe { (*current_pcb().sighand).action }
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
if !(x as *const crate::include::bindings::bindings::sigaction).is_null() {
|
||||
sig.action[index] =
|
||||
*sigaction::convert_ref(x as *const crate::include::bindings::bindings::sigaction)
|
||||
.unwrap();
|
||||
} else {
|
||||
sig.action[index] = DEFAULT_SIGACTION;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(unsafe { &mut (*current_pcb().sighand).siglock }, &flags);
|
||||
|
||||
// 将所有屏蔽的信号的处理函数设置为default
|
||||
if (clone_flags & (CLONE_CLEAR_SIGHAND as u64)) != 0 {
|
||||
todo!();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
|
||||
kdebug!("process_copy_signal");
|
||||
0
|
||||
// 如果克隆的是线程,则不拷贝信号(同一进程的各个线程之间共享信号)
|
||||
if (clone_flags & (CLONE_THREAD as u64)) != 0 {
|
||||
return 0;
|
||||
}
|
||||
let sig: &mut signal_struct = Box::leak(Box::new(signal_struct::default()));
|
||||
if (sig as *mut signal_struct) == null_mut() {
|
||||
return -(ENOMEM as i32);
|
||||
}
|
||||
atomic_set(&mut sig.sig_cnt, 1);
|
||||
// 将sig赋值给pcb中的字段
|
||||
unsafe {
|
||||
(*pcb).signal = sig as *mut signal_struct as usize
|
||||
as *mut crate::include::bindings::bindings::signal_struct;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_exit_signal(pcb: *mut process_control_block){
|
||||
// todo: 回收进程的信号结构体
|
||||
pub extern "C" fn process_exit_signal(pcb: *mut process_control_block) {
|
||||
// 回收进程的信号结构体
|
||||
unsafe {
|
||||
drop((*pcb).sighand as *mut sighand_struct);
|
||||
(*pcb).sighand = 0 as *mut crate::include::bindings::bindings::sighand_struct;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block){
|
||||
pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block) {
|
||||
// todo: 回收进程的sighand结构体
|
||||
unsafe {
|
||||
drop((*pcb).signal as *mut signal_struct);
|
||||
(*pcb).signal = 0 as *mut crate::include::bindings::bindings::signal_struct;
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,21 @@
|
||||
use crate::{
|
||||
include::{
|
||||
bindings::bindings::{atomic_t, spinlock_t, wait_queue_head_t, List},
|
||||
bindings::bindings::{atomic_t, spinlock_t},
|
||||
DragonOS::signal::{sighand_struct, signal_struct, MAX_SIG_NUM},
|
||||
},
|
||||
ipc::signal::DEFAULT_SIGACTION,
|
||||
};
|
||||
|
||||
/// @brief 初始进程的signal结构体
|
||||
#[no_mangle]
|
||||
pub static INITIAL_SIGNALS: signal_struct = signal_struct {
|
||||
sig_cnt: atomic_t { value: 0 },
|
||||
};
|
||||
|
||||
/// @brief 初始进程的sighand结构体
|
||||
#[no_mangle]
|
||||
pub static mut INITIAL_SIGHAND: sighand_struct = sighand_struct {
|
||||
count: REFCOUNT_INIT!(1),
|
||||
siglock: spinlock_t { lock: 1 },
|
||||
signal_fd_wqh: wait_queue_head_t {
|
||||
lock: spinlock_t { lock: 1 },
|
||||
wait_list: List {
|
||||
prev: unsafe { &INITIAL_SIGHAND.signal_fd_wqh.wait_list as *const List } as *mut List,
|
||||
next: unsafe { &INITIAL_SIGHAND.signal_fd_wqh.wait_list as *const List } as *mut List,
|
||||
},
|
||||
},
|
||||
action: [DEFAULT_SIGACTION; MAX_SIG_NUM as usize],
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <DragonOS/signal.h>
|
||||
#include <common/wait_queue.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// 进程最大可拥有的文件描述符数量
|
||||
#define PROC_MAX_FD_NUM 16
|
||||
@ -32,11 +32,12 @@
|
||||
#define USER_DS (0x30)
|
||||
|
||||
// 进程初始化时的数据拷贝标志位
|
||||
#define CLONE_FS (1UL << 0) // 在进程间共享打开的文件
|
||||
#define CLONE_SIGNAL (1UL << 1) // 克隆时,与父进程共享信号结构体
|
||||
#define CLONE_VM (1UL << 2) // 在进程间共享虚拟内存空间
|
||||
#define CLONE_SIGHAND (1UL << 3) // 克隆时,与父进程共享信号处理结构体
|
||||
|
||||
#define CLONE_FS (1UL << 0) // 在进程间共享打开的文件
|
||||
#define CLONE_SIGNAL (1UL << 1) // 克隆时,与父进程共享信号结构体
|
||||
#define CLONE_VM (1UL << 2) // 在进程间共享虚拟内存空间
|
||||
#define CLONE_SIGHAND (1UL << 3) // 克隆时,与父进程共享信号处理结构体
|
||||
#define CLONE_CLEAR_SIGHAND (1UL << 4) // 克隆时,将原本被设置为SIG_IGNORE的信号,设置回SIG_DEFAULT
|
||||
#define CLONE_THREAD (1UL << 5) // 拷贝线程
|
||||
#define PCB_NAME_LEN 16
|
||||
|
||||
struct thread_struct
|
||||
|
Loading…
x
Reference in New Issue
Block a user