forked from bonsai/harakit
tail(1p): segfaults for some reason lol
This commit is contained in:
parent
1d2a9c2521
commit
0e4faead44
87
src/tail.c
87
src/tail.c
@ -22,26 +22,78 @@
|
|||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "yac.h"
|
#include "yac.h"
|
||||||
|
|
||||||
void tail(FILE *file, bool c, bool f, long num) {
|
void tailc(FILE *file, long num) {
|
||||||
long offset;
|
int byte;
|
||||||
if (c) { fseek(file, offset, SEEK_END); }
|
char buf[num];
|
||||||
else {
|
long offset = -num;
|
||||||
for
|
|
||||||
|
fseek(file, offset, SEEK_END);
|
||||||
|
for (int i = 0; (byte = fgetc(file)) != EOF; i++) {
|
||||||
|
buf[i] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fputs(buf, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tailf(FILE *file) {
|
||||||
|
int byte;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if ((byte = fgetc(file)) != EOF) { putchar(byte); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tailn(FILE *file, long num) {
|
||||||
|
char *buf = calloc(4096, 1);
|
||||||
|
char *lines[num];
|
||||||
|
int byte;
|
||||||
|
int lc = 0;
|
||||||
|
|
||||||
|
for (int bc = 0; (byte = fgetc(file)) != EOF; bc++) {
|
||||||
|
if (bc == sizeof(buf)) {
|
||||||
|
int err;
|
||||||
|
if (err = realloc(buf, sizeof(buf) * 2) == NULL) {
|
||||||
|
// TODO: error handling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[bc] = byte;
|
||||||
|
|
||||||
|
if (byte == '\n') {
|
||||||
|
lines[lc] = buf;
|
||||||
|
bc = 0;
|
||||||
|
lc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lc == num) {
|
||||||
|
for (int i = 0; i < lc; i++) {
|
||||||
|
lines[i] = lines[i + 1];
|
||||||
|
}
|
||||||
|
lc--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
if ((i = lc - num) < 0) { i = 0; }
|
||||||
|
|
||||||
|
for (; i < lc; i++) {
|
||||||
|
fputs(lines[i], stdout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
bool c = false;
|
bool c = false;
|
||||||
bool f = false;
|
bool f = false;
|
||||||
bool n = false;
|
bool n = false;
|
||||||
long num;
|
|
||||||
int opt;
|
|
||||||
int i;
|
int i;
|
||||||
|
int opt;
|
||||||
|
long num;
|
||||||
|
void (*fn)(FILE *, long) = tailn;
|
||||||
|
|
||||||
extern int optind;
|
extern int optind;
|
||||||
while ((opt = getopt(argc, argv, "c:fn:")) != -1) {
|
while ((opt = getopt(argc, argv, "c:fn:")) != -1) {
|
||||||
@ -87,6 +139,7 @@ int main(int argc, char *argv[]) {
|
|||||||
*/
|
*/
|
||||||
case 'c':
|
case 'c':
|
||||||
c = true;
|
c = true;
|
||||||
|
fn = tailc;
|
||||||
num = (long)optarg;
|
num = (long)optarg;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
@ -116,19 +169,21 @@ int main(int argc, char *argv[]) {
|
|||||||
return EX_USAGE;
|
return EX_USAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind = argc) {
|
|
||||||
tail(stdin, c, f, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
|
if (optind = argc) {
|
||||||
|
fn(stdin, num);
|
||||||
|
|
||||||
|
if (f) { tailf(stdin); }
|
||||||
|
} else {
|
||||||
for (i = optind; i < argc; i++) {
|
for (i = optind; i < argc; i++) {
|
||||||
file = rfile(argv0, argv[i]);
|
if ((file = rpath(argv[0], argv[i])) != NULL) {
|
||||||
if file != NULL {
|
fn(file, num);
|
||||||
tail(file, c, f, num);
|
fclose(file);
|
||||||
if (file != stdin) { fclose(file); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f) { tailf(file); }
|
||||||
|
}
|
||||||
|
}
|
||||||
return EX_OK;
|
return EX_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user