unixcrap.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
unixcrap.c (3678B) | |
--- | |
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" | |
13 | |
14 extern char **mkargv(word*); | |
15 extern int mapfd(int); | |
16 | |
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 }; | |
46 | |
47 static void | |
48 eusage(void) | |
49 { | |
50 fprint(mapfd(2), "usage: ulimit [-SHa%s [limit]]\n", eargs); | |
51 } | |
52 | |
53 #define Notset -4 | |
54 #define Unlimited -3 | |
55 #define Hard -2 | |
56 #define Soft -1 | |
57 | |
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; | |
66 | |
67 argv0 = nil; | |
68 setstatus(""); | |
69 oargv = mkargv(runq->argv->words); | |
70 argv = oargv+1; | |
71 for(argc=0; argv[argc]; argc++) | |
72 ; | |
73 | |
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 | |
87 | |
88 if(argc > 1){ | |
89 eusage(); | |
90 goto out; | |
91 } | |
92 | |
93 fd = mapfd(1); | |
94 | |
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; | |
103 | |
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; | |
115 } | |
116 } | |
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); | |
125 } | |
126 goto out; | |
127 } | |
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_cu… | |
135 if(n == -1) | |
136 fprint(fd, "ulimit -%c unlimited… | |
137 else | |
138 fprint(fd, "ulimit -%c %d\n", *p… | |
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\… | |
158 } | |
159 } | |
160 } | |
161 | |
162 out: | |
163 free(oargv); | |
164 poplist(); | |
165 flush(err); | |
166 } | |
167 | |
168 void | |
169 execumask(void) | |
170 { | |
171 int n, argc; | |
172 char **argv, **oargv, *p; | |
173 char *argv0; | |
174 | |
175 argv0 = nil; | |
176 setstatus(""); | |
177 oargv = mkargv(runq->argv->words); | |
178 argv = oargv+1; | |
179 for(argc=0; argv[argc]; argc++) | |
180 ; | |
181 | |
182 ARGBEGIN{ | |
183 default: | |
184 usage: | |
185 fprint(mapfd(2), "usage: umask [mode]\n"); | |
186 goto out; | |
187 }ARGEND | |
188 | |
189 if(argc > 1) | |
190 goto usage; | |
191 | |
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; | |
198 } | |
199 | |
200 n = umask(0); | |
201 umask(n); | |
202 if(n < 0){ | |
203 fprint(mapfd(2), "umask: %r\n"); | |
204 goto out; | |
205 } | |
206 | |
207 fprint(mapfd(1), "umask %03o\n", n); | |
208 | |
209 out: | |
210 free(oargv); | |
211 poplist(); | |
212 flush(err); | |
213 } | |
214 | |
215 /* | |
216 * Cope with non-blocking read. | |
217 */ | |
218 long | |
219 readnb(int fd, char *buf, long cnt) | |
220 { | |
221 int n, didreset; | |
222 int flgs; | |
223 | |
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; | |
233 } | |
234 | |
235 return n; | |
236 } |