URI:
       tunixcrap.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tunixcrap.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 }