Je lis le code source de coreutils et je suis venu pour lire le code tty.c
La fonction principale de tty
est la suivante:
int main (int argc, char **argv) { char *tty; int optc; initialize_main (&argc, &argv); set_program_name (argv[0]); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); initialize_exit_failure (TTY_WRITE_ERROR); atexit (close_stdout); silent = false; while ((optc = getopt_long (argc, argv, "s", longopts, NULL)) != -1) { switch (optc) { case 's': silent = true; break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: usage (TTY_FAILURE); } } if (optind < argc) error (0, 0, _("extra operand %s"), quote (argv[optind])); tty = ttyname (STDIN_FILENO); if (!silent) { if (tty) puts (tty); else puts (_("not a tty")); } exit (isatty (STDIN_FILENO) ? EXIT_SUCCESS : EXIT_FAILURE); }
Pour ma compréhension de la ligne qui obtient le tty courant est tty = ttyname (STDIN_FILENO);
Mais quand je lance tty
utilisant strace
dans la sortie de strace
il n'y a pas d'appel à ttyname
. Quelle est la raison?
Voici la sortie de strace:
> strace -c tty /dev/pts/3 % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 0.00 0.000000 0 1 read 0.00 0.000000 0 1 write 0.00 0.000000 0 3 open 0.00 0.000000 0 5 close 0.00 0.000000 0 1 stat 0.00 0.000000 0 5 fstat 0.00 0.000000 0 10 mmap 0.00 0.000000 0 4 mprotect 0.00 0.000000 0 2 munmap 0.00 0.000000 0 3 brk 0.00 0.000000 0 2 ioctl 0.00 0.000000 0 1 1 access 0.00 0.000000 0 1 execve 0.00 0.000000 0 1 readlink 0.00 0.000000 0 1 arch_prctl ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000000 41 1 total
Aucun ttyname
n'est la list!
La raison en est que ttyname(3)
n'est pas un appel système , c'est une fonction de bibliothèque C. Vous pouvez vérifier sa mise en œuvre, par exemple dans la glibc
, pour voir quels appels système il utilise lui-même (et que vous verrez alors dans la sortie de strace
).
Pour tracer des appels de bibliothèque sur Linux, vous pouvez utiliser ltrace (qui peut également suivre les appels système). (Merci à Marki555 pour la suggestion.)