1 #include <sys/types.h>
2 #include <time.h>
3 #include <sys/time.h>
4 #include <sys/resource.h>
5 #include "env.h"
6 #include "pathexec.h"
7 #include "sgetopt.h"
8 #include "strerr.h"
9 #include "scan.h"
10 #include "str.h"
11 
12 #define FATAL "softlimit: fatal: "
13 
die_usage(void)14 static void die_usage(void)
15 {
16   strerr_die1x(100,"softlimit: usage: softlimit [-a allbytes] [-c corebytes] [-d databytes] [-f filebytes] [-l lockbytes] [-m membytes] [-o openfiles] [-p processes] [-r residentbytes] [-s stackbytes] [-t cpusecs] child");
17 }
18 
doit(int resource,const char * arg)19 static void doit(int resource,const char *arg)
20 {
21   unsigned long u;
22   struct rlimit r;
23 
24   if (getrlimit(resource,&r) == -1)
25     strerr_die2sys(111,FATAL,"getrlimit failed");
26 
27   if (str_equal(arg,"="))
28     r.rlim_cur = r.rlim_max;
29   else if (str_equal(arg,"-"))
30     r.rlim_cur = r.rlim_max = RLIM_INFINITY;
31   else {
32     if (arg[scan_ulong(arg,&u)]) die_usage();
33     r.rlim_cur = u;
34     if (r.rlim_cur > r.rlim_max)
35       r.rlim_cur = r.rlim_max;
36   }
37 
38   if (setrlimit(resource,&r) == -1)
39     strerr_die2sys(111,FATAL,"setrlimit failed");
40 }
41 
doenv(int resource,const char * name)42 static void doenv(int resource,const char *name)
43 {
44   const char *arg;
45   if ((arg = env_get(name)) != 0)
46     doit(resource,arg);
47 }
48 
doallenv(void)49 static void doallenv(void)
50 {
51 #ifdef RLIMIT_AS
52   doenv(RLIMIT_AS,"SOFTLIMIT_ALLBYTES");
53   doenv(RLIMIT_AS,"SOFTLIMIT_MEMBYTES");
54 #endif
55 #ifdef RLIMIT_VMEM
56   doenv(RLIMIT_VMEM,"SOFTLIMIT_ALLBYTES");
57   doenv(RLIMIT_VMEM,"SOFTLIMIT_MEMBYTES");
58 #endif
59 #ifdef RLIMIT_CORE
60   doenv(RLIMIT_CORE,"SOFTLIMIT_COREBYTES");
61 #endif
62 #ifdef RLIMIT_DATA
63   doenv(RLIMIT_DATA,"SOFTLIMIT_DATABYTES");
64   doenv(RLIMIT_DATA,"SOFTLIMIT_MEMBYTES");
65 #endif
66 #ifdef RLIMIT_FSIZE
67   doenv(RLIMIT_FSIZE,"SOFTLIMIT_FILEBYTES");
68 #endif
69 #ifdef RLIMIT_MEMLOCK
70   doenv(RLIMIT_MEMLOCK,"SOFTLIMIT_LOCKEDBYTES");
71   doenv(RLIMIT_MEMLOCK,"SOFTLIMIT_MEMBYTES");
72 #endif
73 #ifdef RLIMIT_STACK
74   doenv(RLIMIT_STACK,"SOFTLIMIT_STACKBYTES");
75   doenv(RLIMIT_STACK,"SOFTLIMIT_MEMBYTES");
76 #endif
77 #ifdef RLIMIT_NOFILE
78   doenv(RLIMIT_NOFILE,"SOFTLIMIT_OPENFILES");
79 #endif
80 #ifdef RLIMIT_OFILE
81   doenv(RLIMIT_OFILE,"SOFTLIMIT_OPENFILES");
82 #endif
83 #ifdef RLIMIT_NPROC
84   doenv(RLIMIT_NPROC,"SOFTLIMIT_PROCS");
85 #endif
86 #ifdef RLIMIT_RSS
87   doenv(RLIMIT_RSS,"SOFTLIMIT_RSSBYTES");
88 #endif
89 #ifdef RLIMIT_CPU
90   doenv(RLIMIT_CPU,"SOFTLIMIT_CPUSECS");
91 #endif
92 }
93 
main(int argc,const char * const * argv,const char * const * envp)94 int main(int argc,const char *const *argv,const char *const *envp)
95 {
96   int opt;
97 
98   doallenv();
99   while ((opt = getopt(argc,argv,"a:c:d:f:l:m:o:p:r:s:t:")) != opteof)
100     switch(opt) {
101       case '?':
102 	die_usage();
103       case 'a':
104 #ifdef RLIMIT_AS
105         doit(RLIMIT_AS,optarg);
106 #endif
107 #ifdef RLIMIT_VMEM
108         doit(RLIMIT_VMEM,optarg);
109 #endif
110         break;
111       case 'c':
112 #ifdef RLIMIT_CORE
113         doit(RLIMIT_CORE,optarg);
114 #endif
115         break;
116       case 'd':
117 #ifdef RLIMIT_DATA
118         doit(RLIMIT_DATA,optarg);
119 #endif
120         break;
121       case 'f':
122 #ifdef RLIMIT_FSIZE
123         doit(RLIMIT_FSIZE,optarg);
124 #endif
125         break;
126       case 'l':
127 #ifdef RLIMIT_MEMLOCK
128         doit(RLIMIT_MEMLOCK,optarg);
129 #endif
130         break;
131       case 'm':
132 #ifdef RLIMIT_DATA
133         doit(RLIMIT_DATA,optarg);
134 #endif
135 #ifdef RLIMIT_STACK
136         doit(RLIMIT_STACK,optarg);
137 #endif
138 #ifdef RLIMIT_MEMLOCK
139         doit(RLIMIT_MEMLOCK,optarg);
140 #endif
141 #ifdef RLIMIT_VMEM
142         doit(RLIMIT_VMEM,optarg);
143 #endif
144 #ifdef RLIMIT_AS
145         doit(RLIMIT_AS,optarg);
146 #endif
147 	break;
148       case 'o':
149 #ifdef RLIMIT_NOFILE
150         doit(RLIMIT_NOFILE,optarg);
151 #endif
152 #ifdef RLIMIT_OFILE
153         doit(RLIMIT_OFILE,optarg);
154 #endif
155         break;
156       case 'p':
157 #ifdef RLIMIT_NPROC
158         doit(RLIMIT_NPROC,optarg);
159 #endif
160         break;
161       case 'r':
162 #ifdef RLIMIT_RSS
163         doit(RLIMIT_RSS,optarg);
164 #endif
165         break;
166       case 's':
167 #ifdef RLIMIT_STACK
168         doit(RLIMIT_STACK,optarg);
169 #endif
170         break;
171       case 't':
172 #ifdef RLIMIT_CPU
173         doit(RLIMIT_CPU,optarg);
174 #endif
175         break;
176     }
177 
178   argv += optind;
179   if (!*argv) die_usage();
180 
181   pathexec_run(*argv,argv,envp);
182   strerr_die3sys(111,FATAL,"unable to run ",*argv);
183 }
184