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_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 }