Host-Key-Popup mit Fingerprint + ctty-run-Helper (Ctty fuer ssh-Prompts), Doku
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
// ctty-run: gibt dem Kindprozess ein Controlling-Terminal auf dem PTY-Slave.
|
||||
// Usage: ctty-run <slave-pfad> <programm> [args...]
|
||||
// stdin/stdout zeigen dabei bereits auf den Slave (vom Parent gesetzt),
|
||||
// stderr bleibt unberührt (Eltern-Pipe für garantierte Fehlerausgabe).
|
||||
//
|
||||
// Warum Double-Fork: Apples Process startet Kinder in eigener Prozessgruppe,
|
||||
// daher schlägt setsid() im direkten Kind mit EPERM fehl. Der Wächter forkt
|
||||
// einmal weiter (Enkel = kein Leader mehr), wartet auf ihn und übernimmt
|
||||
// dessen Exit-Code — Lifecycle/Exit-Codes bleiben für den Parent korrekt.
|
||||
// Der Enkel: setsid() -> Slave einmal öffnen (wird dadurch Ctty) -> exec.
|
||||
// Ohne Ctty scheitern ssh-Passwort- und Yes/No-Prompts still (/dev/tty ENXIO).
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
dprintf(STDERR_FILENO, "usage: ctty-run <slave> <prog> [args...]\n");
|
||||
return 2;
|
||||
}
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
dprintf(STDERR_FILENO, "ctty-run: fork: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if (pid > 0) {
|
||||
/* Wächter: keine FDs offen halten (sonst nie EOF), aufs Kind warten. */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
int st = 0;
|
||||
while (waitpid(pid, &st, 0) < 0 && errno == EINTR)
|
||||
;
|
||||
if (WIFEXITED(st))
|
||||
return WEXITSTATUS(st);
|
||||
return 128;
|
||||
}
|
||||
/* Enkel: eigene Session; danach Slave-Open = Ctty. */
|
||||
if (setsid() < 0) {
|
||||
dprintf(STDERR_FILENO, "ctty-run: setsid: %s (weiter ohne Ctty)\n",
|
||||
strerror(errno));
|
||||
}
|
||||
int fd = open(argv[1], O_RDWR);
|
||||
if (fd < 0) {
|
||||
dprintf(STDERR_FILENO, "ctty-run: open slave: %s\n", strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
close(fd); /* Ctty bleibt der Session erhalten */
|
||||
execvp(argv[2], &argv[2]);
|
||||
dprintf(STDERR_FILENO, "ctty-run: execvp: %s\n", strerror(errno));
|
||||
_exit(127);
|
||||
}
|
||||
Reference in New Issue
Block a user