J’aurais besoin d’un système de fichiers bidirectionnel (c.-à-d. Un nœud de périphérique, un socket nommé, un tube nommé ou quelque chose comme ça) possibilité de communication interprocessus sous Linux (et peut-être aussi d’autres systèmes UNIX), disons un port série , c.-à-d. que vous pouvez ouvrir /dev/ttyS0
en lecture / écriture et que vous pouvez le lire / écrire avec n’importe quel outil (y compris une commande cat
simple), juste dans mon cas, l’autre partie mais processus totalement indépendant. Oui, j’ai déjà lu des questions similaires sur SO, mais je ne suis toujours pas sûr qu’il existe une autre solution similaire, si les canaux nommés ne correspondent pas à mes besoins ici.
Ce que je peux voir:
named pipe / FIFO n’est pas une solution car il est unidirectionnel (du moins sur certains systèmes UNIX, y compris Linux), deux canaux nommés (un pour RX et un pour TX) ne sont pas une solution.
Les sockets (nommés) ne sont pas une solution car ils nécessitent une attention particulière, je ne peux pas simplement faire écho à cela par exemple, mais je dois me connecter (), etc.
Je suis un peu incertain à propos de socketpair () car il crée deux sockets connectés, mais même cela, l’autre processus nécessite encore une préparation spéciale (le problème précédent dans ma liste)
openpty()
comme les astuces peuvent être une solution (et utiliser alors /dev/pts/...
par le client, je ne suis pas sûr sur OSX cependant), cependant c’est moche, pas si portable …
Des solutions comme un module de kernel ne sont pas une solution car elles ne sont pas du tout portables et nécessitent de toute façon un access root
les possibilités IPC basées sur des systèmes de fichiers ne sont pas non plus une solution pour moi, car la nature du problème
Le meilleur moyen serait un canal nommé bidirectionnel (un processus l’écrit, l’autre peut lire, et vice-versa, s’il est en semi-duplex, ce n’est pas vraiment un problème), ce qui fonctionne sur tous les systèmes UNIX. y compris au moins Linux et OSX, cependant je n’ai rien trouvé qui fonctionne comme ça.
Ce que je voudrais, c’est avoir un moyen d’émuler (à partir de l’espace utilisateur uniquement) quelque chose comme un port série, donc je peux même l’utiliser avec un simple terminal client (bien sûr, les ioctl pour configurer les parameters série pas un problème!), ou je peux simplement écrire / lire avec echo mmmmm > ...
ou cat ...
J’en aurais besoin pour un émulateur (d’un ordinateur) qui fournit quelque chose comme le port série d’une vraie machine, de sorte que je puisse interagir avec la machine émulée à travers elle. Je ne peux pas utiliser d’autres outils (comme socat
et utiliser des sockets nommés, ou même TCP / IP ou autre) puisque j’ai aussi un logiciel client source fermé que je ne peux pas changer, il attend un nom de fichier comme “périphérique de port série”, cependant j’ai testé qu’il n’échoue pas sur les différents appels ioctl () liés au port série heureusement (cela fonctionnerait sur des canaux nommés, seulement l’uni-directionnalité est mon problème alors), donc j’ai besoin de résoudre “seulement” ce problème, et ça marcherait.
Les seuls objects système qui vous permettent de read(2)
et d’ write(2)
sur chaque descripteur sont le socket et le pty. Ce sont les seuls objects qui ont deux files d’attente pour envoyer et recevoir des données. Tous les autres éléments de canal n’en ont qu’un, et lorsque vous recevez une paire de descripteurs (pour des canaux sans nom, par exemple), ce que vous écrivez sera reçu immédiatement si vous le lisez ensuite.
Je ne recommande pas l’utilisation de l’interface pty dans ce cas, car comme vous l’avez dit, vous devez faire un peu de ménage avant de pouvoir transmettre et vous devez gérer les parameters de périphérique (comme termios
config, baudrate et le niveau de l’appareil)
getsocketpair(3)
est une fonction de bibliothèque qui vous donne déjà une paire de sockets déjà connectées , et vous permet de spécifier le type de sockets (sockets réseau, sockets unix, etc.) que vous aimez dans l’appel.
int res, sfds[2]; res = getsocketpair(PF_LOCAL, SOCK_STREAM, 0, sfds);
renverra 0
en cas de succès et deux sockets déjà connectées dans le tableau sfds
. Dans les systèmes BSD (comme dérive OS / X), getsocketpair(2)
est un appel système qui permet au kernel de sélectionner une version efficace (comme le montre l’exemple) qui n’a pas la surcharge imposée par les protocoles réseau.
Comme vous le dites dans les commentaires, il est probable que vos programmes non seulement read(2)
et write(2)
appels, mais qu’ils reçoivent aussi des entrées brutes de l’utilisateur entrée brute en tant que programmes interactifs, comme vi(1)
ou emacs(1)
)
Dans ce cas, je vous suggère de télécharger mon programme slowtty
et d’étudier et de le modifier pour qu’il fonctionne pour vous. Il fait exactement ce que vous voulez. Il alloue une paire de pty
s et fait des entrées / sorties. Vous devez également utiliser une ligne tty, mais uniquement parce qu’elle copie les parameters du terminal depuis votre stdin vers la ligne pty. C’est un programme simple, conçu simplement pour apprendre aux gens à utiliser l’interface pty(7)
, et cela fonctionne très bien avec FreeBSD, Mac / OS X et Linux. En tant que tel, le programme ralentit l’entrée / sortie tty sur le débit en bauds ajusté dans l’esclave esclave, il vous permet donc de voir la sortie comme si vous utilisiez une ancienne ligne série tty. Le ralentissement se fait dans une routine distincte, ce qui permet de l’éliminer facilement du code source.