00001
00002
00003
00004
00005
00006
00007 #include <errno.h>
00008 #include <sys/types.h>
00009 #include <fcntl.h>
00010 #include <string.h>
00011 #include <unistd.h>
00012 #include <stdlib.h>
00013 #include <minix/minlib.h>
00014 #include <stdio.h>
00015
00016 #define CHUNK_SIZE (2048 * sizeof(char *))
00017
00018 static int unbuffered;
00019 static char ibuf[CHUNK_SIZE];
00020 static char obuf[CHUNK_SIZE];
00021 static char *op = obuf;
00022
00023 int main(int argc, char **argv);
00024 static void copyout(char *file, int fd);
00025 static void output(char *buf, size_t count);
00026 static void report(char *label);
00027 static void fatal(char *label);
00028
00029 static char STDIN[] = "standard input";
00030 static char STDOUT[] = "standard output";
00031
00032 static int excode = 0;
00033
00034 int main(int argc, char *argv[])
00035 {
00036 int i, fd;
00037
00038 i = 1;
00039 while (i < argc && argv[i][0] == '-') {
00040 char *opt = argv[i] + 1;
00041
00042 if (opt[0] == 0) break;
00043 i++;
00044 if (opt[0] == '-' && opt[1] == 0) break;
00045
00046 while (*opt != 0) switch (*opt++) {
00047 case 'u':
00048 unbuffered = 1;
00049 break;
00050 default:
00051 std_err("Usage: cat [-u] [file ...]\n");
00052 exit(1);
00053 }
00054 }
00055
00056 if (i >= argc) {
00057 copyout(STDIN, STDIN_FILENO);
00058 } else {
00059 while (i < argc) {
00060 char *file = argv[i++];
00061
00062 if (file[0] == '-' && file[1] == 0) {
00063 copyout(STDIN, STDIN_FILENO);
00064 } else {
00065 fd = open(file, O_RDONLY);
00066 if (fd < 0) {
00067 report(file);
00068 } else {
00069 copyout(file, fd);
00070 close(fd);
00071 }
00072 }
00073 }
00074 }
00075 output(obuf, (op - obuf));
00076 return(excode);
00077 }
00078
00079 static void copyout(char *file, int fd)
00080 {
00081 int n;
00082
00083 while (1) {
00084 n = read(fd, ibuf, CHUNK_SIZE);
00085 if (n < 0) fatal(file);
00086 if (n == 0) return;
00087 if (unbuffered || (op == obuf && n == CHUNK_SIZE)) {
00088 output(ibuf, n);
00089 } else {
00090 int bytes_left;
00091
00092 bytes_left = &obuf[CHUNK_SIZE] - op;
00093 if (n <= bytes_left) {
00094 memcpy(op, ibuf, (size_t)n);
00095 op += n;
00096 } else {
00097 memcpy(op, ibuf, (size_t)bytes_left);
00098 output(obuf, CHUNK_SIZE);
00099 n -= bytes_left;
00100 memcpy(obuf, ibuf + bytes_left, (size_t)n);
00101 op = obuf + n;
00102 }
00103 }
00104 }
00105 }
00106
00107 static void output(char *buf, size_t count)
00108 {
00109 ssize_t n;
00110
00111 while (count > 0) {
00112 n = write(STDOUT_FILENO, buf, count);
00113 if (n <= 0) {
00114 if (n < 0) fatal(STDOUT);
00115 std_err("cat: standard output: EOF\n");
00116 exit(1);
00117 }
00118 buf += n;
00119 count -= n;
00120 }
00121 }
00122
00123 static void report(char *label)
00124 {
00125 int e = errno;
00126 std_err("cat: ");
00127 std_err(label);
00128 std_err(": ");
00129 std_err(strerror(e));
00130 std_err("\n");
00131 excode = 1;
00132 }
00133
00134 static void fatal(char *label)
00135 {
00136 report(label);
00137 exit(1);
00138 }