unixcrap.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) 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 }