Commit | Line | Data |
---|---|---|
e8cc3348 MS |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | ||
3 | #include <errno.h> | |
4 | #include <stdbool.h> | |
5 | #include <stdio.h> | |
6 | #include <stdlib.h> | |
7 | #include <string.h> | |
8 | #include <sys/stat.h> | |
9 | #include <unistd.h> | |
10 | #include <linux/limits.h> | |
11 | ||
12 | #include "../kselftest.h" | |
13 | ||
14 | #define MIN_TTY_PATH_LEN 8 | |
15 | ||
16 | static bool tty_valid(char *tty) | |
17 | { | |
18 | if (strlen(tty) < MIN_TTY_PATH_LEN) | |
19 | return false; | |
20 | ||
21 | if (strncmp(tty, "/dev/tty", MIN_TTY_PATH_LEN) == 0 || | |
22 | strncmp(tty, "/dev/pts", MIN_TTY_PATH_LEN) == 0) | |
23 | return true; | |
24 | ||
25 | return false; | |
26 | } | |
27 | ||
28 | static int write_dev_tty(void) | |
29 | { | |
30 | FILE *f; | |
31 | int r = 0; | |
32 | ||
33 | f = fopen("/dev/tty", "r+"); | |
34 | if (!f) | |
35 | return -errno; | |
36 | ||
37 | r = fprintf(f, "hello, world!\n"); | |
38 | if (r != strlen("hello, world!\n")) | |
39 | r = -EIO; | |
40 | ||
41 | fclose(f); | |
42 | return r; | |
43 | } | |
44 | ||
45 | int main(int argc, char **argv) | |
46 | { | |
47 | int r; | |
48 | char tty[PATH_MAX] = {}; | |
49 | struct stat st1, st2; | |
50 | ||
51 | ksft_print_header(); | |
52 | ksft_set_plan(1); | |
53 | ||
54 | r = readlink("/proc/self/fd/0", tty, PATH_MAX); | |
55 | if (r < 0) | |
56 | ksft_exit_fail_msg("readlink on /proc/self/fd/0 failed: %m\n"); | |
57 | ||
58 | if (!tty_valid(tty)) | |
59 | ksft_exit_skip("invalid tty path '%s'\n", tty); | |
60 | ||
61 | r = stat(tty, &st1); | |
62 | if (r < 0) | |
63 | ksft_exit_fail_msg("stat failed on tty path '%s': %m\n", tty); | |
64 | ||
65 | /* We need to wait at least 8 seconds in order to observe timestamp change */ | |
66 | /* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fbf47635315ab308c9b58a1ea0906e711a9228de */ | |
67 | sleep(10); | |
68 | ||
69 | r = write_dev_tty(); | |
70 | if (r < 0) | |
71 | ksft_exit_fail_msg("failed to write to /dev/tty: %s\n", | |
72 | strerror(-r)); | |
73 | ||
74 | r = stat(tty, &st2); | |
75 | if (r < 0) | |
76 | ksft_exit_fail_msg("stat failed on tty path '%s': %m\n", tty); | |
77 | ||
78 | /* We wrote to the terminal so timestamps should have been updated */ | |
79 | if (st1.st_atim.tv_sec == st2.st_atim.tv_sec && | |
80 | st1.st_mtim.tv_sec == st2.st_mtim.tv_sec) { | |
81 | ksft_test_result_fail("tty timestamps not updated\n"); | |
82 | ksft_exit_fail(); | |
83 | } | |
84 | ||
85 | ksft_test_result_pass( | |
86 | "timestamps of terminal '%s' updated after write to /dev/tty\n", tty); | |
87 | return EXIT_SUCCESS; | |
88 | } |