pat.c (1735B)
- // Collection of Unix tools, comparable to coreutils
- // SPDX-FileCopyrightText: 2017-2023 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include <errno.h> /* errno */
- #include <fcntl.h> /* open(), O_RDONLY */
- #include <stdio.h> /* fprintf(), fwrite(), BUFSIZ */
- #include <string.h> /* strerror(), strncmp() */
- #include <unistd.h> /* read(), close() */
- int files = 1;
- int
- concat(int fd, const char *fdname)
- {
- ssize_t c;
- char buf[BUFSIZ];
- // File Number as an esccape/containment solution
- printf("\n### File %d << %s >> ###\n", files++, fdname);
- while((c = read(fd, buf, sizeof(buf))) > 0)
- {
- if(fwrite(buf, (size_t)c, 1, stdout) < 0)
- {
- fprintf(stderr, "pat: Error writing: %s\n", strerror(errno));
- return 1;
- }
- }
- if(c < 0)
- {
- fprintf(stderr, "pat: Error reading ‘%s’: %s\n", fdname, strerror(errno));
- return 1;
- }
- return 0;
- }
- int
- main(int argc, char *argv[])
- {
- if(argc <= 1)
- {
- printf("### 1 Files ###");
- return concat(0, "<stdin>");
- }
- // no \n, concat starts with one
- printf("### %d Files ###", argc - 1);
- for(int argi = 1; argi < argc; argi++)
- {
- if(strncmp(argv[argi], "-", 2) == 0)
- {
- if(concat(0, "<stdin>") != 0)
- {
- return 1;
- }
- }
- else if(strncmp(argv[argi], "--", 3) == 0)
- {
- continue;
- }
- else
- {
- int fd = open(argv[argi], O_RDONLY);
- if(fd < 0)
- {
- fprintf(stderr, "pat: Error opening ‘%s’: %s\n", argv[argi], strerror(errno));
- return 1;
- }
- if(concat(fd, argv[argi]) != 0)
- {
- return 1;
- }
- if(close(fd) < 0)
- {
- fprintf(stderr, "pat: Error closing ‘%s’: %s\n", argv[argi], strerror(errno));
- return 1;
- }
- }
- }
- return 0;
- }