1 /*
2 * Check decoding of inotify_init1 syscall.
3 *
4 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
5 * Copyright (c) 2016-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include "scno.h"
13
14 #if defined(__NR_inotify_init1)
15
16 # include <stdio.h>
17 # include <unistd.h>
18 # include "kernel_fcntl.h"
19
20 # define all_flags (O_NONBLOCK | O_CLOEXEC)
21
22 # ifdef PRINT_PATHS
23 # define RC_FMT "%ld<%s>"
24 # else
25 # define RC_FMT "%s"
26 # endif
27
28 int
29 main(void)
30 {
31 # ifdef PRINT_PATHS
32 skip_if_unavailable("/proc/self/fd/");
33 # endif
34
35 static const kernel_ulong_t bogus_flags1 =
36 (kernel_ulong_t) 0xfacefeeddeadbeefULL | O_NONBLOCK;
37 static const kernel_ulong_t bogus_flags2 =
38 (kernel_ulong_t) 0x55555550ff96b77bULL & ~all_flags;
39
40 long rc;
41
42 rc = syscall(__NR_inotify_init1, bogus_flags1);
43 printf("inotify_init1(IN_NONBLOCK|%s%#x) = %s\n",
44 bogus_flags1 & O_CLOEXEC ? "IN_CLOEXEC|" : "",
45 (unsigned int) (bogus_flags1 & ~all_flags),
46 sprintrc(rc));
47
48 rc = syscall(__NR_inotify_init1, bogus_flags2);
49 printf("inotify_init1(%#x /* IN_??? */) = %s\n",
50 (unsigned int) bogus_flags2, sprintrc(rc));
51
52 rc = syscall(__NR_inotify_init1, all_flags);
53
54 # ifdef PRINT_PATHS
55 if (rc < 0)
56 perror_msg_and_skip("inotify_init(%#x)", all_flags);
57
58 /*
59 * Kernels that do not have v2.6.33-rc1~34^2~7 do not have
60 * "anon_inode:" prefix. Let's assume that it can be either "inotify"
61 * or "anon_inode:inotify" for now, as any change there may be
62 * of interest.
63 */
64 char path[sizeof("/proc/self/fd/") + sizeof(rc) * 3];
65 char buf[2] = "";
66 const char *inotify_path;
67 ssize_t ret;
68
69 ret = snprintf(path, sizeof(path), "/proc/self/fd/%ld", rc);
70 if ((ret < 0) || ((size_t) ret >= sizeof(path)))
71 perror_msg_and_fail("snprintf(path)");
72
73 ret = readlink(path, buf, sizeof(buf));
74 if (ret < 0)
75 perror_msg_and_fail("readlink");
76
77 switch (buf[0]) {
78 case 'a':
79 inotify_path = "anon_inode:inotify";
80 break;
81 case 'i':
82 inotify_path = "inotify";
83 break;
84 default:
85 error_msg_and_fail("Unexpected first char '%c' of inotify fd "
86 "link path", buf[0]);
87 }
88 # endif
89
90 printf("inotify_init1(IN_NONBLOCK|IN_CLOEXEC) = " RC_FMT "\n",
91 # ifdef PRINT_PATHS
92 rc, inotify_path
93 # else
94 sprintrc(rc)
95 # endif
96 );
97
98 puts("+++ exited with 0 +++");
99
100 return 0;
101 }
102
103 #else
104
105 SKIP_MAIN_UNDEFINED("__NR_inotify_init1");
106
107 #endif