exercise_4_1.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * The tee command reads its standard input until end-of-file, writing a copy of the input
  3. * to standard output and to the file named in its command-line argument. (We show
  4. * an example of the use of this command when we discuss FIFOs in Section 44.7.)
  5. * Implement tee using I/O system calls. By default, tee overwrites any existing file with
  6. * the given name. Implement the –a command-line option (tee –a file), which causes tee
  7. * to append text to the end of a file if it already exists. (Refer to Appendix B for a
  8. * description of the getopt() function, which can be used to parse command-line
  9. * options.)
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. static const size_t buffer_size = 10;
  16. int
  17. main (int argc, char *argv[])
  18. {
  19. int fd = STDOUT_FILENO;
  20. int opt;
  21. while ((opt = getopt (argc, argv, "+:a:")) != -1)
  22. {
  23. int file_fd;
  24. switch (opt)
  25. {
  26. case 'a':
  27. file_fd = open (optarg, O_WRONLY|O_CREAT|O_APPEND,
  28. S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
  29. if (file_fd != -1)
  30. fd = file_fd;
  31. else
  32. fputs ("Failed to open given file", stderr), _exit (EXIT_FAILURE);
  33. break;
  34. default:
  35. fprintf (stderr, "Unexpected case %c\n", opt);
  36. _exit (EXIT_FAILURE);
  37. }
  38. }
  39. if (optind < argc)
  40. {
  41. int file_fd = open (argv[optind], O_WRONLY|O_CREAT|O_TRUNC,
  42. S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
  43. if (file_fd != -1)
  44. fd = file_fd;
  45. else
  46. fputs ("Failed to open given file", stderr), _exit (EXIT_FAILURE);
  47. }
  48. char buffer[buffer_size];
  49. ssize_t nbytes_read = 0;
  50. while ((nbytes_read = read (STDIN_FILENO, buffer, buffer_size)) > 0)
  51. {
  52. if (write (fd, buffer, nbytes_read) != nbytes_read)
  53. {
  54. exit (EXIT_FAILURE);
  55. }
  56. }
  57. close (fd);
  58. return EXIT_SUCCESS;
  59. }