8 changed files with 219 additions and 62 deletions
@ -0,0 +1,29 @@ |
|||
// See LICENSE for license details.
|
|||
|
|||
// termios-xspike sets up a canonical terminal and blocks forever.
|
|||
// It allows us to send Ctrl-C etc. to the target machine.
|
|||
|
|||
#include <unistd.h> |
|||
#include <termios.h> |
|||
#include <signal.h> |
|||
#include <assert.h> |
|||
#include <stdlib.h> |
|||
#include <stdio.h> |
|||
|
|||
int main() |
|||
{ |
|||
struct termios old_tios; |
|||
if (tcgetattr(0, &old_tios) < 0) |
|||
return -1; |
|||
|
|||
signal(SIGTERM, [](int) { }); |
|||
|
|||
struct termios new_tios = old_tios; |
|||
new_tios.c_lflag &= ~(ICANON | ECHO | ISIG); |
|||
if (tcsetattr(0, TCSANOW, &new_tios) < 0) |
|||
return -1; |
|||
|
|||
pause(); |
|||
|
|||
return tcsetattr(0, TCSANOW, &old_tios); |
|||
} |
|||
@ -0,0 +1,96 @@ |
|||
// See LICENSE for license details.
|
|||
|
|||
// xspike forks an xterm for spike's target machine console,
|
|||
// preserving the current terminal for debugging.
|
|||
|
|||
#include <unistd.h> |
|||
#include <fcntl.h> |
|||
#include <signal.h> |
|||
#include <sys/wait.h> |
|||
#include <cstdio> |
|||
#include <climits> |
|||
#include <cstring> |
|||
#include <stdexcept> |
|||
|
|||
static pid_t fork_spike(int tty_fd, int argc, char** argv); |
|||
static pid_t fork_xterm(int* tty_fd); |
|||
|
|||
int main(int argc, char** argv) |
|||
{ |
|||
int tty_fd, wait_status, ret = -1; |
|||
pid_t xterm, spike; |
|||
|
|||
static bool signal_exit = false; |
|||
auto handle_signal = [](int) { signal_exit = true; }; |
|||
signal(SIGINT, handle_signal); |
|||
|
|||
if ((xterm = fork_xterm(&tty_fd)) < 0) |
|||
{ |
|||
fprintf(stderr, "could not open xterm\n"); |
|||
goto out; |
|||
} |
|||
|
|||
if ((spike = fork_spike(tty_fd, argc, argv)) < 0) |
|||
{ |
|||
fprintf(stderr, "could not open spike\n"); |
|||
goto close_xterm; |
|||
} |
|||
|
|||
while (waitpid(spike, &wait_status, 0) < 0 && !signal_exit) |
|||
; |
|||
ret = !signal_exit && WIFEXITED(wait_status) ? WEXITSTATUS(wait_status) : -1; |
|||
|
|||
close_xterm: |
|||
kill(-xterm, SIGTERM); |
|||
out: |
|||
return ret; |
|||
} |
|||
|
|||
static pid_t fork_spike(int tty_fd, int argc, char** argv) |
|||
{ |
|||
pid_t pid = fork(); |
|||
if (pid < 0) |
|||
return -1; |
|||
|
|||
if (pid == 0) |
|||
{ |
|||
if (dup2(tty_fd, STDIN_FILENO) < 0 || dup2(tty_fd, STDOUT_FILENO) < 0) |
|||
return -1; |
|||
execvp("spike", argv); |
|||
return -1; |
|||
} |
|||
|
|||
return pid; |
|||
} |
|||
|
|||
static pid_t fork_xterm(int* tty_fd) |
|||
{ |
|||
static const char cmd[] = "3>&1 xterm -title xspike -e sh -c 'tty 1>&3; termios-xspike'"; |
|||
|
|||
int fds[2]; |
|||
if (pipe(fds) < 0) |
|||
return -1; |
|||
|
|||
pid_t pid = fork(); |
|||
if (pid < 0) |
|||
return -1; |
|||
|
|||
if (pid == 0) |
|||
{ |
|||
setpgid(0, 0); |
|||
if (dup2(fds[1], STDOUT_FILENO) < 0) |
|||
return -1; |
|||
execl("/bin/sh", "sh", "-c", cmd, NULL); |
|||
return -1; |
|||
} |
|||
|
|||
char tty[NAME_MAX]; |
|||
ssize_t ttylen = read(fds[0], tty, sizeof(tty)); |
|||
if (ttylen <= 1 || tty[ttylen-1] != '\n') |
|||
return -1; |
|||
tty[ttylen-1] = '\0'; |
|||
if ((*tty_fd = open(tty, O_RDWR)) < 0) |
|||
return -1; |
|||
|
|||
return pid; |
|||
} |
|||
Loading…
Reference in new issue