#include #ifdef __APPLE__ #include #include #else #include #endif #include #include #include // compile with gcc term.c -lutil int main(int argc, char **argv) { if (argc < 2) { printf("usage: %s ROM [LOGIN]\n", argv[0]); return 1; } char *rom = argv[1]; // find term.rom int login = argc > 2; // any extra arg signals login shell // detect the user's shell char *shell = getenv("SHELL"); if (shell == NULL) { struct passwd *passwd = getpwuid(getuid()); if (passwd != NULL) { shell = passwd->pw_shell; } } if (shell == NULL) { shell = "/bin/sh"; } // allocate a pty, fork, inititialize file descriptor int fdm = -1; // allocate file descriptor pid_t pid = forkpty(&fdm, NULL, NULL, NULL); if (pid < 0) { // failure perror("fork failed"); return 1; } else if (pid == 0) { // child setenv("TERM", "ansi", 1); // execute shell if (login) { execlp(shell, shell, "-l", "-i", NULL); } else { execlp(shell, shell, NULL); } perror("exec bash failed"); } else { // parent struct winsize ws = {23, 80, 8, 12}; // rows, cols, xps, ypx ioctl(fdm, TIOCSWINSZ, &ws); // set term window size dup2(fdm, 0); // use fdm for stdin dup2(fdm, 1); // use fdm for stdout execlp("uxnemu", "uxnemu", rom, NULL); // exec uxnemu perror("exec uxnemu failed"); } }