logo

utils

~/.local/bin tools and git-hooks git clone https://hacktivis.me/git/utils.git

cat.c (1505B)


  1. // Collection of Unix tools, comparable to coreutils
  2. // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
  4. #define _POSIX_C_SOURCE 200809L
  5. #include <errno.h> /* errno */
  6. #include <fcntl.h> /* open(), O_RDONLY */
  7. #include <stdio.h> /* fprintf(), BUFSIZ */
  8. #include <string.h> /* strerror(), strncmp() */
  9. #include <unistd.h> /* read(), write(), close() */
  10. int
  11. concat(int fd, const char *fdname)
  12. {
  13. ssize_t c;
  14. char buf[BUFSIZ];
  15. while((c = read(fd, buf, sizeof(buf))) > 0)
  16. {
  17. if(write(1, buf, (size_t)c) < 0)
  18. {
  19. fprintf(stderr, "\nError writing: %s\n", strerror(errno));
  20. return 1;
  21. }
  22. }
  23. if(c < 0)
  24. {
  25. fprintf(stderr, "\nError reading ‘%s’: %s\n", fdname, strerror(errno));
  26. return 1;
  27. }
  28. return 0;
  29. }
  30. int
  31. main(int argc, char *argv[])
  32. {
  33. if(argc <= 1)
  34. {
  35. return concat(0, "<stdin>");
  36. }
  37. for(int argi = 1; argi < argc; argi++)
  38. {
  39. if(strncmp(argv[argi], "-", 2) == 0)
  40. {
  41. if(concat(0, "<stdin>") != 0)
  42. {
  43. return 1;
  44. }
  45. }
  46. else if(strncmp(argv[argi], "--", 3) == 0)
  47. {
  48. continue;
  49. }
  50. else
  51. {
  52. int fd = open(argv[argi], O_RDONLY);
  53. if(fd < 0)
  54. {
  55. fprintf(stderr, "\nError opening ‘%s’: %s\n", argv[argi], strerror(errno));
  56. return 1;
  57. }
  58. if(concat(fd, argv[argi]) != 0)
  59. {
  60. return 1;
  61. }
  62. if(close(fd) < 0)
  63. {
  64. fprintf(stderr, "\nError closing ‘%s’: %s\n", argv[argi], strerror(errno));
  65. return 1;
  66. }
  67. }
  68. }
  69. return 0;
  70. }