cat.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2013-2018 K. Lange
  5. *
  6. * cat - Concatenate files
  7. *
  8. * Concatenates files together to standard output.
  9. * In a supporting terminal, you can then pipe
  10. * standard out to another file or other useful
  11. * things like that.
  12. */
  13. #include <stdio.h>
  14. #include <fcntl.h>
  15. #include <unistd.h>
  16. #include <string.h>
  17. #include <errno.h>
  18. #include <sys/stat.h>
  19. #define CHUNK_SIZE 4096
  20. static char * _argv_0;
  21. static char * _file;
  22. void doit(int fd) {
  23. while (1) {
  24. char buf[CHUNK_SIZE];
  25. memset(buf, 0, CHUNK_SIZE);
  26. ssize_t r = read(fd, buf, CHUNK_SIZE);
  27. if (!r) return;
  28. if (r < 0) {
  29. fprintf(stderr, "%s: %s: %s\n", _argv_0, _file, strerror(errno));
  30. return;
  31. }
  32. write(STDOUT_FILENO, buf, r);
  33. }
  34. }
  35. int main(int argc, char ** argv) {
  36. int ret = 0;
  37. _argv_0 = argv[0];
  38. if (argc == 1) {
  39. _file = "stdin";
  40. doit(0);
  41. }
  42. for (int i = 1; i < argc; ++i) {
  43. if (!strcmp(argv[i],"-")) {
  44. _file = "stdin";
  45. doit(0);
  46. continue;
  47. }
  48. _file = argv[i];
  49. int fd = open(argv[i], O_RDONLY);
  50. if (fd < 0) {
  51. fprintf(stderr, "%s: %s: %s\n", argv[0], argv[i], strerror(errno));
  52. ret = 1;
  53. continue;
  54. }
  55. struct stat _stat;
  56. fstat(fd, &_stat);
  57. if (S_ISDIR(_stat.st_mode)) {
  58. fprintf(stderr, "%s: %s: Is a directory\n", argv[0], argv[i]);
  59. close(fd);
  60. ret = 1;
  61. continue;
  62. }
  63. doit(fd);
  64. close(fd);
  65. }
  66. return ret;
  67. }