unixcrap.c (3767B)
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 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; 67 68 argv0 = nil; 69 setstatus(""); 70 oargv = mkargv(runq->argv->words); 71 argv = oargv+1; 72 for(argc=0; argv[argc]; argc++) 73 ; 74 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 88 89 if(argc > 1){ 90 eusage(); 91 goto out; 92 } 93 94 fd = mapfd(1); 95 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; 104 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; 116 } 117 } 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); 126 } 127 goto out; 128 } 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"); 159 } 160 } 161 } 162 163 out: 164 free(oargv); 165 poplist(); 166 flush(err); 167 } 168 169 void 170 execumask(void) 171 { 172 int n, argc; 173 char **argv, **oargv, *p; 174 char *argv0; 175 176 argv0 = nil; 177 setstatus(""); 178 oargv = mkargv(runq->argv->words); 179 argv = oargv+1; 180 for(argc=0; argv[argc]; argc++) 181 ; 182 183 ARGBEGIN{ 184 default: 185 usage: 186 fprint(mapfd(2), "usage: umask [mode]\n"); 187 goto out; 188 }ARGEND 189 190 if(argc > 1) 191 goto usage; 192 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; 199 } 200 201 n = umask(0); 202 umask(n); 203 if(n < 0){ 204 fprint(mapfd(2), "umask: %r\n"); 205 goto out; 206 } 207 208 fprint(mapfd(1), "umask %03o\n", n); 209 210 out: 211 free(oargv); 212 poplist(); 213 flush(err); 214 } 215 216 /* 217 * Cope with non-blocking read. 218 */ 219 long 220 readnb(int fd, char *buf, long cnt) 221 { 222 int n, didreset; 223 int flgs; 224 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; 237 } 238 goto again; 239 } 240 241 return n; 242 }