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}