Annotation of researchv9/cmd/tail.c, revision 1.1.1.1

1.1       root        1: /* tail command 
                      2:  *
                      3:  *     tail where [file]
                      4:  *     where is +_n[type]
                      5:  *     - means n lines before end
                      6:  *     + means nth line from beginning
                      7:  *     type 'b' means tail n blocks, not lines
                      8:  *     type 'c' means tail n characters
                      9:  *     Type 'r' means in lines in reverse order from end
                     10:  *      (for -r, default is entire buffer )
                     11:  *     option 'f' means loop endlessly trying to read more
                     12:  *             characters after the end of file, on the  assumption
                     13:  *             that the file is growing
                     14: */
                     15: 
                     16: #include       <stdio.h>
                     17: #include       <ctype.h>
                     18: #include       <sys/types.h>
                     19: #include       <sys/stat.h>
                     20: #include       <errno.h>
                     21: 
                     22: #define LBIN 16383
                     23: struct stat    statb;
                     24: int    follow;
                     25: int    piped;
                     26: char   bin[LBIN];
                     27: int    errno;
                     28: int    infd = 0;
                     29: 
                     30: main(argc,argv)
                     31: char **argv;
                     32: {
                     33:        long n,di;
                     34:        register i,j,k;
                     35:        char *arg;
                     36:        int partial,bylines,bkwds,fromend,lastnl;
                     37:        char *p;
                     38:        int anydigit = 0;
                     39: 
                     40:        arg = argv[1];
                     41:        if(argc<=1 || *arg!='-'&&*arg!='+') {
                     42:                arg = "-10l";
                     43:                argc++;
                     44:                argv--;
                     45:        }
                     46:        n = 0;
                     47:        fromend = *arg=='-';
                     48:        arg++;
                     49:        while(isdigit(*arg)) {
                     50:                anydigit++;
                     51:                n = n*10 + *arg++ - '0';
                     52:        }
                     53:        if(!fromend&&n>0)
                     54:                n--;
                     55:        if(argc>2) {
                     56:                if((infd = open(argv[2],0))<0) {
                     57:                        perror(argv[2]);
                     58:                        exit(1);
                     59:                }
                     60:        }
                     61:        lseek(infd,(long)0,1);
                     62:        piped = errno==ESPIPE;
                     63:        bylines = -1; bkwds = 0;
                     64:        while(*arg)
                     65:        switch(*arg++) {
                     66: 
                     67:        case 'b':
                     68:                n *= BUFSIZ;
                     69:                if(bylines!=-1) goto errcom;
                     70:                bylines=0;
                     71:                break;
                     72:        case 'c':
                     73:                if(bylines!=-1) goto errcom;
                     74:                bylines=0;
                     75:                break;
                     76:        case 'f':
                     77:                follow = 1;
                     78:                break;
                     79:        case 'r':
                     80:                if(!anydigit) n = LBIN;
                     81:                bkwds = 1; fromend = 1; bylines = 1;
                     82:                break;
                     83:        case 'l':
                     84:                if(bylines!=-1) goto errcom;
                     85:                bylines = 1;
                     86:                break;
                     87:        default:
                     88:                goto errcom;
                     89:        }
                     90:         if(fromend && !bkwds && !anydigit) n = 10;
                     91:        if(bylines==-1) bylines = 1;
                     92:        if(bkwds) follow=0;
                     93:        if(fromend)
                     94:                goto keep;
                     95: 
                     96:                        /*seek from beginning */
                     97: 
                     98:        if(bylines) {
                     99:                j = 0;
                    100:                while(n-->0) {
                    101:                        do {
                    102:                                if(j--<=0) {
                    103:                                        p = bin;
                    104:                                        j = read(infd,p,BUFSIZ);
                    105:                                        if(j--<=0)
                    106:                                                fexit();
                    107:                                }
                    108:                        } while(*p++ != '\n');
                    109:                }
                    110:                if(j>0)
                    111:                        zwrite(1,p,j);
                    112:        } else  if(n>0) {
                    113:                if(!piped)
                    114:                        fstat(infd,&statb);
                    115:                if(piped||(statb.st_mode&S_IFMT)==S_IFCHR)
                    116:                        while(n>0) {
                    117:                                i = n>BUFSIZ?BUFSIZ:n;
                    118:                                i = read(infd,bin,i);
                    119:                                if(i<=0)
                    120:                                        fexit();
                    121:                                n -= i;
                    122:                        }
                    123:                else
                    124:                        lseek(infd,n,0);
                    125:        }
                    126: copy:
                    127:        while((i=read(infd,bin,BUFSIZ))>0)
                    128:                zwrite(1,bin,i);
                    129:        fexit();
                    130: 
                    131:                        /*seek from end*/
                    132: 
                    133: keep:
                    134:        if(n <= 0) {
                    135:                lseek(infd,0L,2);
                    136:                fexit();
                    137:        }
                    138:        if(!piped) {
                    139:                fstat(infd,&statb);
                    140:                di = !bylines&&n<LBIN?n:LBIN-1;
                    141:                if(statb.st_size > di)
                    142:                        lseek(infd,-di,2);
                    143:                if(!bylines)
                    144:                        goto copy;
                    145:        }
                    146:        partial = 1;
                    147:        for(;;) {
                    148:                i = 0;
                    149:                do {
                    150:                        j = read(infd,&bin[i],LBIN-i);
                    151:                        if(j<=0)
                    152:                                goto brka;
                    153:                        i += j;
                    154:                } while(i<LBIN);
                    155:                partial = 0;
                    156:        }
                    157: brka:
                    158:        if(!bylines) {
                    159:                k = n<=i ? i-n: partial ? 0: n>=LBIN ? i+1: i-n+LBIN;
                    160:                k--;
                    161:        } else {
                    162:                if(bkwds && bin[i==0?LBIN-1:i-1]!='\n'){        /* force trailing newline */
                    163:                        bin[i]='\n';
                    164:                        if(++i>=LBIN) {i = 0; partial = 0;}
                    165:                }
                    166:                k = i;
                    167:                j = 0;
                    168:                do {
                    169:                        lastnl = k;
                    170:                        do {
                    171:                                if(--k<0) {
                    172:                                        if(partial) {
                    173:                                                if(bkwds) zwrite(1,bin,lastnl+1);
                    174:                                                goto brkb;
                    175:                                        }
                    176:                                        k = LBIN -1;
                    177:                                }
                    178:                        } while(bin[k]!='\n'&&k!=i);
                    179:                        if(bkwds && j>0){
                    180:                                if(k<lastnl) zwrite(1,&bin[k+1],lastnl-k);
                    181:                                else {
                    182:                                        if(k<LBIN-1)
                    183:                                                zwrite(1,&bin[k+1],LBIN-k-1);
                    184:                                        zwrite(1,bin,lastnl+1);
                    185:                                }
                    186:                        }
                    187:                } while(j++<n&&k!=i);
                    188: brkb:
                    189:                if(bkwds) exit(0);
                    190:                if(k==i) do {
                    191:                        if(++k>=LBIN)
                    192:                                k = 0;
                    193:                } while(bin[k]!='\n'&&k!=i);
                    194:        }
                    195:        if(k<i)
                    196:                zwrite(1,&bin[k+1],i-k-1);
                    197:        else {
                    198:                if(k<LBIN-1)
                    199:                        zwrite(1,&bin[k+1],LBIN-k-1);
                    200:                if(i>0)
                    201:                        zwrite(1,bin,i);
                    202:        }
                    203:        fexit();
                    204: errcom:
                    205:        fprintf(stderr, "usage: tail [+_[n][lbc][rf]] [file]\n");
                    206:        exit(2);
                    207: }
                    208: 
                    209: fexit()
                    210: {      register int n;
                    211:        long amtread;
                    212:        if (!follow || piped) exit(0);
                    213:        amtread = lseek(infd, 0L, 1);
                    214:        for (;;) {
                    215:                sleep(5);
                    216:                if(fstat(infd, &statb) == -1)
                    217:                        exit(1);
                    218:                if(statb.st_size < amtread) {
                    219:                        fprintf(stderr, "tail: file truncated; restarting\n");
                    220:                        lseek(infd, 0L, 0);
                    221:                        amtread = 0;
                    222:                }
                    223:                while ((n = read (infd, bin, BUFSIZ)) > 0) {
                    224:                        zwrite (1, bin, n);
                    225:                        amtread += n;
                    226:                }
                    227:                if(n < 0)
                    228:                        exit(1);
                    229:        }
                    230: }
                    231: 
                    232: zwrite(f, b, n)
                    233: char *b;
                    234: {
                    235:        if (n!=0)
                    236:                write(f, b, n);
                    237: }

unix.superglobalmegacorp.com

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