1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Simple poll on a file.
4  *
5  * Copyright (c) 2024 Google LLC.
6  */
7 
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <poll.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 
16 #define BUFSIZE 4096
17 
18 /*
19  * Usage:
20  *  poll [-I|-P] [-t timeout] FILE
21  */
main(int argc,char * argv[])22 int main(int argc, char *argv[])
23 {
24 	struct pollfd pfd = {.events = POLLIN};
25 	char buf[BUFSIZE];
26 	int timeout = -1;
27 	int ret, opt;
28 
29 	while ((opt = getopt(argc, argv, "IPt:")) != -1) {
30 		switch (opt) {
31 		case 'I':
32 			pfd.events = POLLIN;
33 			break;
34 		case 'P':
35 			pfd.events = POLLPRI;
36 			break;
37 		case 't':
38 			timeout = atoi(optarg);
39 			break;
40 		default:
41 			fprintf(stderr, "Usage: %s [-I|-P] [-t timeout] FILE\n",
42 				argv[0]);
43 			return -1;
44 		}
45 	}
46 	if (optind >= argc) {
47 		fprintf(stderr, "Error: Polling file is not specified\n");
48 		return -1;
49 	}
50 
51 	pfd.fd = open(argv[optind], O_RDONLY);
52 	if (pfd.fd < 0) {
53 		fprintf(stderr, "failed to open %s", argv[optind]);
54 		perror("open");
55 		return -1;
56 	}
57 
58 	/* Reset poll by read if POLLIN is specified. */
59 	if (pfd.events & POLLIN)
60 		do {} while (read(pfd.fd, buf, BUFSIZE) == BUFSIZE);
61 
62 	ret = poll(&pfd, 1, timeout);
63 	if (ret < 0 && errno != EINTR) {
64 		perror("poll");
65 		return -1;
66 	}
67 	close(pfd.fd);
68 
69 	/* If timeout happned (ret == 0), exit code is 1 */
70 	if (ret == 0)
71 		return 1;
72 
73 	return 0;
74 }
75