Annotation of researchv10no/cmd/limiter.c, revision 1.1.1.1

1.1       root        1: #include <sys/types.h>
                      2: #include <sys/filio.h>
                      3: #include <stdio.h>
                      4: #include <sys/stream.h>
                      5: 
                      6: extern int conn_ld;
                      7: extern int mesg_ld;
                      8: #define        msglen(mp)      ((mp)->losize + ((mp)->hisize<<8))
                      9: 
                     10: int count;             /* max connections */
                     11: fd_set serving;                /* clients being served */
                     12: int nserving;
                     13: fd_set waiting;                /* clients waiting */
                     14: int nwaiting;
                     15: int fd;                        /* mounted fd */
                     16: 
                     17: 
                     18: main(ac, av)
                     19:        int ac;
                     20:        char *av[];
                     21: {
                     22:        if(ac!=3)
                     23:                die("usage: %s path count\n", av[0]);
                     24:        fd=mountit(av[1]);
                     25:        count=atoi(av[2]);
                     26:        if(count<=0)
                     27:                die("usage: %s path count\n", av[0]);
                     28:        detach();
                     29:        doit();
                     30: }
                     31: 
                     32: doit()
                     33: {
                     34:        int i, n;
                     35:        fd_set afds;
                     36: 
                     37:        FD_ZERO(serving);
                     38:        for(;;){
                     39:                afds=serving;
                     40:                FD_SET(fd, afds);
                     41:                switch(n=select(NOFILE, &afds, 0, 10000L)){
                     42:                case -1:
                     43:                        /* there's a bad fd in the group */
                     44:                        afds=serving;
                     45:                        for(i=0; i<NOFILE; i++)
                     46:                                if(FD_ISSET(i, afds))
                     47:                                        dropclient(i);
                     48:                        break;
                     49:                case 0:
                     50:                        /* timeout, try again */
                     51:                        break;
                     52:                default:
                     53:                        /* look for new clients */
                     54:                        if(FD_ISSET(fd, afds)){
                     55:                                request();
                     56:                                n--;
                     57:                        }
                     58: 
                     59:                        /* someone needs servicing */
                     60:                        for(i=0; n && i<NOFILE; i++){
                     61:                                if(FD_ISSET(i, afds)){
                     62:                                        dropclient(i);
                     63:                                        n--;
                     64:                                }
                     65:                        }
                     66:                        break;
                     67:                }
                     68:        }
                     69: }
                     70: 
                     71: newclient(cfd)
                     72:        int cfd;
                     73: {
                     74:        FD_SET(cfd, waiting);
                     75:        nwaiting++;
                     76:        wtos();
                     77: }
                     78: 
                     79: dropclient(cfd)
                     80:        int cfd;
                     81: {
                     82:        FD_CLR(cfd, serving);
                     83:        nserving--;
                     84:        close(cfd);
                     85:        wtos();
                     86: }
                     87: 
                     88: wtos()
                     89: {
                     90:        int i=0;
                     91:        struct mesg m;
                     92: 
                     93:        while(nwaiting && nserving<count){
                     94:                for(;i<NOFILE;i++){
                     95:                        if(FD_ISSET(i,waiting)){
                     96:                                nwaiting--;
                     97:                                nserving++;
                     98:                                FD_SET(i, serving);
                     99:                                FD_CLR(i, waiting);
                    100:                                m.losize = 0;
                    101:                                m.hisize = 0 >> 8;
                    102:                                m.type = M_HANGUP;
                    103:                                m.magic = MSGMAGIC;
                    104:                                if(ioctl(i, FIOACCEPT, (void *)0)<0
                    105:                                || ioctl(i, FIOPUSHLD, &mesg_ld)<0
                    106:                                || write(i, &m, sizeof(m))!=sizeof(m)){
                    107:                                        close(i);
                    108:                                        FD_CLR(i, serving);
                    109:                                        nserving--;
                    110:                                        continue;
                    111:                                }
                    112:                        }
                    113:                }
                    114:        }
                    115: }
                    116: 
                    117: request()
                    118: {
                    119:        struct passfd pass;
                    120: 
                    121:        if(ioctl(fd, FIORCVFD, &pass)<0)
                    122:                abort();
                    123:        newclient(pass.fd);
                    124: }
                    125: 
                    126: mountit(path)
                    127:        char *path;
                    128: {
                    129:        int pfd[2];
                    130: 
                    131:        /* make a node to mount onto */
                    132:        if (access(path,0)<0 && creat(path, 0666)<0)
                    133:                die("can't creat %s\n", path);
                    134: 
                    135:        /* get the stream to mount */
                    136:        if (pipe(pfd) < 0)
                    137:                die("out of pipes\n", 0);
                    138:        if (ioctl(pfd[1], FIOPUSHLD, &conn_ld) < 0)
                    139:                die("can't push line discipline\n", 0);
                    140: 
                    141:        /* mount */
                    142:        if (fmount(3, pfd[1], path, 0) < 0)
                    143:                die("can't mount onto %s\n", path);
                    144:        umask(0);
                    145:        chmod(path, 0666);
                    146:        close(pfd[1]);
                    147:        return pfd[0];
                    148: }
                    149: 
                    150: detach()
                    151: {
                    152:        switch(fork()){
                    153:        case -1:
                    154:                die("can't fork\n", 0);
                    155:        case 0:
                    156:                break;
                    157:        default:
                    158:                exit(0);
                    159:        }
                    160:        for(fd=0; fd<NSYSFILE; fd++)
                    161:                close(fd);
                    162:        setpgrp(getpid(), getpid());
                    163: }
                    164: 
                    165: die(a, b)
                    166:        char *a;
                    167: {
                    168:        fprintf(stderr, a, b);
                    169:        exit(1);
                    170: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.