Programm1 redet normalerweise per /dev/ttyUSBx mit einer Hardware. Jetzt soll Programm2 diese Hardware simulieren. Prog1 kann einen symlink (z.B. "/tmp/hardware") für die Schnittstelle benutzen, dann sieht es sehr einfach aus:
1
pts=open("/dev/ptmx",O_RDONLY);
2
path=ptsname(pts);
3
grantpt(pts);
4
unlockpt(pts);
5
symlink(path,"/tmp/hardware");
so kann Prog1 sein normales open("/tmp/hardware") machen.
Jetzt muss man "nur noch" dafür sorgen, dass der Link entfernt wird, wenn Prog2 beendet wird. atexit() funktioniert dafür nur meistens. Ja, Prog1 könnte das pty in /proc/$(pidof Prog2)/fd/ suchen, aber wie macht man das normalerweise?
Den Symlink könnte man früher löschen - der kann weg sobald Prog1 sein
open() call ausgeführt hat.
Gute Idee, danke!
Ob das in der Praxis funktioniert ist zweifelhaft.
Meinst du das Link-löschen oder die Schnittstellenparameter? Es bleibt ein kleines Restrisiko: Prog2 startet, Prog1 aber nicht, Prog2 erwischt einen Segfault, Prog1 startet und findet den kaputten Link. Irgendwas ist immer; hauptsächlich wundert mich, dass es dafür scheinbar keinen Mechanismus gibt. So in der Art, wie z.B. Speicher garantiert freigegeben wird, egal, wie das Programm beendet wird.
Die ioctl() Syscalls funktionieren, praktisch als NOP. Nur das Timing ist natürlich völlig anders, dagegen reicht mir in diesem speziellen Fall ein usleep().
Den Symlink könnte man früher löschen - der kann weg sobald Prog1 sein
open() call ausgeführt hat.
Ob das in der Praxis funktioniert ist zweifelhaft.
Das gilt eigentlich für alle was über Filedescriptoren angesprochen wird. Mann kann das Objekt (File, (Sym)Link, Gerät, ...) auf Filesystem-Ebene hinterrücks löschen. Das Objekt bleibt trotzdem so lange erhalten bis der letzte Filedescriptor drauf zu gemacht wird.
Eine uralte, schon zu UNIX-Zeiten beliebte Technik um zum Beispiel temporäre Dateien automatisch zu löschen wenn der Prozess endet. Datei öffnen, Filedescriptor brav behalte, Datei im Filesystem löschen, frisch und fröhlich mit der nun unsichtbaren Datei über den Filedescriptor arbeiten. Der Prozess endet und Linux räumt erst dann die Datei ab.
Eine uralte, schon zu UNIX-Zeiten beliebte Technik um zum Beispiel
temporäre Dateien automatisch zu löschen wenn der Prozess endet. Datei
öffnen, Filedescriptor brav behalte, Datei im Filesystem löschen, frisch
und fröhlich mit der nun unsichtbaren Datei über den Filedescriptor
arbeiten. Der Prozess endet und Linux räumt erst dann die Datei ab.
Oder, wenn der Prozess weiter und weiter auf /tmp schreibt, gibt es eine panic und der Systemverwalter steht in Deinem Buero... Der schoene neue Convex-Supercomputer sollte fuer etwas gut sein...
Ja, Prog1 könnte das pty in /proc/$(pidof Prog2)/fd/ suchen, aber wie macht
man das normalerweise?
Da würde es aber doch nur das ptm, nicht das pts, finden.
Falls Programm 2 von Program 1 gestartet wird, könnte man Program 2 ein FD von Program 1 übergeben. Man könnte das pts öffnen und als FD 0,1,2 (stdin, stdout, stderr) setzen. Oder man könnte eine environment Variable oder einen Parameter setzen, und ihm so mitteilen, wo das pts zu finden ist.
(Mit /proc/self/fd/N kann man für FDs auch einen Dateipfad angeben. Aber ein open da drauf gibt eine neue File Description (nicht nur einen neuen File Descriptor). Beim pts kein Problem, bei (gelöschten) Dateien auch nicht. Aber z.B. bei einem fd auf ein ptm von /dev/ptmx bekäme man ein neues pts).
Ja, Prog1 könnte das pty in /proc/$(pidof Prog2)/fd/ suchen, aber wie macht
man das normalerweise?
Da würde es aber doch nur das ptm, nicht das pts, finden.
Stimmt auch wieder. Wenn man einem vorhandenen Programm eine Hardware vortäuschen will, kommt sowas ja sowieso nicht in Frage, da ist ein symlink vernünftig. Und im Normalfall, wenn beide Programme zusammenarbeiten, funktioniert ja alles automatisch richtig. Dankeschön!
Im Prinzip sollte kein Programm in einen segfault laufen, das wäre eigentlich das Maß der Dinge.
Man kann ansonsten alle anderen Sigs abfangen und abhandeln, dann wäre jede andere Möglichkeit den Symlink doch zu löschen abgedeckt.
Einen kritischen Segfault kann man verhindern indem man es richtig programmiert. man könnte auch bei jedem start des "Programm2" einen vorhandenen symlink löschen. Somit gäbe es keinen unlösbaren Worst case.
Wenn du auf beide Codes (Anwendung und Simulator) vollen Zugriff hast, könnte man auch auf unterster Ebene eine alternative Kommunikation einbauen, speziell für den Simu-Fall, z.B. per IP oder IPC oder schlicht ein File ...
Wenn du auf beide Codes (Anwendung und Simulator) vollen Zugriff hast,
könnte man auch auf unterster Ebene eine alternative Kommunikation...
hätte ich sogar, aber das geht in die falsche Richtung. So richtig "minimal-invasiv" ist nur ein Kabel und eine echte serielle Schnittstelle; dann stimmt auch das Timing ganz von alleine.