1 // See LICENSE for license details.
3 // xspike forks an xterm for spike's target machine console,
4 // preserving the current terminal for debugging.
15 static pid_t
fork_spike(int tty_fd
, int argc
, char** argv
);
16 static pid_t
fork_xterm(int* tty_fd
);
18 int main(int argc
, char** argv
)
20 int tty_fd
, wait_status
, ret
= -1;
23 static bool signal_exit
= false;
24 auto handle_signal
= [](int) { signal_exit
= true; };
26 if ((xterm
= fork_xterm(&tty_fd
)) < 0)
28 fprintf(stderr
, "could not open xterm\n");
32 signal(SIGINT
, handle_signal
);
34 if ((spike
= fork_spike(tty_fd
, argc
, argv
)) < 0)
36 fprintf(stderr
, "could not open spike\n");
40 while ((ret
= waitpid(spike
, &wait_status
, 0)) < 0)
44 if (ret
< 0) // signal_exit
47 ret
= WIFEXITED(wait_status
) ? WEXITSTATUS(wait_status
) : -1;
50 kill(-xterm
, SIGTERM
);
55 static pid_t
fork_spike(int tty_fd
, int argc
, char** argv
)
63 if (dup2(tty_fd
, STDIN_FILENO
) < 0 || dup2(tty_fd
, STDOUT_FILENO
) < 0)
65 execvp("spike", argv
);
72 static pid_t
fork_xterm(int* tty_fd
)
74 static const char cmd
[] = "3>&1 xterm -title xspike -e sh -c 'tty 1>&3; termios-xspike'";
87 if (dup2(fds
[1], STDOUT_FILENO
) < 0)
89 execl("/bin/sh", "sh", "-c", cmd
, NULL
);
94 ssize_t ttylen
= read(fds
[0], tty
, sizeof(tty
));
95 if (ttylen
<= 1 || tty
[ttylen
-1] != '\n')
98 if ((*tty_fd
= open(tty
, O_RDWR
)) < 0)