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_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"); 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 }