tee.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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) 2018 K. Lange
  5. *
  6. * tee - copy stdin to stdout and to specified files
  7. */
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <getopt.h>
  11. #include <signal.h>
  12. #include <string.h>
  13. #include <errno.h>
  14. int main(int argc, char * argv[]) {
  15. int append = 0;
  16. int ret_val = 0;
  17. int opt;
  18. while ((opt = getopt(argc, argv, "ai")) != -1) {
  19. switch (opt) {
  20. case 'a':
  21. append = 1;
  22. break;
  23. case 'i':
  24. signal(SIGINT, SIG_IGN);
  25. break;
  26. }
  27. }
  28. int file_count = argc - optind;
  29. FILE ** files = malloc(sizeof(FILE *) * file_count);
  30. for (int i = 0, j = optind; j < argc && i < file_count; j++) {
  31. files[i] = fopen(argv[j], append ? "a" : "w");
  32. if (!files[i]) {
  33. fprintf(stderr, "%s: %s: %s\n", argv[0], argv[j], strerror(errno));
  34. ret_val = 1;
  35. file_count--;
  36. continue;
  37. } else {
  38. i++;
  39. }
  40. }
  41. while (!feof(stdin)) {
  42. int c = fgetc(stdin);
  43. if (c >= 0) {
  44. fputc(c, stdout);
  45. for (int i = 0; i < file_count; ++i) {
  46. fputc(c, files[i]);
  47. }
  48. }
  49. }
  50. for (int i = 0; i < file_count; ++i) {
  51. fclose(files[i]);
  52. }
  53. return ret_val;
  54. }