From bb099036fbbecf718e4eb8333ffcb39049622cc4 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 23 Jul 2023 21:54:43 -0600 Subject: [PATCH 01/15] cat(1p), true(1p), false(1p): added source files & Makefile --- Makefile | 28 +++++++++++++++ src/cat.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/false.c | 21 ++++++++++++ src/true.c | 21 ++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 Makefile create mode 100644 src/cat.c create mode 100644 src/false.c create mode 100644 src/true.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7c1a847 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +# Copyright (c) 2023 YAC +# SPDX-License-Identifier: FSFAP +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice and this +# notice are preserved. This file is offered as-is, without any warranty. + +.POSIX: + +PREFIX=/usr/local/bin + +build: build_dir cat false true + +cat: build_dir + cc -o build/cat src/cat.c + +false: build_dir + cc -o build/false src/false.c + +true: build_dir + cc -o build/true src/true.c + +build_dir: + mkdir -p build + +install: build + mkdir -p $(PREFIX) + cp -f build/* $(PREFIX)/ diff --git a/src/cat.c b/src/cat.c new file mode 100644 index 0000000..74df7d5 --- /dev/null +++ b/src/cat.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023 YAC + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This file is part of YAC coreutils. + * + * YAC coreutils is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * YAC coreutils is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + int i = 1; + bool u = false; + + char *usage_text = "(-u) [file...]"; + int buf_size = strlen(argv[0]) + strlen("Usage: ") + strlen(usage_text) + 3; + char *usage = calloc(buf_size, buf_size); + + if (( + snprintf(usage, buf_size, "Usage: %s (-u) [file...]\n", argv[0]) + ) < 0 ) {} + + int opt; + + while ((opt = getopt(argc, argv, "u")) != -1) { + switch(opt) { + /* + * From cat(1p): + * + * -u Write bytes from the input file to the standard output + * without delay as each is read. + */ + case 'u': + i = 2; + u = true; + break; + default: + break; + } + } + + FILE *file; + + for (; i <= (argc - 1); i++) { + /* + * From cat(1p): + * + * file A pathname of an input file. If no file operands are + * specified, the standard input shall be used. If a file is + * '-', the cat utility shall read from the standard input at + * that point in the sequence. The cat utility shall not close + * and reopen standard input when it is referenced in this way, + * but shall accept multiple occurrences of '-' as a file + * operand. + */ + printf("argv[%d]: %s\n", i, argv[1]); + + if (argc == 1 || argv[i] == "-") { file = fdopen(1, "r"); } + else if ((file = fopen(argv[i], O_RDONLY)) == NULL) { + fputs(usage, stderr); + return EX_NOINPUT; + } + + int byte = 0; + + if (u) { + while (byte != EOF) { + byte = fgetc(file); + putchar(byte); + } + } else { + char *buf = calloc(4096, 1); + } + if (fclose(file) == -1) { + fprintf(stderr, "%s: %s: Error closing file.\n", argv[0], argv[i]); + return EX_OSERR; + } + } + + return EX_OK; +} diff --git a/src/false.c b/src/false.c new file mode 100644 index 0000000..d255a9a --- /dev/null +++ b/src/false.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 YAC + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This file is part of YAC coreutils. + * + * YAC coreutils is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * YAC coreutils is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + +int main() { return 1; } diff --git a/src/true.c b/src/true.c new file mode 100644 index 0000000..2791766 --- /dev/null +++ b/src/true.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 YAC + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This file is part of YAC coreutils. + * + * YAC coreutils is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * YAC coreutils is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + +int main() {} From 9adde985d9c590220eb4513dedb2ef5715631984 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 24 Jul 2023 09:01:41 -0600 Subject: [PATCH 02/15] fixed segfault --- src/cat.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cat.c b/src/cat.c index 74df7d5..1807acf 100644 --- a/src/cat.c +++ b/src/cat.c @@ -18,6 +18,7 @@ * along with this program. If not, see https://www.gnu.org/licenses/. */ +#include #include #include #include @@ -71,11 +72,12 @@ int main(int argc, char *argv[]) { * but shall accept multiple occurrences of '-' as a file * operand. */ - printf("argv[%d]: %s\n", i, argv[1]); - - if (argc == 1 || argv[i] == "-") { file = fdopen(1, "r"); } - else if ((file = fopen(argv[i], O_RDONLY)) == NULL) { - fputs(usage, stderr); + printf("argv[%d]: %s\n", i, argv[i]); + if (argv[i] == "-" || u && (argc - 1) == 1 || !u && argc == 1) { + file = fdopen(0, "r"); + } else if ((file = fopen(argv[i], "r")) == NULL) { + // TODO: Add error handling + fputs(usage, stderr); return EX_NOINPUT; } @@ -87,7 +89,11 @@ int main(int argc, char *argv[]) { putchar(byte); } } else { - char *buf = calloc(4096, 1); + char *buf = calloc(1, 4096); + while (byte != EOF) { + byte = fgetc(file); + fputc(byte, fdopen(1, "r")); + } } if (fclose(file) == -1) { fprintf(stderr, "%s: %s: Error closing file.\n", argv[0], argv[i]); From c8d6e9f5e4140cb6fcfad66748125e6dc6c0e7a8 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 7 Aug 2023 20:38:57 -0600 Subject: [PATCH 03/15] cat(1p): fix unbuffered output --- src/cat.c | 42 ++++++++++++------------------ trincat.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 trincat.c diff --git a/src/cat.c b/src/cat.c index 1807acf..250170d 100644 --- a/src/cat.c +++ b/src/cat.c @@ -28,9 +28,9 @@ #include int main(int argc, char *argv[]) { - int i = 1; bool u = false; - + int opt; + FILE *file; char *usage_text = "(-u) [file...]"; int buf_size = strlen(argv[0]) + strlen("Usage: ") + strlen(usage_text) + 3; char *usage = calloc(buf_size, buf_size); @@ -39,8 +39,7 @@ int main(int argc, char *argv[]) { snprintf(usage, buf_size, "Usage: %s (-u) [file...]\n", argv[0]) ) < 0 ) {} - int opt; - + extern int optind; while ((opt = getopt(argc, argv, "u")) != -1) { switch(opt) { /* @@ -50,17 +49,17 @@ int main(int argc, char *argv[]) { * without delay as each is read. */ case 'u': - i = 2; u = true; break; default: break; } } + argv += optind; + argc -= optind; - FILE *file; - - for (; i <= (argc - 1); i++) { + for (int i = 0; i < argc; i++) { + int byte = 0; /* * From cat(1p): * @@ -72,33 +71,24 @@ int main(int argc, char *argv[]) { * but shall accept multiple occurrences of '-' as a file * operand. */ - printf("argv[%d]: %s\n", i, argv[i]); - if (argv[i] == "-" || u && (argc - 1) == 1 || !u && argc == 1) { - file = fdopen(0, "r"); + if (argv[i] == "-" || argc == 0) { + file = stdin; } else if ((file = fopen(argv[i], "r")) == NULL) { // TODO: Add error handling fputs(usage, stderr); return EX_NOINPUT; } - int byte = 0; - - if (u) { - while (byte != EOF) { - byte = fgetc(file); + for (char *buf = calloc(4096, 1); byte != EOF; fputs(buf, stdout)) { + byte = fgetc(file); + if (u) { putchar(byte); - } - } else { - char *buf = calloc(1, 4096); - while (byte != EOF) { - byte = fgetc(file); - fputc(byte, fdopen(1, "r")); + } else { + snprintf(buf, 4096, "%c", byte); } } - if (fclose(file) == -1) { - fprintf(stderr, "%s: %s: Error closing file.\n", argv[0], argv[i]); - return EX_OSERR; - } + + if (file != stdin) { fclose(file); } } return EX_OK; diff --git a/trincat.c b/trincat.c new file mode 100644 index 0000000..7a3e389 --- /dev/null +++ b/trincat.c @@ -0,0 +1,78 @@ +#include /* maybe */ +#include /* no */ +#include /* sure */ +#include /* no */ +#include /* yes */ +#include /* yes */ +#include /* maybe */ +#include /* yes */ +#define BUF_SIZE 4096 + +unsigned char u = 0; /* unbuffered */ +unsigned char buf[BUF_SIZE]; + +void usage(char *argv0){ + fprintf(stderr, "Usage: %s (-u) (file...)\n", argv0); + exit(EX_USAGE); +} + +int main(int argc, char *argv[]) { + char *argv0; + extern int optind; + int c; + FILE *in; + argv0 = argv[0]; + + while ((c = getopt(argc, argv, "u")) != -1) { + switch(c) { + /* + * From cat(1p): + * + * -u Write bytes from the input file to the standard output + * without delay as each is read. + */ + case 'u': + u = 1; + break; + default: + usage(argv[0]); + } + } + + while(++argv != NULL) /* increments over argv[0] */ + /* + * From cat(1p): + * + * file A pathname of an input file. If no file operands are + * specified, the standard input shall be used. If a file is + * '-', the cat utility shall read from the standard input at + * that point in the sequence. The cat utility shall not close + * and reopen standard input when it is referenced in this way, + * but shall accept multiple occurrences of '-' as a file + * operand. + */ + if(argv[0][0] == '-' && argv[0][1] == '\0') in = stdin; + else if ((in = fopen(argv[0], "r")) == NULL) { + // TODO: Add error handling + usage(argv0); + return EX_NOINPUT; + } + + int byte = 0; + char *buf = calloc(4096, 1); + + while ((c = fgetc(in) != EOF)) { + if (u) { + putchar(c); + } else { + /* fucky wucky buffering */ + } + } + + if(!u) fputs(buf, stdout); + + if(in != stdin) fclose(file); /* who cares if it cant close */ + } + + return EX_OK; + } From 27a227e365798c87a4ae79bdf3e6cc36a462e32f Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 7 Aug 2023 20:39:32 -0600 Subject: [PATCH 04/15] trincat(1): removed file --- trincat.c | 78 ------------------------------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 trincat.c diff --git a/trincat.c b/trincat.c deleted file mode 100644 index 7a3e389..0000000 --- a/trincat.c +++ /dev/null @@ -1,78 +0,0 @@ -#include /* maybe */ -#include /* no */ -#include /* sure */ -#include /* no */ -#include /* yes */ -#include /* yes */ -#include /* maybe */ -#include /* yes */ -#define BUF_SIZE 4096 - -unsigned char u = 0; /* unbuffered */ -unsigned char buf[BUF_SIZE]; - -void usage(char *argv0){ - fprintf(stderr, "Usage: %s (-u) (file...)\n", argv0); - exit(EX_USAGE); -} - -int main(int argc, char *argv[]) { - char *argv0; - extern int optind; - int c; - FILE *in; - argv0 = argv[0]; - - while ((c = getopt(argc, argv, "u")) != -1) { - switch(c) { - /* - * From cat(1p): - * - * -u Write bytes from the input file to the standard output - * without delay as each is read. - */ - case 'u': - u = 1; - break; - default: - usage(argv[0]); - } - } - - while(++argv != NULL) /* increments over argv[0] */ - /* - * From cat(1p): - * - * file A pathname of an input file. If no file operands are - * specified, the standard input shall be used. If a file is - * '-', the cat utility shall read from the standard input at - * that point in the sequence. The cat utility shall not close - * and reopen standard input when it is referenced in this way, - * but shall accept multiple occurrences of '-' as a file - * operand. - */ - if(argv[0][0] == '-' && argv[0][1] == '\0') in = stdin; - else if ((in = fopen(argv[0], "r")) == NULL) { - // TODO: Add error handling - usage(argv0); - return EX_NOINPUT; - } - - int byte = 0; - char *buf = calloc(4096, 1); - - while ((c = fgetc(in) != EOF)) { - if (u) { - putchar(c); - } else { - /* fucky wucky buffering */ - } - } - - if(!u) fputs(buf, stdout); - - if(in != stdin) fclose(file); /* who cares if it cant close */ - } - - return EX_OK; - } From b360b823aca1907bbf5c1df63e4ffbdfe4779527 Mon Sep 17 00:00:00 2001 From: emma Date: Thu, 10 Aug 2023 15:24:07 -0600 Subject: [PATCH 05/15] cat(1p): made simpler, added error handling --- src/cat.c | 60 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/src/cat.c b/src/cat.c index 250170d..455765f 100644 --- a/src/cat.c +++ b/src/cat.c @@ -30,18 +30,12 @@ int main(int argc, char *argv[]) { bool u = false; int opt; + int i = 1; FILE *file; - char *usage_text = "(-u) [file...]"; - int buf_size = strlen(argv[0]) + strlen("Usage: ") + strlen(usage_text) + 3; - char *usage = calloc(buf_size, buf_size); - - if (( - snprintf(usage, buf_size, "Usage: %s (-u) [file...]\n", argv[0]) - ) < 0 ) {} extern int optind; while ((opt = getopt(argc, argv, "u")) != -1) { - switch(opt) { + switch (opt) { /* * From cat(1p): * @@ -52,14 +46,15 @@ int main(int argc, char *argv[]) { u = true; break; default: - break; + printf("Usage: %s (-u) file...\n", argv[0]); + return EX_USAGE; } } - argv += optind; - argc -= optind; - for (int i = 0; i < argc; i++) { - int byte = 0; + for (i = optind; i < argc; i++) { + int byte = 0; // variable for storing bytes as they are read + char buf[4096]; // buffer for buffered + int p = 0; // index counter for bytes in buffered reading /* * From cat(1p): * @@ -71,23 +66,50 @@ int main(int argc, char *argv[]) { * but shall accept multiple occurrences of '-' as a file * operand. */ - if (argv[i] == "-" || argc == 0) { + if (argv[i] == "-" || argc == 1) { file = stdin; } else if ((file = fopen(argv[i], "r")) == NULL) { - // TODO: Add error handling - fputs(usage, stderr); - return EX_NOINPUT; + switch (errno) { + case EACCES: + printf("%s: %s: Permission denied.\n", argv[0], argv[i]); + return EX_NOINPUT; + case EISDIR: + printf("%s: %s: Is a directory.\n", argv[0], argv[i]); + return EX_NOINPUT; + case ELOOP: + printf("%s: %s: Is a symbolic link loop.\n", argv[0], argv[i]); + return EX_UNAVAILABLE; + case EMFILE: + printf("%s: Internal error.\n", argv[0]); + return EX_SOFTWARE; + case ENOENT: case ENOTDIR: case ENXIO: + printf("%s: %s: No such file or directory.\n", argv[0], argv[i]); + return EX_NOINPUT; + default: + printf("%s: Unknown error.\n", argv[0]); + return EX_UNAVAILABLE; + } } - for (char *buf = calloc(4096, 1); byte != EOF; fputs(buf, stdout)) { + while (byte != EOF) { byte = fgetc(file); + if (u) { putchar(byte); } else { - snprintf(buf, 4096, "%c", byte); + if (p > sizeof(buf)) { + fputs(buf, stdout); + p = 0; + } + + buf[p] = byte; + p += 1; } } + fputs(buf, stdout); + fflush(stdout); + if (file != stdin) { fclose(file); } } From e530f10cd595b50a3c5809fa1b9ce6262588137e Mon Sep 17 00:00:00 2001 From: emma Date: Thu, 10 Aug 2023 15:34:02 -0600 Subject: [PATCH 06/15] cat(1p): fixed write buffering --- src/cat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cat.c b/src/cat.c index 455765f..11876f3 100644 --- a/src/cat.c +++ b/src/cat.c @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) { } } - fputs(buf, stdout); + fwrite(buf, 1, p, stdout); fflush(stdout); if (file != stdin) { fclose(file); } From da2ebdb1e1dcc8607c4fe4919ee66ea021ba032c Mon Sep 17 00:00:00 2001 From: emma Date: Thu, 10 Aug 2023 20:10:30 -0600 Subject: [PATCH 07/15] cat(1p): small reformatting --- Makefile | 3 +++ src/cat.c | 12 +++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 7c1a847..887aefd 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,9 @@ PREFIX=/usr/local/bin build: build_dir cat false true +clean: build_dir + rm -rf build/ + cat: build_dir cc -o build/cat src/cat.c diff --git a/src/cat.c b/src/cat.c index 11876f3..ccc1e4e 100644 --- a/src/cat.c +++ b/src/cat.c @@ -30,8 +30,6 @@ int main(int argc, char *argv[]) { bool u = false; int opt; - int i = 1; - FILE *file; extern int optind; while ((opt = getopt(argc, argv, "u")) != -1) { @@ -51,10 +49,10 @@ int main(int argc, char *argv[]) { } } + int i = 1; + FILE *file; + for (i = optind; i < argc; i++) { - int byte = 0; // variable for storing bytes as they are read - char buf[4096]; // buffer for buffered - int p = 0; // index counter for bytes in buffered reading /* * From cat(1p): * @@ -91,6 +89,10 @@ int main(int argc, char *argv[]) { } } + int byte = 0; /* variable for storing bytes as they are read */ + int p = 0; /* index counter for bytes in buffered reading */ + char buf[4096]; /* buffer for buffered reading */ + while (byte != EOF) { byte = fgetc(file); From b57a7179a5f3acb40e38f916412f1cac4eae55d4 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 13 Aug 2023 23:30:03 -0600 Subject: [PATCH 08/15] cat(1p): refactor to get no args working --- src/cat.c | 87 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/src/cat.c b/src/cat.c index ccc1e4e..6f0d380 100644 --- a/src/cat.c +++ b/src/cat.c @@ -27,9 +27,37 @@ #include #include +void cat(FILE *file, bool u) { + int byte = 0; /* variable for storing bytes as they are read */ + int p = 0; /* index counter for bytes in buffered reading */ + char buf[4096]; /* buffer for buffered reading */ + + while (byte != EOF) { + byte = fgetc(file); + + if (u) { + putchar(byte); + } else { + if (p > sizeof(buf)) { + fputs(buf, stdout); + p = 0; + } + + buf[p] = byte; + p += 1; + } + } + + fwrite(buf, 1, p, stdout); + fflush(stdout); + + if (file != stdin) { fclose(file); } +} + int main(int argc, char *argv[]) { bool u = false; int opt; + int i; extern int optind; while ((opt = getopt(argc, argv, "u")) != -1) { @@ -49,22 +77,27 @@ int main(int argc, char *argv[]) { } } - int i = 1; - FILE *file; + /* + * From cat(1p): + * + * file A pathname of an input file. If no file operands are + * specified, the standard input shall be used. If a file is + * '-', the cat utility shall read from the standard input at + * that point in the sequence. The cat utility shall not close + * and reopen standard input when it is referenced in this way, + * but shall accept multiple occurrences of '-' as a file + * operand. + */ + if (optind == argc) { + cat(stdin, u); + } + + FILE *file; for (i = optind; i < argc; i++) { - /* - * From cat(1p): - * - * file A pathname of an input file. If no file operands are - * specified, the standard input shall be used. If a file is - * '-', the cat utility shall read from the standard input at - * that point in the sequence. The cat utility shall not close - * and reopen standard input when it is referenced in this way, - * but shall accept multiple occurrences of '-' as a file - * operand. - */ - if (argv[i] == "-" || argc == 1) { + if (argv[i][0] == '-' && argv[i][1] != '\0') { + continue; + } if (strcmp(argv[i], "-") == 0) { file = stdin; } else if ((file = fopen(argv[i], "r")) == NULL) { switch (errno) { @@ -88,31 +121,7 @@ int main(int argc, char *argv[]) { return EX_UNAVAILABLE; } } - - int byte = 0; /* variable for storing bytes as they are read */ - int p = 0; /* index counter for bytes in buffered reading */ - char buf[4096]; /* buffer for buffered reading */ - - while (byte != EOF) { - byte = fgetc(file); - - if (u) { - putchar(byte); - } else { - if (p > sizeof(buf)) { - fputs(buf, stdout); - p = 0; - } - - buf[p] = byte; - p += 1; - } - } - - fwrite(buf, 1, p, stdout); - fflush(stdout); - - if (file != stdin) { fclose(file); } + cat(file, u); } return EX_OK; From ede0817cbd8ca83f136951e1a97dc97f11a68b71 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 14 Aug 2023 00:01:29 -0600 Subject: [PATCH 09/15] minor changes to license headers and to compilation --- Makefile | 9 +++++---- src/cat.c | 2 +- src/false.c | 2 +- src/true.c | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 887aefd..b620128 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# Copyright (c) 2023 YAC +# Copyright (c) 2023 Emma Tebibyte # SPDX-License-Identifier: FSFAP # # Copying and distribution of this file, with or without modification, are @@ -8,6 +8,7 @@ .POSIX: PREFIX=/usr/local/bin +CFLAGS=-O3 -s -Wl,-z,noseparate-code,-z,nosectionheader -flto build: build_dir cat false true @@ -15,13 +16,13 @@ clean: build_dir rm -rf build/ cat: build_dir - cc -o build/cat src/cat.c + cc $(CFLAGS) -o build/cat src/cat.c false: build_dir - cc -o build/false src/false.c + cc $(CFLAGS) -o build/false src/false.c true: build_dir - cc -o build/true src/true.c + cc $(CFLAGS) -o build/true src/true.c build_dir: mkdir -p build diff --git a/src/cat.c b/src/cat.c index 6f0d380..d684768 100644 --- a/src/cat.c +++ b/src/cat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 YAC + * Copyright (c) 2023 Emma Tebibyte * SPDX-License-Identifier: AGPL-3.0-or-later * * This file is part of YAC coreutils. diff --git a/src/false.c b/src/false.c index d255a9a..e6f64b3 100644 --- a/src/false.c +++ b/src/false.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 YAC + * Copyright (c) 2023 Emma Tebibyte * SPDX-License-Identifier: AGPL-3.0-or-later * * This file is part of YAC coreutils. diff --git a/src/true.c b/src/true.c index 2791766..9d1f79f 100644 --- a/src/true.c +++ b/src/true.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 YAC + * Copyright (c) 2023 Emma Tebibyte * SPDX-License-Identifier: AGPL-3.0-or-later * * This file is part of YAC coreutils. From dd584b2886ae9211128e0a054496bbddca6a6334 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 14 Aug 2023 00:07:03 -0600 Subject: [PATCH 10/15] cat(1p): minor typo --- src/cat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cat.c b/src/cat.c index d684768..0574d2b 100644 --- a/src/cat.c +++ b/src/cat.c @@ -97,7 +97,7 @@ int main(int argc, char *argv[]) { for (i = optind; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] != '\0') { continue; - } if (strcmp(argv[i], "-") == 0) { + } else if (strcmp(argv[i], "-") == 0) { file = stdin; } else if ((file = fopen(argv[i], "r")) == NULL) { switch (errno) { From 96d692d26eb1dc3e564e5f2a0334041554fd7bf2 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 14 Aug 2023 00:17:09 -0600 Subject: [PATCH 11/15] cat(1p): print errors to stderr --- src/cat.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cat.c b/src/cat.c index 0574d2b..c577d2d 100644 --- a/src/cat.c +++ b/src/cat.c @@ -72,7 +72,7 @@ int main(int argc, char *argv[]) { u = true; break; default: - printf("Usage: %s (-u) file...\n", argv[0]); + fprintf(stderr, "Usage: %s (-u) file...\n", argv[0]); return EX_USAGE; } } @@ -102,22 +102,22 @@ int main(int argc, char *argv[]) { } else if ((file = fopen(argv[i], "r")) == NULL) { switch (errno) { case EACCES: - printf("%s: %s: Permission denied.\n", argv[0], argv[i]); + fprintf(stderr, "%s: %s: Permission denied.\n", argv[0], argv[i]); return EX_NOINPUT; case EISDIR: - printf("%s: %s: Is a directory.\n", argv[0], argv[i]); + fprintf(stderr, "%s: %s: Is a directory.\n", argv[0], argv[i]); return EX_NOINPUT; case ELOOP: - printf("%s: %s: Is a symbolic link loop.\n", argv[0], argv[i]); + fprintf(stderr, "%s: %s: Is a symbolic link loop.\n", argv[0], argv[i]); return EX_UNAVAILABLE; case EMFILE: - printf("%s: Internal error.\n", argv[0]); + fprintf(stderr, "%s: Internal error.\n", argv[0]); return EX_SOFTWARE; case ENOENT: case ENOTDIR: case ENXIO: - printf("%s: %s: No such file or directory.\n", argv[0], argv[i]); + fprintf(stderr, "%s: %s: No such file or directory.\n", argv[0], argv[i]); return EX_NOINPUT; default: - printf("%s: Unknown error.\n", argv[0]); + fprintf(stderr, "%s: Unknown error.\n", argv[0]); return EX_UNAVAILABLE; } } From 0c290646ec088a6647c622975f1988ebdbd7554e Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 14 Aug 2023 00:25:10 -0600 Subject: [PATCH 12/15] cat(1p): trimming size --- src/cat.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cat.c b/src/cat.c index c577d2d..3fc2a72 100644 --- a/src/cat.c +++ b/src/cat.c @@ -19,12 +19,9 @@ */ #include -#include #include #include #include -#include -#include #include void cat(FILE *file, bool u) { @@ -97,7 +94,7 @@ int main(int argc, char *argv[]) { for (i = optind; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] != '\0') { continue; - } else if (strcmp(argv[i], "-") == 0) { + } else if (argv[i][0] == '-' && argv[i][1] == '\0') { file = stdin; } else if ((file = fopen(argv[i], "r")) == NULL) { switch (errno) { From f041ae5d63f878576818ece99685d7d8cce380e3 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 14 Aug 2023 11:45:43 -0600 Subject: [PATCH 13/15] cat(1p): cleanup --- src/cat.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/cat.c b/src/cat.c index 3fc2a72..7047c1f 100644 --- a/src/cat.c +++ b/src/cat.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -29,26 +30,26 @@ void cat(FILE *file, bool u) { int p = 0; /* index counter for bytes in buffered reading */ char buf[4096]; /* buffer for buffered reading */ - while (byte != EOF) { - byte = fgetc(file); - - if (u) { + if (u) { + while (byte != EOF) { + byte = fgetc(file); putchar(byte); - } else { + } + } else { + while (byte != EOF) { + byte = fgetc(file); if (p > sizeof(buf)) { fputs(buf, stdout); p = 0; + } else { + buf[p] = byte; + p += 1; } - - buf[p] = byte; - p += 1; } + + fwrite(buf, 1, p, stdout); + fflush(stdout); } - - fwrite(buf, 1, p, stdout); - fflush(stdout); - - if (file != stdin) { fclose(file); } } int main(int argc, char *argv[]) { @@ -91,11 +92,20 @@ int main(int argc, char *argv[]) { } FILE *file; + struct stat stats; + for (i = optind; i < argc; i++) { - if (argv[i][0] == '-' && argv[i][1] != '\0') { - continue; - } else if (argv[i][0] == '-' && argv[i][1] == '\0') { - file = stdin; + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case '\0': + file = stdin; + break; + default: + continue; + } + } else if (stat(argv[i], &stats) == 0 && S_ISDIR(stats.st_mode)) { + fprintf(stderr, "%s: %s: Is a directory.\n", argv[0], argv[i]); + return EX_NOINPUT; } else if ((file = fopen(argv[i], "r")) == NULL) { switch (errno) { case EACCES: @@ -118,7 +128,9 @@ int main(int argc, char *argv[]) { return EX_UNAVAILABLE; } } + cat(file, u); + if (file != stdin) { fclose(file); } } return EX_OK; From 3c7d4c41be9797e4aaffbdc211b9c868c6b33667 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 14 Aug 2023 12:04:16 -0600 Subject: [PATCH 14/15] cat(1p): minor cleanup --- src/cat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cat.c b/src/cat.c index 7047c1f..c719e4b 100644 --- a/src/cat.c +++ b/src/cat.c @@ -89,6 +89,7 @@ int main(int argc, char *argv[]) { if (optind == argc) { cat(stdin, u); + return 0; } FILE *file; From 6c73ffadd648333d46f21c2998a1cae244abf545 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 14 Aug 2023 12:08:03 -0600 Subject: [PATCH 15/15] cat(1p): formatting --- src/cat.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/cat.c b/src/cat.c index c719e4b..6fd9671 100644 --- a/src/cat.c +++ b/src/cat.c @@ -116,13 +116,23 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s: %s: Is a directory.\n", argv[0], argv[i]); return EX_NOINPUT; case ELOOP: - fprintf(stderr, "%s: %s: Is a symbolic link loop.\n", argv[0], argv[i]); + fprintf( + stderr, + "%s: %s: Is a symbolic link loop.\n", + argv[0], + argv[i] + ); return EX_UNAVAILABLE; case EMFILE: fprintf(stderr, "%s: Internal error.\n", argv[0]); return EX_SOFTWARE; case ENOENT: case ENOTDIR: case ENXIO: - fprintf(stderr, "%s: %s: No such file or directory.\n", argv[0], argv[i]); + fprintf( + stderr, + "%s: %s: No such file or directory.\n", + argv[0], + argv[i] + ); return EX_NOINPUT; default: fprintf(stderr, "%s: Unknown error.\n", argv[0]);