main terminal.c
 1#include <sys/types.h>
 2#include <sys/stat.h>
 3#include <unistd.h>
 4#include <fcntl.h>
 5#include <stdlib.h>
 6#include <stdint.h>
 7#include <signal.h>
 8#include "util.h"
 9#include "terminal.h"
10
11pid_t child;
12
13void cleanup_terminal()
14{
15	kill(child, SIGKILL);
16	unlink(INPUT_PATH);
17	unlink(OUTPUT_PATH);
18}
19
20static char init_done;
21
22void force_no_terminal()
23{
24	init_done = 1;
25}
26
27void init_terminal()
28{
29	if (!init_done) {
30		if (!(isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))) {
31#ifndef __APPLE__
32			//check to see if x-terminal-emulator exists, just use xterm if it doesn't
33			char *term = system("which x-terminal-emulator > /dev/null") ? "xterm" : "x-terminal-emulator";
34#endif
35			//get rid of FIFO's if they already exist
36			unlink(INPUT_PATH);
37			unlink(OUTPUT_PATH);
38			//create FIFOs for talking to helper process in terminal app
39			mkfifo(INPUT_PATH, 0666);
40			mkfifo(OUTPUT_PATH, 0666);
41
42			//close existing file descriptors
43			close(STDIN_FILENO);
44			close(STDOUT_FILENO);
45			close(STDERR_FILENO);
46
47			child = fork();
48			if (child == -1) {
49				//error, oh well
50				warning("Failed to fork for terminal spawn");
51			} else if (!child) {
52				//child process, exec our terminal emulator
53#ifdef __APPLE__
54				execlp("open", "open", "./termhelper", NULL);
55#else
56				execlp(term, term, "-title", "BlastEm Debugger", "-e", "./termhelper", NULL);
57#endif
58			} else {
59				//connect to the FIFOs, these will block so order is important
60				open(INPUT_PATH, O_RDONLY);
61				open(OUTPUT_PATH, O_WRONLY);
62				atexit(cleanup_terminal);
63				if (-1 == dup(STDOUT_FILENO)) {
64					fatal_error("failed to dup STDOUT to STDERR after terminal fork");
65				}
66			}
67		}
68
69		init_done = 1;
70	}
71}