Ich versuche, einen Pager in C zu implementieren, ich möchte den Code ein anderes Terminal öffnen (xterm
) und einige Ausgaben in es drucken.Xterm Pager - zwei Terminal-Ausgang - mit Rohr und dup2
Also erstelle ich zuerst eine Pipe und fork das Hauptprogramm, das Kind wird xterm mit dem Tail-Befehl ausführen, das Hauptprogramm wird Dinge in der Pipe ausgeben und das Kind vor der Ausführung von xterm wird die Pipe mit der stdin verbinden Dateibeschreibung des Kindes.
Ich habe möglicherweise die Verwendung von pipe
und dup2
missverstanden, weil mein Code nicht funktioniert.
int p[2];
pipe(p);
char buff[512];
switch (fork()) {
case -1:
fprintf(stderr, "Fork error.\n");
break;
case 0:
dup2(p[0], 0);
close(p[0]);
close(p[1]);
execlp("xterm", "xterm", "tail", NULL);
break;
default:
scanf("%s", buff);
write(p[1], buff, strlen(buff));
getchar();
break;
}
Für jetzt tippe ich etwas in den Eltern und nichts wird in beiden Prozess gedruckt. Also, wie erstelle ich eine Kommunikation zwischen Xterm und dem übergeordneten Prozess?
Edit: eine Probe von meinem Programm:
#define VERBM_NOVERB 0
#define VERBM_STDOUT 1
#define VERBM_XTERMO 2
static int fd_xterm = -1;
void init_outputxterm() {
mkfifo("/tmp/mypipe", 0600);
switch (fork()) {
case -1:
fprintf(stderr, "Fork error.\n");
break;
case 0:
execlp("xterm", "xterm", "-e", "/usr/bin/tail -f /tmp/mypipe", NULL);
printf("FAILURE\n");
exit(EXIT_FAILURE);
break;
default:
if ((fd_xterm = open("/tmp/mypipe", O_WRONLY)) == -1) {
fprintf(stderr, "Can't open pipe");
exit(1);
}
write(fd_xterm, "yayay\n", 6);
dprintf(fd_xterm, "Hello world\n");
getchar();
break;
}
}
void verbose_xterm(char *format, ...) {
dprintf(fd_xterm, BOLD UNDERLINED "verbose - " RESET);
va_list aptr;
va_start(aptr, format);
dprintf(fd_xterm, format, aptr);
va_end(aptr);
}
void verbose_stdout(char *format, ...) {
printf(BOLD UNDERLINED "verbose - " RESET);
va_list aptr;
va_start(aptr, format);
vprintf(format, aptr);
va_end(aptr);
}
void verbose_noverb(char *format, ...) {
}
void (*verbose)(char *format, ...) = verbose_stdout;
void (*verbose_mode[])(char *, ...) = {
verbose_noverb,
verbose_stdout,
verbose_xterm
};
void verbosity(int mode) {
if (mode == VERBM_XTERMO)
init_outputxterm();
verbose = verbose_mode[mode];
}
Im Haupt:
verbosity(VERBM_XTERMO);
Gefolgt von mehreren Anrufen zu verbose
. Sie können in init_outputxterm
ein Tentavie in Xterm kurz nach der Erstellung von Xterm, wie in der Lösung zu schreiben. Aber alles wird erst angezeigt, nachdem ich das Programm beendet habe, indem ich das Hauptterminal brutal geschlossen habe, damit das Kind Waisenkind wird (wenn ich mit Ctrl-C
aufhöre, wird das Kind ebenfalls getötet).
Ich weiß nicht warum, aber xterm öffnet einfach und schließt sofort mit diesem Code ... –
Vielleicht ist der Pfad zu deinem 'tail' anders oder die Pipe'/tmp/mypipe' wurde aus irgendeinem Grund nicht korrekt erstellt ? – Ctx
Es funktioniert, danke! Das Problem kam von meinem tiling window manager, i3, weil das Hauptterminal im Floating-Modus gestartet wurde und i3 nicht wusste, wie das Pop-up-Fenster zu verwalten ist. Das wird gelöst, indem das Hauptterminal im Tiling-Modus läuft. –