*/ void Trim_String(REBSER *ser, REBCNT index, REBCNT len, REBCNT flags, REBVAL *with) /* ***********************************************************************/ { REBCNT tail = index + len; // /all or /with if (flags & (AM_TRIM_ALL | AM_TRIM_WITH)) { replace_with(ser, index, tail, with); } // /auto option else if (flags & AM_TRIM_AUTO) { trim_auto(ser, index, tail); } // /lines option else if (flags & AM_TRIM_LINES) { trim_lines(ser, index, tail); } else { trim_head_tail(ser, index, tail, flags & AM_TRIM_HEAD, flags & AM_TRIM_TAIL); } }
int main(int argc, char *argv[]) { char *filename, *buffer; int filelen, nlines, bufsize, tlines, nlen, fd; char opt; ssize_t n; nlines = DEFAULT_LINES; while ((opt = getopt(argc, argv, "n:")) != -1) { switch(opt) { case 'n': nlines = atoi(optarg); break; default: fprintf(stderr, "Usage: mtail [-n <lines>] <filename>\n"); exit(EXIT_FAILURE); } } if (optind < argc) { nlen = strlen(argv[optind]); filename = malloc(nlen + 1); strncpy(filename, argv[optind], nlen + 1); fd = open(filename, O_RDONLY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } } else { fprintf(stderr, "Usage: mtail [-n <lines>] <filename>\n"); exit(EXIT_FAILURE); } if ((filelen = (int)lseek(fd, 0, SEEK_END)) == -1) { perror("lseek"); exit(EXIT_FAILURE); } bufsize = BUFSIZE; while (1) { bufsize = min(bufsize, filelen); if (lseek(fd, -bufsize, SEEK_END) == -1) { perror("lseek"); exit(EXIT_FAILURE); } buffer = alloca(bufsize + 1); n = read(fd, buffer, bufsize); buffer[n] = '\0'; tlines = get_line_count(buffer); if (tlines >= nlines || filelen == bufsize) { if (nlines < tlines) buffer = trim_lines(buffer, nlines, tlines); write(STDOUT_FILENO, buffer, strlen(buffer)); break; } bufsize *= 2; } exit(EXIT_SUCCESS); }