Add POSIX implementation of cat(1) (it's really bad.).master
parent
1ac44c03b7
commit
209c0401de
@ -1 +1 @@
|
||||
2021/11/23 - Added true and false, as well as a skeleton for wc. Created LOG.
|
||||
2021/11/23 - Added true and false, as well as a skeleton for wc. Created LOG.
|
||||
|
@ -0,0 +1,24 @@
|
||||
.POSIX:
|
||||
.SUFFIXES:
|
||||
CC = cc
|
||||
CFLAGS = -Wall -O2
|
||||
LDFLAGS = -static
|
||||
LDLIBS =
|
||||
PREFIX = /usr/local/bin/
|
||||
DESTDIR =
|
||||
|
||||
all: echo wc yes true false cat
|
||||
echo: echo.c
|
||||
wc: wc.c
|
||||
yes: yes.c
|
||||
true: true.c
|
||||
false:
|
||||
ln -s true false
|
||||
cat: cat.c
|
||||
|
||||
clean:
|
||||
rm echo true wc yes false cat
|
||||
|
||||
.SUFFIXES: .c .o
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -c $<
|
@ -0,0 +1,112 @@
|
||||
/* cat.c -- provides a routine to output the contents of the named files in either a buffered or unbuffered fashion. */
|
||||
/* Accepts the following parameters: */
|
||||
/* -u: Output should be unbuffered. */
|
||||
|
||||
/* Returns the following values: */
|
||||
/* 0: All files were printed successfully. */
|
||||
/* 1: One or more files could not be opened. */
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* If mode is set to zero, return a null pointer and print characters directly. Otherwise, return a pointer to a buffer containing */
|
||||
/* the contents of the file pointed to by fp. */
|
||||
char *cat(FILE *fp, const int mode)
|
||||
{
|
||||
char c;
|
||||
|
||||
if(!mode)
|
||||
{
|
||||
int i, buflen;
|
||||
buflen = 4096;
|
||||
char *arr = malloc(4096);
|
||||
char *newarr = 0;
|
||||
|
||||
for(i = 0; (c = fgetc(fp)) != EOF; i++)
|
||||
{
|
||||
if(i >= buflen)
|
||||
{
|
||||
buflen *= 2;
|
||||
newarr = malloc(buflen);
|
||||
strcpy(newarr, arr);
|
||||
free(arr);
|
||||
arr = newarr;
|
||||
}
|
||||
|
||||
arr[i] = c;
|
||||
}
|
||||
arr[i] = '\0';
|
||||
|
||||
return arr;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(;(c = fgetc(fp)) != EOF;)
|
||||
{
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *buf, *newbuf, *tmpbuf;
|
||||
int i, upresence, fppresence;
|
||||
i = upresence = fppresence = 0;
|
||||
long unsigned int buflen;
|
||||
buflen = 4096;
|
||||
FILE *fp;
|
||||
fp = 0;
|
||||
buf = malloc(buflen);
|
||||
|
||||
if((upresence = (getopt(argc, argv, ":u") == 'u')))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
for(i++;argv[i] != NULL; i++)
|
||||
{
|
||||
if(!strcmp(argv[i], "-"))
|
||||
{
|
||||
fppresence++;
|
||||
newbuf = cat(fopen("/dev/stdin", "r"), upresence);
|
||||
}
|
||||
else if((fp = fopen(argv[i], "r")) != NULL)
|
||||
{
|
||||
fppresence++;
|
||||
newbuf = cat(fp, upresence);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: failed to open %s. Aborting.\n", argv[0], argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!upresence and (2 * (strlen(buf) + strlen(newbuf)) >= buflen))
|
||||
{
|
||||
tmpbuf = malloc(2 * (strlen(buf) + strlen(newbuf)));
|
||||
strcpy(tmpbuf, buf);
|
||||
free(buf);
|
||||
buf = tmpbuf;
|
||||
}
|
||||
|
||||
if(!upresence)
|
||||
{
|
||||
strcat(buf, newbuf);
|
||||
}
|
||||
}
|
||||
|
||||
if(!fppresence)
|
||||
{
|
||||
buf = cat(fopen("/dev/stdin", "r"), upresence);
|
||||
}
|
||||
|
||||
if(!upresence)
|
||||
{
|
||||
printf("%s", buf);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <iso646.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
Loading…
Reference in new issue