Au début, j'ai essayé de remonter quelques secondes xterm
au xterm
pid en fonction des informations que j'ai trouvées, /proc/locks
mais c'était lâche. Je veux dire, cela a fonctionné, je pense, mais c'était au mieux circonstanciel - je ne comprends pas complètement toutes les informations que le fichier fournit et ne correspondait qu'à ce qui semblait correspondre entre son contenu et les processus terminaux connus.
Ensuite, j'ai essayé de regarder lsof/strace
un write/talk
processus actif entre ptys. Je n'avais jamais utilisé aucun des deux programmes auparavant, mais ils semblent s'appuyer sur eux utmp
. Si mon pty ciblé n'avait pas d' utmp
entrée pour une raison quelconque, ils refusaient tous les deux d'admettre qu'elle existait. Peut-être qu'il y a un moyen de contourner cela, mais j'étais assez confus pour l'abandonner.
J'ai essayé une udevadm
découverte avec 136 et 128 nœuds de périphérique de nombre majeur comme annoncé pts
et ptm
respectivement /proc/tty/drivers
, mais je manque également d'expérience très utile avec cet outil et encore une fois rien de substantiel. Fait intéressant, cependant, j'ai remarqué que la :min
plage des deux types d'appareils était répertoriée de manière stupéfiante 0-1048575
.
Ce n'est que lorsque j'ai revu ce document sur le noyau que j'ai commencé à penser au problème en termes de mount
s. J'avais lu cela plusieurs fois auparavant, mais lorsque des recherches continues dans ce domaine m'ont amené à ce patchset 2012,/dev/pts
j'ai eu une idée:
sudo fuser -v /dev/ptmx
J'ai pensé à ce que j'utilise habituellement pour associer des processus à un mount
? Et bien sûr:
USER PID ACCESS COMMAND
/dev/ptmx: root 410 F.... kmscon
mikeserv 710 F.... terminology
Donc, avec ces informations, je peux faire, par exemple à partir de terminology
:
sudo sh -c '${cmd:=grep rchar /proc/410/io} && printf 1 >/dev/pts/0 && $cmd'
###OUTPUT###
rchar: 667991010
rchar: 667991011
Comme vous pouvez le voir, avec un peu de test explicite, un tel processus pourrait être fait pour produire de manière assez fiable le processus maître d'un pty arbitraire. En ce qui concerne les sockets, je suis assez certain que l'on pourrait l'approcher dans cette direction en utilisant socat
plutôt qu'un débogueur, mais je n'ai pas encore expliqué comment. Pourtant, je pense que cela ss
pourrait aider si vous le connaissez mieux que moi:
sudo sh -c 'ss -oep | grep "$(printf "pid=%s\n" $(fuser /dev/ptmx))"'
Je l'ai donc configuré avec des tests un peu plus explicites, en fait:
sudo sh <<\CMD
chkio() {
read io io <$1
dd bs=1 count=$$ </dev/zero >$2 2>/dev/null
return $((($(read io io <$1; echo $io)-io)!=$$))
}
for pts in /dev/pts/[0-9]* ; do
for ptm in $(fuser /dev/ptmx 2>/dev/null)
do chkio /proc/$ptm/io $pts && break
done && set -- "$@" "$ptm owns $pts"
done
printf %s\\n "$@"
CMD
Il imprime $$
num \0
octets nuls à chaque pty et vérifie l'io de chaque processus maître par rapport à une vérification précédente. Si la différence est $$
alors il associe le pid au pty. Cela fonctionne principalement . Je veux dire, pour moi, ça revient:
410 owns /dev/pts/0
410 owns /dev/pts/1
710 owns /dev/pts/2
Ce qui est correct, mais, évidemment, c'est un peu racé. Je veux dire, si l'un de ces autres lisait un tas de données à l'époque, il manquerait probablement. J'essaie de comprendre comment changer les stty
modes sur un autre pty afin d'envoyer le bit d'arrêt en premier ou quelque chose comme ça pour que je puisse résoudre ce problème.
sudo find /proc/*/fd/0 -ls | grep '/dev/pts/4'
, fournirait la liste des PID (/proc/PID
) en sortie.