Minix1.5/commands/cat.c

Compare this file to the similar file:
Show the results in this format:

/* 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);
}