]> git.ipfire.org Git - thirdparty/dracut.git/blob - logtee.c
ci: add function to generate qemu disk arguments
[thirdparty/dracut.git] / logtee.c
1 #define _GNU_SOURCE
2 #include <fcntl.h>
3 #include <poll.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <errno.h>
8 #include <limits.h>
9
10 #define BUFLEN 4096
11
12 int main(int argc, char *argv[])
13 {
14 int fd;
15 int len, slen;
16 int ret;
17 int timeout;
18 char *timeout_env;
19 struct pollfd fds[] = { {
20 .fd = STDIN_FILENO,
21 .events = POLLIN | POLLERR,
22 }
23 };
24
25 timeout_env = getenv("LOGTEE_TIMEOUT_MS");
26 if (timeout_env)
27 timeout = atoi(timeout_env);
28 else
29 timeout = -1;
30
31 if (argc != 2) {
32 fprintf(stderr, "Usage: %s <file>\n", argv[0]);
33 exit(EXIT_FAILURE);
34 }
35
36 fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, 0644);
37 if (fd == -1) {
38 perror("open");
39 exit(EXIT_FAILURE);
40 }
41
42 fprintf(stderr, "Logging to %s: ", argv[1]);
43
44 slen = 0;
45
46 do {
47 ret = poll(fds, sizeof(fds) / sizeof(fds[0]), timeout);
48 if (ret == 0) {
49 fprintf(stderr, "Timed out after %d milliseconds of no output.\n", timeout);
50 exit(EXIT_FAILURE);
51 }
52 len = splice(STDIN_FILENO, NULL, fd, NULL, BUFLEN, SPLICE_F_MOVE | SPLICE_F_NONBLOCK);
53
54 if (len < 0) {
55 if (errno == EAGAIN)
56 continue;
57 perror("tee");
58 exit(EXIT_FAILURE);
59 } else if (len == 0)
60 break;
61 slen += len;
62 if ((slen / BUFLEN) > 0) {
63 fprintf(stderr, ".");
64 }
65 slen = slen % BUFLEN;
66
67 } while (1);
68 close(fd);
69 fprintf(stderr, "\n");
70 exit(EXIT_SUCCESS);
71 }