121 lines
2.2 KiB
C
121 lines
2.2 KiB
C
/* cat.c -- program to concatenate input and stdin onto stdout. */
|
|
/* first version */
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "support.h"
|
|
|
|
|
|
char *cat(FILE *fp, const int mode, long unsigned *bufsize)
|
|
{
|
|
char c;
|
|
static long unsigned int i, finalbuflen, tmpbuflen;
|
|
char *arr, *tmparr, *finalarr;
|
|
tmpbuflen = 4096;
|
|
|
|
if(!mode)
|
|
{
|
|
arr = malloc(tmpbuflen);
|
|
tmparr = finalarr = 0;
|
|
|
|
for(i = 0, finalbuflen = 0; (c = fgetc(fp)) != EOF; i++, finalbuflen++)
|
|
{
|
|
if(i >= tmpbuflen)
|
|
{
|
|
tmpbuflen *= 2;
|
|
tmparr = malloc(tmpbuflen);
|
|
memcpy(tmparr, arr, tmpbuflen/2);
|
|
free(arr);
|
|
arr = tmparr;
|
|
}
|
|
|
|
arr[i] = c;
|
|
}
|
|
|
|
finalarr = malloc(finalbuflen);
|
|
memcpy(finalarr, arr, finalbuflen);
|
|
free(arr);
|
|
arr = finalarr;
|
|
*bufsize = finalbuflen;
|
|
return arr;
|
|
}
|
|
else
|
|
{
|
|
for(;(c = fgetc(fp)) != EOF;)
|
|
{
|
|
putchar(c);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
long unsigned int i, upresence, fppresence, buflen, newbuflen;
|
|
char *buf, *newbuf, *tmpbuf;
|
|
FILE *fp;
|
|
|
|
i = upresence = fppresence = buflen = newbuflen = 0;
|
|
buf = newbuf = tmpbuf = 0;
|
|
fp = 0;
|
|
|
|
|
|
switch( (upresence = getopt(argc, argv, "u")))
|
|
{
|
|
case 'u': i++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
for(i++;argv[i] != NULL; i++)
|
|
{
|
|
if(!strcmp(argv[i], "-"))
|
|
{
|
|
fppresence++;
|
|
newbuf = cat(fopen("/dev/stdin", "r"), upresence, &newbuflen);
|
|
}
|
|
else if((fp = fopen(argv[i], "r")) != NULL)
|
|
{
|
|
fppresence++;
|
|
newbuf = cat(fp, upresence, &newbuflen);
|
|
fclose(fp);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "%s: failed to open %s. Aborting.\n", argv[0], argv[i]);
|
|
exit(1);
|
|
}
|
|
|
|
/* This is where the actual magic happens. */
|
|
if(!upresence)
|
|
{
|
|
/* Here, we copy buf and newbuf end-to-end into a new buffer of size buflen+newbuflen, then store that in buflen and */
|
|
/* return a pointer to the new buffer. */
|
|
tmpbuf = arrccat(buf, newbuf, &buflen, newbuflen);
|
|
free(buf);
|
|
buf = tmpbuf;
|
|
}
|
|
|
|
}
|
|
|
|
if(!fppresence)
|
|
{
|
|
buf = cat(fopen("/dev/stdin", "r"), upresence, &buflen);
|
|
}
|
|
|
|
if(!upresence)
|
|
{
|
|
for(i = 0; i < buflen; i++)
|
|
{
|
|
putchar(buf[i]);
|
|
}
|
|
}
|
|
|
|
exit(0);
|
|
}
|