plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }