Commenti al problema di {{{SPLICE_F_NONBLOCK}}} e correzione del
[gapil.git] / listati / tee.c
1 #define _GNU_SOURCE
2 #include <fcntl.h>       /* file control functions */
3 ...
4 int main(int argc, char *argv[])
5 {
6     size_t size = 4096;
7     int fd, len, nwrite;
8     struct stat fdata;
9     ...
10     /* check argument, open destination file and check stdin and stdout */
11     if ((argc - optind) != 1) { /* There must be one argument */
12         printf("Wrong number of arguments %d\n", argc - optind);
13         usage();
14     }
15     fd = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0644);
16     if (fd == -1) {
17         printf("opening file %s falied: %s", argv[1], strerror(errno));
18         exit(EXIT_FAILURE);
19     }
20     if (fstat(STDIN_FILENO, &fdata) < 0) {
21         perror("cannot stat stdin");
22         exit(EXIT_FAILURE);
23     }
24     if (!S_ISFIFO(fdata.st_mode)) {
25         fprintf(stderr, "stdin must be a pipe\n");
26         exit(EXIT_FAILURE);
27     }
28     if (fstat(STDOUT_FILENO, &fdata) < 0) {
29         perror("cannot stat stdout");
30         exit(EXIT_FAILURE);
31     }
32     if (!S_ISFIFO(fdata.st_mode)) {
33         fprintf(stderr, "stdout must be a pipe\n");
34         exit(EXIT_FAILURE);
35     }
36     /* tee loop */
37     while (1) {
38         /* copy stdin to stdout */
39         len = tee(STDIN_FILENO, STDOUT_FILENO, size, 0);
40         if (len == 0) break;
41         if (len < 0) {
42             if (errno == EAGAIN) {
43                 continue;
44             } else {
45                 perror("error on tee stdin to stdout");
46                 exit(EXIT_FAILURE);
47             }
48         }
49         /* write data to the file using splice */
50         while (len > 0) {
51             nwrite = splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
52             if (nwrite < 0) {
53                 perror("error on splice stdin to file");
54                 break;
55             }
56             len -= nwrite;
57         }
58     }
59     exit(EXIT_SUCCESS);
60 }