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_MEMLOCK23 RLIMIT_MEMLOCK,24 #else25 0,26 #endif27 #ifdef RLIMIT_RSS28 RLIMIT_RSS,29 #else30 0,31 #endif32 RLIMIT_NOFILE,33 RLIMIT_STACK,34 RLIMIT_CPU,35 #ifdef RLIMIT_NPROC36 RLIMIT_NPROC,37 #else38 0,39 #endif40 #ifdef RLIMIT_RSS41 RLIMIT_RSS,42 #else43 0,44 #endif45 };47 static void48 eusage(void)49 {50 fprint(mapfd(2), "usage: ulimit [-SHa%s [limit]]\n", eargs);51 }53 #define Notset -454 #define Unlimited -355 #define Hard -256 #define Soft -158 void59 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 }ARGEND88 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;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 else124 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 else138 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 }162 out:163 free(oargv);164 poplist();165 flush(err);166 }168 void169 execumask(void)170 {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++)180 ;182 ARGBEGIN{183 default:184 usage:185 fprint(mapfd(2), "usage: umask [mode]\n");186 goto out;187 }ARGEND189 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;198 }200 n = umask(0);201 umask(n);202 if(n < 0){203 fprint(mapfd(2), "umask: %r\n");204 goto out;205 }207 fprint(mapfd(1), "umask %03o\n", n);209 out:210 free(oargv);211 poplist();212 flush(err);213 }215 /*216 * Cope with non-blocking read.217 */218 long219 readnb(int fd, char *buf, long cnt)220 {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;233 }235 return n;236 }