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 int fd, n, argc, sethard, setsoft, limit;
62 int flag[256];
63 char **argv, **oargv, *p;
64 char *argv0;
65 struct rlimit rl;
67 argv0 = nil;
68 setstatus("");
69 oargv = mkargv(runq->argv->words);
70 argv = oargv+1;
71 for(argc=0; argv[argc]; argc++)
72 ;
74 memset(flag, 0, sizeof flag);
75 ARGBEGIN{
76 default:
77 if(strchr(eargs, ARGC()) == nil){
78 eusage();
79 return;
80 }
81 case 'S':
82 case 'H':
83 case 'a':
84 flag[ARGC()] = 1;
85 break;
86 }ARGEND
88 if(argc > 1){
89 eusage();
90 goto out;
91 }
93 fd = mapfd(1);
95 sethard = 1;
96 setsoft = 1;
97 if(flag['S'] && flag['H'])
98 ;
99 else if(flag['S'])
100 sethard = 0;
101 else if(flag['H'])
102 setsoft = 0;
104 limit = Notset;
105 if(argc>0){
106 if(strcmp(argv[0], "unlimited") == 0)
107 limit = Unlimited;
108 else if(strcmp(argv[0], "hard") == 0)
109 limit = Hard;
110 else if(strcmp(argv[0], "soft") == 0)
111 limit = Soft;
112 else if((limit = strtol(argv[0], &p, 0)) < 0 || *p != 0){
113 eusage();
114 goto out;
117 if(flag['a']){
118 for(p=eargs; *p; p++){
119 getrlimit(rlx[p-eargs], &rl);
120 n = flag['H'] ? rl.rlim_max : rl.rlim_cur;
121 if(n == -1)
122 fprint(fd, "ulimit -%c unlimited\n", *p);
123 else
124 fprint(fd, "ulimit -%c %d\n", *p, n);
126 goto out;
128 for(p=eargs; *p; p++){
129 if(flag[(uchar)*p]){
130 n = 0;
131 getrlimit(rlx[p-eargs], &rl);
132 switch(limit){
133 case Notset:
134 n = flag['H'] ? rl.rlim_max : rl.rlim_cur;
135 if(n == -1)
136 fprint(fd, "ulimit -%c unlimited\n", *p);
137 else
138 fprint(fd, "ulimit -%c %d\n", *p, n);
139 break;
140 case Hard:
141 n = rl.rlim_max;
142 goto set;
143 case Soft:
144 n = rl.rlim_cur;
145 goto set;
146 case Unlimited:
147 n = -1;
148 goto set;
149 default:
150 n = limit;
151 set:
152 if(setsoft)
153 rl.rlim_cur = n;
154 if(sethard)
155 rl.rlim_max = n;
156 if(setrlimit(rlx[p-eargs], &rl) < 0)
157 fprint(mapfd(2), "setrlimit: %r\n");
162 out:
163 free(oargv);
164 poplist();
165 flush(err);
168 void
169 execumask(void)
171 int n, argc;
172 char **argv, **oargv, *p;
173 char *argv0;
175 argv0 = nil;
176 setstatus("");
177 oargv = mkargv(runq->argv->words);
178 argv = oargv+1;
179 for(argc=0; argv[argc]; argc++)
182 ARGBEGIN{
183 default:
184 usage:
185 fprint(mapfd(2), "usage: umask [mode]\n");
186 goto out;
187 }ARGEND
189 if(argc > 1)
190 goto usage;
192 if(argc == 1){
193 n = strtol(argv[0], &p, 8);
194 if(*p != 0 || p == argv[0])
195 goto usage;
196 umask(n);
197 goto out;
200 n = umask(0);
201 umask(n);
202 if(n < 0){
203 fprint(mapfd(2), "umask: %r\n");
204 goto out;
207 fprint(mapfd(1), "umask %03o\n", n);
209 out:
210 free(oargv);
211 poplist();
212 flush(err);
215 /*
216 * Cope with non-blocking read.
217 */
218 long
219 readnb(int fd, char *buf, long cnt)
221 int n, didreset;
222 int flgs;
224 didreset = 0;
225 while((n = read(fd, buf, cnt)) == -1)
226 if(!didreset && errno == EAGAIN){
227 if((flgs = fcntl(fd, F_GETFL, 0)) == -1)
228 return -1;
229 flgs &= ~O_NONBLOCK;
230 if(fcntl(fd, F_SETFL, flgs) == -1)
231 return -1;
232 didreset = 1;
235 return n;