tty_tstamp_update.c 2.1 KB

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