Luna/apps/src/cat.c
2022-10-26 20:51:20 +02:00

62 lines
1.6 KiB
C

#define _GNU_SOURCE // for program_invocation_name
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
void cat(FILE* stream)
{
struct stat statbuf;
fstat(fileno(stream), &statbuf);
if (statbuf.st_mode == __VFS_DEVICE) // FIXME: Add S_ISDEV.
{
char buf[4096]; // FIXME: Do not limit ourselves to 4096 bytes. Devices which can't seek and are constant should
// return EOF after the first read.
fgets(buf, 4096, stream);
if (ferror(stream))
{
perror(program_invocation_name);
exit(EXIT_FAILURE);
}
if (feof(stream)) return;
fputs(buf, stdout);
return;
}
char buf[BUFSIZ];
do {
fgets(buf, BUFSIZ, stream);
if (ferror(stream))
{
perror(program_invocation_name);
exit(EXIT_FAILURE);
}
fputs(buf, stdout);
} while (!feof(stream));
}
int main(int argc, char** argv)
{
if (argc == 1) cat(stdin);
else
{
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "-") == 0) cat(stdin);
else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--newline") == 0)
putchar('\n');
else
{
FILE* stream = fopen(argv[i], "r");
if (!stream)
{
perror(program_invocation_name);
return EXIT_FAILURE;
}
cat(stream);
fclose(stream);
}
}
}
}