github.com/LanceLRQ/deer-common@v0.0.9-0.20210319081233-e8222ac018a8/sandbox/forkexec/setrlimit_unix.go (about)

     1  // +build darwin linux
     2  
     3  package forkexec
     4  
     5  import (
     6  	"math"
     7  	"runtime"
     8  	"syscall"
     9  )
    10  
    11  const DarwinSafeStackSize = 65500
    12  
    13  // 定义ITimer的常量
    14  const (
    15  	ITIMER_REAL    = 0
    16  	ITIMER_VIRTUAL = 1
    17  	ITIMER_PROF    = 2
    18  )
    19  
    20  type RLimit struct {
    21  	Which  int
    22  	Enable bool
    23  	RLim   syscall.Rlimit
    24  }
    25  
    26  type ITimerVal struct {
    27  	ItInterval TimeVal
    28  	ItValue    TimeVal
    29  }
    30  
    31  type TimeVal struct {
    32  	TvSec  uint64
    33  	TvUsec uint64
    34  }
    35  
    36  type ExecRLimit struct {
    37  	TimeLimit     int // 时间限制 (ms)
    38  	RealTimeLimit int // 真实时间限制 (ms, 触发SIGALRM)
    39  	MemoryLimit   int // 内存限制 (KB)
    40  	FileSizeLimit int // 文件读写限制 (B)
    41  	StackLimit    int // 栈大小限制 (KB,0表示用内存限制的值,-1表示不限制,建议设置为2倍。Mac下有坑,不要去设置。)
    42  }
    43  
    44  type RlimitOptions struct {
    45  	Rlimits     []RLimit
    46  	ITimerValue ITimerVal
    47  }
    48  
    49  // 解析ExecRLimit结构体并获取setrlimit操作需要的信息
    50  func GetRlimitOptions(sysRlimit *ExecRLimit) *RlimitOptions {
    51  	// Make stack limit
    52  	stackLimit := uint64(sysRlimit.StackLimit)
    53  	if stackLimit <= 0 {
    54  		stackLimit = uint64(sysRlimit.MemoryLimit * 2)
    55  	}
    56  
    57  	return &RlimitOptions{
    58  		Rlimits: []RLimit{
    59  			// Set time limit: RLIMIT_CPU
    60  			{
    61  				Which:  syscall.RLIMIT_CPU,
    62  				Enable: sysRlimit.TimeLimit > 0,
    63  				RLim: syscall.Rlimit{
    64  					Cur: uint64(math.Ceil(float64(sysRlimit.TimeLimit) / 1000.0)),
    65  					Max: uint64(math.Ceil(float64(sysRlimit.TimeLimit) / 1000.0)),
    66  				},
    67  			},
    68  			// Set memory limit: RLIMIT_DATA
    69  			{
    70  				Which:  syscall.RLIMIT_DATA,
    71  				Enable: sysRlimit.MemoryLimit > 0,
    72  				RLim: syscall.Rlimit{
    73  					Cur: uint64(sysRlimit.MemoryLimit * 1024),
    74  					Max: uint64(sysRlimit.MemoryLimit * 1024 * 2),
    75  				},
    76  			},
    77  			// Set memory limit: RLIMIT_AS
    78  			{
    79  				Which:  syscall.RLIMIT_AS,
    80  				Enable: sysRlimit.MemoryLimit > 0,
    81  				RLim: syscall.Rlimit{
    82  					Cur: uint64(sysRlimit.MemoryLimit * 1024 * 2),
    83  					Max: uint64(sysRlimit.MemoryLimit*1024*2 + 1024),
    84  				},
    85  			},
    86  			// Set stack limit (坑:macos不要去搞这个!)
    87  			{
    88  				Which:  syscall.RLIMIT_STACK,
    89  				Enable: stackLimit > 0 && sysRlimit.StackLimit >= 0 && runtime.GOOS != "darwin",
    90  				RLim: syscall.Rlimit{
    91  					Cur: stackLimit * 1024,
    92  					Max: stackLimit*1024 + 1024,
    93  				},
    94  			},
    95  			// Set file size limit: RLIMIT_FSIZE
    96  			{
    97  				Which:  syscall.RLIMIT_FSIZE,
    98  				Enable: sysRlimit.FileSizeLimit > 0,
    99  				RLim: syscall.Rlimit{
   100  					Cur: uint64(sysRlimit.FileSizeLimit),
   101  					Max: uint64(sysRlimit.FileSizeLimit),
   102  				},
   103  			},
   104  		},
   105  		ITimerValue: ITimerVal{
   106  			ItInterval: TimeVal{
   107  				TvSec:  uint64(math.Floor(float64(sysRlimit.RealTimeLimit) / 1000.0)),
   108  				TvUsec: uint64(sysRlimit.RealTimeLimit % 1000 * 1000),
   109  			},
   110  			ItValue: TimeVal{
   111  				TvSec:  uint64(math.Floor(float64(sysRlimit.RealTimeLimit) / 1000.0)),
   112  				TvUsec: uint64(sysRlimit.RealTimeLimit % 1000 * 1000),
   113  			},
   114  		},
   115  	}
   116  }