xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/inotify/inotify01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2007 SWSoft.  All Rights Reserved.
4*49cdfc7eSAndroid Build Coastguard Worker  * Author: Andrew Vagin <[email protected]>
5*49cdfc7eSAndroid Build Coastguard Worker  */
6*49cdfc7eSAndroid Build Coastguard Worker 
7*49cdfc7eSAndroid Build Coastguard Worker /*\
8*49cdfc7eSAndroid Build Coastguard Worker  * [Description]
9*49cdfc7eSAndroid Build Coastguard Worker  *
10*49cdfc7eSAndroid Build Coastguard Worker  * Basic test for inotify events on file.
11*49cdfc7eSAndroid Build Coastguard Worker  */
12*49cdfc7eSAndroid Build Coastguard Worker 
13*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
14*49cdfc7eSAndroid Build Coastguard Worker 
15*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
16*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
17*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
18*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
19*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
20*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
21*49cdfc7eSAndroid Build Coastguard Worker #include <sys/syscall.h>
22*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
23*49cdfc7eSAndroid Build Coastguard Worker #include "inotify.h"
24*49cdfc7eSAndroid Build Coastguard Worker 
25*49cdfc7eSAndroid Build Coastguard Worker #if defined(HAVE_SYS_INOTIFY_H)
26*49cdfc7eSAndroid Build Coastguard Worker #include <sys/inotify.h>
27*49cdfc7eSAndroid Build Coastguard Worker 
28*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_MAX 1024
29*49cdfc7eSAndroid Build Coastguard Worker /* size of the event structure, not counting name */
30*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_SIZE  (sizeof (struct inotify_event))
31*49cdfc7eSAndroid Build Coastguard Worker /* reasonable guess as to size of 1024 events */
32*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_BUF_LEN        (EVENT_MAX * (EVENT_SIZE + 16))
33*49cdfc7eSAndroid Build Coastguard Worker 
34*49cdfc7eSAndroid Build Coastguard Worker #define BUF_SIZE 256
35*49cdfc7eSAndroid Build Coastguard Worker 
36*49cdfc7eSAndroid Build Coastguard Worker static char fname[BUF_SIZE];
37*49cdfc7eSAndroid Build Coastguard Worker static char buf[BUF_SIZE];
38*49cdfc7eSAndroid Build Coastguard Worker static int fd, fd_notify;
39*49cdfc7eSAndroid Build Coastguard Worker static int wd, reap_wd;
40*49cdfc7eSAndroid Build Coastguard Worker 
41*49cdfc7eSAndroid Build Coastguard Worker static unsigned int event_set[EVENT_MAX];
42*49cdfc7eSAndroid Build Coastguard Worker 
43*49cdfc7eSAndroid Build Coastguard Worker static char event_buf[EVENT_BUF_LEN];
44*49cdfc7eSAndroid Build Coastguard Worker 
verify_inotify(void)45*49cdfc7eSAndroid Build Coastguard Worker void verify_inotify(void)
46*49cdfc7eSAndroid Build Coastguard Worker {
47*49cdfc7eSAndroid Build Coastguard Worker 	int test_cnt = 0;
48*49cdfc7eSAndroid Build Coastguard Worker 
49*49cdfc7eSAndroid Build Coastguard Worker 	/*
50*49cdfc7eSAndroid Build Coastguard Worker 	 * generate sequence of events
51*49cdfc7eSAndroid Build Coastguard Worker 	 */
52*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CHMOD(fname, 0755);
53*49cdfc7eSAndroid Build Coastguard Worker 	event_set[test_cnt] = IN_ATTRIB;
54*49cdfc7eSAndroid Build Coastguard Worker 	test_cnt++;
55*49cdfc7eSAndroid Build Coastguard Worker 
56*49cdfc7eSAndroid Build Coastguard Worker 	fd = SAFE_OPEN(fname, O_RDONLY);
57*49cdfc7eSAndroid Build Coastguard Worker 	event_set[test_cnt] = IN_OPEN;
58*49cdfc7eSAndroid Build Coastguard Worker 	test_cnt++;
59*49cdfc7eSAndroid Build Coastguard Worker 
60*49cdfc7eSAndroid Build Coastguard Worker 	if (read(fd, buf, BUF_SIZE) == -1) {
61*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TERRNO,
62*49cdfc7eSAndroid Build Coastguard Worker 			"read(%d, buf, %d) failed", fd, BUF_SIZE);
63*49cdfc7eSAndroid Build Coastguard Worker 	}
64*49cdfc7eSAndroid Build Coastguard Worker 	event_set[test_cnt] = IN_ACCESS;
65*49cdfc7eSAndroid Build Coastguard Worker 	test_cnt++;
66*49cdfc7eSAndroid Build Coastguard Worker 
67*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CLOSE(fd);
68*49cdfc7eSAndroid Build Coastguard Worker 	event_set[test_cnt] = IN_CLOSE_NOWRITE;
69*49cdfc7eSAndroid Build Coastguard Worker 	test_cnt++;
70*49cdfc7eSAndroid Build Coastguard Worker 
71*49cdfc7eSAndroid Build Coastguard Worker 	fd = SAFE_OPEN(fname, O_RDWR | O_CREAT, 0700);
72*49cdfc7eSAndroid Build Coastguard Worker 	event_set[test_cnt] = IN_OPEN;
73*49cdfc7eSAndroid Build Coastguard Worker 	test_cnt++;
74*49cdfc7eSAndroid Build Coastguard Worker 
75*49cdfc7eSAndroid Build Coastguard Worker 	if (write(fd, buf, BUF_SIZE) == -1) {
76*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK,
77*49cdfc7eSAndroid Build Coastguard Worker 			"write(%d, %s, 1) failed", fd, fname);
78*49cdfc7eSAndroid Build Coastguard Worker 	}
79*49cdfc7eSAndroid Build Coastguard Worker 	event_set[test_cnt] = IN_MODIFY;
80*49cdfc7eSAndroid Build Coastguard Worker 	test_cnt++;
81*49cdfc7eSAndroid Build Coastguard Worker 
82*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CLOSE(fd);
83*49cdfc7eSAndroid Build Coastguard Worker 	event_set[test_cnt] = IN_CLOSE_WRITE;
84*49cdfc7eSAndroid Build Coastguard Worker 	test_cnt++;
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker 	/*
87*49cdfc7eSAndroid Build Coastguard Worker 	 * get list of events
88*49cdfc7eSAndroid Build Coastguard Worker 	 */
89*49cdfc7eSAndroid Build Coastguard Worker 	int len, i = 0, test_num = 0;
90*49cdfc7eSAndroid Build Coastguard Worker 	if ((len = read(fd_notify, event_buf, EVENT_BUF_LEN)) < 0) {
91*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK,
92*49cdfc7eSAndroid Build Coastguard Worker 			"read(%d, buf, %zu) failed",
93*49cdfc7eSAndroid Build Coastguard Worker 			fd_notify, EVENT_BUF_LEN);
94*49cdfc7eSAndroid Build Coastguard Worker 
95*49cdfc7eSAndroid Build Coastguard Worker 	}
96*49cdfc7eSAndroid Build Coastguard Worker 
97*49cdfc7eSAndroid Build Coastguard Worker 	/*
98*49cdfc7eSAndroid Build Coastguard Worker 	 * check events
99*49cdfc7eSAndroid Build Coastguard Worker 	 */
100*49cdfc7eSAndroid Build Coastguard Worker 	while (i < len) {
101*49cdfc7eSAndroid Build Coastguard Worker 		struct inotify_event *event;
102*49cdfc7eSAndroid Build Coastguard Worker 		event = (struct inotify_event *)&event_buf[i];
103*49cdfc7eSAndroid Build Coastguard Worker 		if (test_num >= test_cnt) {
104*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL,
105*49cdfc7eSAndroid Build Coastguard Worker 				"get unnecessary event: wd=%d mask=%02x "
106*49cdfc7eSAndroid Build Coastguard Worker 				"cookie=%u len=%u",
107*49cdfc7eSAndroid Build Coastguard Worker 				event->wd, event->mask,
108*49cdfc7eSAndroid Build Coastguard Worker 				event->cookie, event->len);
109*49cdfc7eSAndroid Build Coastguard Worker 		} else if (event_set[test_num] == event->mask) {
110*49cdfc7eSAndroid Build Coastguard Worker 			if (event->cookie != 0) {
111*49cdfc7eSAndroid Build Coastguard Worker 				tst_res(TFAIL,
112*49cdfc7eSAndroid Build Coastguard Worker 					"get event: wd=%d mask=%02x "
113*49cdfc7eSAndroid Build Coastguard Worker 					"cookie=%u (expected 0) len=%u",
114*49cdfc7eSAndroid Build Coastguard Worker 					event->wd, event->mask,
115*49cdfc7eSAndroid Build Coastguard Worker 					event->cookie, event->len);
116*49cdfc7eSAndroid Build Coastguard Worker 			} else {
117*49cdfc7eSAndroid Build Coastguard Worker 				tst_res(TPASS, "get event: wd=%d "
118*49cdfc7eSAndroid Build Coastguard Worker 					"mask=%02x cookie=%u len=%u",
119*49cdfc7eSAndroid Build Coastguard Worker 					event->wd, event->mask,
120*49cdfc7eSAndroid Build Coastguard Worker 					event->cookie, event->len);
121*49cdfc7eSAndroid Build Coastguard Worker 			}
122*49cdfc7eSAndroid Build Coastguard Worker 
123*49cdfc7eSAndroid Build Coastguard Worker 		} else {
124*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL, "get event: wd=%d mask=%02x "
125*49cdfc7eSAndroid Build Coastguard Worker 				"(expected %x) cookie=%u len=%u",
126*49cdfc7eSAndroid Build Coastguard Worker 				event->wd, event->mask,
127*49cdfc7eSAndroid Build Coastguard Worker 				event_set[test_num],
128*49cdfc7eSAndroid Build Coastguard Worker 				event->cookie, event->len);
129*49cdfc7eSAndroid Build Coastguard Worker 		}
130*49cdfc7eSAndroid Build Coastguard Worker 		test_num++;
131*49cdfc7eSAndroid Build Coastguard Worker 		i += EVENT_SIZE + event->len;
132*49cdfc7eSAndroid Build Coastguard Worker 	}
133*49cdfc7eSAndroid Build Coastguard Worker 	for (; test_num < test_cnt; test_num++) {
134*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "didn't get event: mask=%02x",
135*49cdfc7eSAndroid Build Coastguard Worker 			event_set[test_num]);
136*49cdfc7eSAndroid Build Coastguard Worker 
137*49cdfc7eSAndroid Build Coastguard Worker 	}
138*49cdfc7eSAndroid Build Coastguard Worker }
139*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)140*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
141*49cdfc7eSAndroid Build Coastguard Worker {
142*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(fname, "tfile_%d", getpid());
143*49cdfc7eSAndroid Build Coastguard Worker 
144*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FILE_PRINTF(fname, "%s", fname);
145*49cdfc7eSAndroid Build Coastguard Worker 
146*49cdfc7eSAndroid Build Coastguard Worker 	fd_notify = SAFE_MYINOTIFY_INIT();
147*49cdfc7eSAndroid Build Coastguard Worker 
148*49cdfc7eSAndroid Build Coastguard Worker 	wd = SAFE_MYINOTIFY_ADD_WATCH(fd_notify, fname, IN_ALL_EVENTS);
149*49cdfc7eSAndroid Build Coastguard Worker 	reap_wd = 1;
150*49cdfc7eSAndroid Build Coastguard Worker }
151*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)152*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
153*49cdfc7eSAndroid Build Coastguard Worker {
154*49cdfc7eSAndroid Build Coastguard Worker 	if (reap_wd && myinotify_rm_watch(fd_notify, wd) < 0) {
155*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TWARN | TERRNO, "inotify_rm_watch (%d, %d) failed",
156*49cdfc7eSAndroid Build Coastguard Worker 			fd_notify, wd);
157*49cdfc7eSAndroid Build Coastguard Worker 	}
158*49cdfc7eSAndroid Build Coastguard Worker 
159*49cdfc7eSAndroid Build Coastguard Worker 	if (fd_notify > 0)
160*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_CLOSE(fd_notify);
161*49cdfc7eSAndroid Build Coastguard Worker }
162*49cdfc7eSAndroid Build Coastguard Worker 
163*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
164*49cdfc7eSAndroid Build Coastguard Worker 	.needs_tmpdir = 1,
165*49cdfc7eSAndroid Build Coastguard Worker 	.setup = setup,
166*49cdfc7eSAndroid Build Coastguard Worker 	.cleanup = cleanup,
167*49cdfc7eSAndroid Build Coastguard Worker 	.test_all = verify_inotify,
168*49cdfc7eSAndroid Build Coastguard Worker };
169*49cdfc7eSAndroid Build Coastguard Worker 
170*49cdfc7eSAndroid Build Coastguard Worker #else
171*49cdfc7eSAndroid Build Coastguard Worker 	TST_TEST_TCONF("system doesn't have required inotify support");
172*49cdfc7eSAndroid Build Coastguard Worker #endif
173