Skip to content

Commit e8cc334

Browse files
msekletargregkh
authored andcommitted
selftests: tty: add selftest for tty timestamp updates
Add new test case which checks that timestamp updates on actual terminal character device (e.g. /dev/pts/0) happen even if the terminal is accessed via magic /dev/tty file. Signed-off-by: Michal Sekletar <msekleta@redhat.com> Message-ID: <20230613172107.78138-2-msekleta@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 360c11e commit e8cc334

4 files changed

Lines changed: 96 additions & 0 deletions

File tree

tools/testing/selftests/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ TARGETS += timers
8686
endif
8787
TARGETS += tmpfs
8888
TARGETS += tpm2
89+
TARGETS += tty
8990
TARGETS += user
9091
TARGETS += vDSO
9192
TARGETS += mm
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
tty_tstamp_update
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
CFLAGS = -O2 -Wall
3+
TEST_GEN_PROGS := tty_tstamp_update
4+
5+
include ../lib.mk
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
}

0 commit comments

Comments
 (0)