93 lines
1.7 KiB
C
93 lines
1.7 KiB
C
/* cat - concatenates files Author: Andy Tanenbaum */
|
|
|
|
/* 30 March 90 - Slightly modified for efficiency by Norbert Schlenker. */
|
|
|
|
|
|
#include <blocksize.h>
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
static int unbuffered;
|
|
static char ibuf[BLOCK_SIZE];
|
|
static char obuf[BLOCK_SIZE];
|
|
static char *op = obuf;
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
int i, fd;
|
|
|
|
i = 1;
|
|
/* Check for the -u flag -- unbuffered operation. */
|
|
if (argc >= 2 && argv[1][0] == '-' && argv[1][1] == 'u' && argv[1][2] == 0) {
|
|
unbuffered = 1;
|
|
i = 2;
|
|
}
|
|
if (i >= argc) {
|
|
copyfile(STDIN_FILENO, STDOUT_FILENO);
|
|
} else {
|
|
for ( ; i < argc; i++) {
|
|
if (argv[i][0] == '-' && argv[i][1] == 0) {
|
|
copyfile(STDIN_FILENO, STDOUT_FILENO);
|
|
} else {
|
|
fd = open(argv[i], O_RDONLY);
|
|
if (fd < 0) {
|
|
std_err("cat: cannot open ");
|
|
std_err(argv[i]);
|
|
std_err("\n");
|
|
} else {
|
|
copyfile(fd, STDOUT_FILENO);
|
|
close(fd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
flush();
|
|
exit(0);
|
|
}
|
|
|
|
copyfile(ifd, ofd)
|
|
int ifd, ofd;
|
|
{
|
|
int n;
|
|
|
|
while (1) {
|
|
n = read(ifd, ibuf, BLOCK_SIZE);
|
|
if (n < 0) fatal();
|
|
if (n == 0) return;
|
|
if (unbuffered || (op == obuf && n == BLOCK_SIZE)) {
|
|
if (write(ofd, ibuf, n) != n) fatal();
|
|
} else {
|
|
int bytes_left;
|
|
|
|
bytes_left = &obuf[BLOCK_SIZE] - op;
|
|
if (n <= bytes_left) {
|
|
memcpy(op, ibuf, n);
|
|
op += n;
|
|
} else {
|
|
memcpy(op, ibuf, bytes_left);
|
|
if (write(ofd, obuf, BLOCK_SIZE) != BLOCK_SIZE)
|
|
fatal();
|
|
n -= bytes_left;
|
|
memcpy(obuf, ibuf + bytes_left, n);
|
|
op = obuf + n;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
flush()
|
|
{
|
|
if (op != obuf)
|
|
if (write(STDOUT_FILENO, obuf, (size_t) (op - obuf)) <= 0) fatal();
|
|
}
|
|
|
|
fatal()
|
|
{
|
|
perror("cat");
|
|
exit(1);
|
|
}
|