Blob


1 #include <u.h>
2 #include <sys/time.h>
3 #include <sys/stat.h>
4 #include <sys/resource.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <libc.h>
8 #include "rc.h"
9 #include "exec.h"
10 #include "io.h"
11 #include "fns.h"
12 #include "getflags.h"
14 extern char **mkargv(word*);
15 extern int mapfd(int);
17 static char *eargs = "cdflmnstuv";
18 static int rlx[] = {
19 RLIMIT_CORE,
20 RLIMIT_DATA,
21 RLIMIT_FSIZE,
22 #ifdef RLIMIT_MEMLOCK
23 RLIMIT_MEMLOCK,
24 #else
25 0,
26 #endif
27 #ifdef RLIMIT_RSS
28 RLIMIT_RSS,
29 #else
30 0,
31 #endif
32 RLIMIT_NOFILE,
33 RLIMIT_STACK,
34 RLIMIT_CPU,
35 #ifdef RLIMIT_NPROC
36 RLIMIT_NPROC,
37 #else
38 0,
39 #endif
40 #ifdef RLIMIT_RSS
41 RLIMIT_RSS,
42 #else
43 0,
44 #endif
45 };
47 static void
48 eusage(void)
49 {
50 fprint(mapfd(2), "usage: ulimit [-SHa%s [limit]]\n", eargs);
51 }
53 #define Notset -4
54 #define Unlimited -3
55 #define Hard -2
56 #define Soft -1
58 void
59 execulimit(void)
60 {
61 rlim_t n;
62 int fd, argc, sethard, setsoft, limit;
63 int flag[256];
64 char **argv, **oargv, *p;
65 char *argv0;
66 struct rlimit rl;
68 argv0 = nil;
69 setstatus("");
70 oargv = mkargv(runq->argv->words);
71 argv = oargv+1;
72 for(argc=0; argv[argc]; argc++)
73 ;
75 memset(flag, 0, sizeof flag);
76 ARGBEGIN{
77 default:
78 if(strchr(eargs, ARGC()) == nil){
79 eusage();
80 return;
81 }
82 case 'S':
83 case 'H':
84 case 'a':
85 flag[ARGC()] = 1;
86 break;
87 }ARGEND
89 if(argc > 1){
90 eusage();
91 goto out;
92 }
94 fd = mapfd(1);
96 sethard = 1;
97 setsoft = 1;
98 if(flag['S'] && flag['H'])
99 ;
100 else if(flag['S'])
101 sethard = 0;
102 else if(flag['H'])
103 setsoft = 0;
105 limit = Notset;
106 if(argc>0){
107 if(strcmp(argv[0], "unlimited") == 0)
108 limit = Unlimited;
109 else if(strcmp(argv[0], "hard") == 0)
110 limit = Hard;
111 else if(strcmp(argv[0], "soft") == 0)
112 limit = Soft;
113 else if((limit = strtol(argv[0], &p, 0)) < 0 || *p != 0){
114 eusage();
115 goto out;
118 if(flag['a']){
119 for(p=eargs; *p; p++){
120 getrlimit(rlx[p-eargs], &rl);
121 n = flag['H'] ? rl.rlim_max : rl.rlim_cur;
122 if(n == RLIM_INFINITY)
123 fprint(fd, "ulimit -%c unlimited\n", *p);
124 else
125 fprint(fd, "ulimit -%c %llud\n", *p, (uvlong)n);
127 goto out;
129 for(p=eargs; *p; p++){
130 if(flag[(uchar)*p]){
131 n = 0;
132 getrlimit(rlx[p-eargs], &rl);
133 switch(limit){
134 case Notset:
135 n = flag['H'] ? rl.rlim_max : rl.rlim_cur;
136 if(n == RLIM_INFINITY)
137 fprint(fd, "ulimit -%c unlimited\n", *p);
138 else
139 fprint(fd, "ulimit -%c %llud\n", *p, (uvlong)n);
140 break;
141 case Hard:
142 n = rl.rlim_max;
143 goto set;
144 case Soft:
145 n = rl.rlim_cur;
146 goto set;
147 case Unlimited:
148 n = RLIM_INFINITY;
149 goto set;
150 default:
151 n = limit;
152 set:
153 if(setsoft)
154 rl.rlim_cur = n;
155 if(sethard)
156 rl.rlim_max = n;
157 if(setrlimit(rlx[p-eargs], &rl) < 0)
158 fprint(mapfd(2), "setrlimit: %r\n");
163 out:
164 free(oargv);
165 poplist();
166 flush(err);
169 void
170 execumask(void)
172 int n, argc;
173 char **argv, **oargv, *p;
174 char *argv0;
176 argv0 = nil;
177 setstatus("");
178 oargv = mkargv(runq->argv->words);
179 argv = oargv+1;
180 for(argc=0; argv[argc]; argc++)
183 ARGBEGIN{
184 default:
185 usage:
186 fprint(mapfd(2), "usage: umask [mode]\n");
187 goto out;
188 }ARGEND
190 if(argc > 1)
191 goto usage;
193 if(argc == 1){
194 n = strtol(argv[0], &p, 8);
195 if(*p != 0 || p == argv[0])
196 goto usage;
197 umask(n);
198 goto out;
201 n = umask(0);
202 umask(n);
203 if(n < 0){
204 fprint(mapfd(2), "umask: %r\n");
205 goto out;
208 fprint(mapfd(1), "umask %03o\n", n);
210 out:
211 free(oargv);
212 poplist();
213 flush(err);
216 /*
217 * Cope with non-blocking read.
218 */
219 long
220 readnb(int fd, char *buf, long cnt)
222 int n, didreset;
223 int flgs;
225 didreset = 0;
226 again:
227 n = read(fd, buf, cnt);
228 if(n == -1)
229 if(errno == EAGAIN){
230 if(!didreset){
231 if((flgs = fcntl(fd, F_GETFL, 0)) == -1)
232 return -1;
233 flgs &= ~O_NONBLOCK;
234 if(fcntl(fd, F_SETFL, flgs) == -1)
235 return -1;
236 didreset = 1;
238 goto again;
241 return n;