22#include "pedigree/native/input/Input.h"
38#include <pedigree/fb.h>
39#include <pedigree/log.h>
41#include <sys/select.h>
47pid_t g_RunningPid = -1;
52#define FIRST_PROGRAM "/usr/bin/login"
59int main(
int argc,
char** argv) {
60 pedigree_log(LOG_INFO,
"ttyterm: starting up...");
63 int fd = open(
"/run/ttyterm.lck", O_WRONLY | O_EXCL | O_CREAT);
65 fprintf(stderr,
"ttyterm: lock file exists, terminating.\n");
71 signal(SIGINT, sigint);
75 int fb = open(
"/dev/fb", O_RDWR);
78 pedigree_log(LOG_INFO,
"ttyterm: forcing text mode");
80 int rc = ioctl(fb, PEDIGREE_FB_SETMODE, &mode);
84 pedigree_log(LOG_INFO,
"ttyterm: couldn't force text mode, exiting");
90 int tty = open(
"/dev/textui", O_RDWR);
92 pedigree_log(LOG_ALERT,
"ttyterm: couldn't open /dev/textui: %s", strerror(errno));
98 int serial = open(
"/dev/ttyS0", O_RDWR);
100 pedigree_log(LOG_WARNING,
"ttyterm: couldn't open /dev/ttyS0: %s", strerror(errno));
103 g_MasterPty = posix_openpt(O_RDWR);
104 if (g_MasterPty < 0) {
106 pedigree_log(LOG_ALERT,
"ttyterm: couldn't get a pseudo-terminal to use: %s", strerror(errno));
111 struct winsize ptySize;
114 ioctl(g_MasterPty, TIOCSWINSZ, &ptySize);
116 char slavename[64] = {0};
117 strncpy(slavename, ptsname(g_MasterPty), 64);
121 write(tty,
"\e[2J", 5);
124 g_RunningPid = fork();
125 if (g_RunningPid == -1) {
126 pedigree_log(LOG_ALERT,
"ttyterm: couldn't fork: %s", strerror(errno));
128 }
else if (g_RunningPid == 0) {
139 int slave = open(slavename, O_RDWR);
141 pedigree_log(LOG_ALERT,
"ttyterm: couldn't open pty slave: %s", strerror(errno));
145 if (dup2(slave, STDIN_FILENO) < 0) {
146 pedigree_log(LOG_ALERT,
"ttyterm: couldn't attach pty slave to stdin: %s", strerror(errno));
151 if (slave > STDERR_FILENO) {
157 setenv(
"TERM",
"pedigree", 1);
160 setenv(
"LC_ALL",
"en_US.UTF-8", 1);
166 memset(&ut, 0,
sizeof(ut));
167 gettimeofday(&tv, NULL);
168 ut.ut_type = LOGIN_PROCESS;
169 ut.ut_pid = getpid();
171 strncpy(ut.ut_id,
"/",
sizeof(ut.ut_id));
172 strncpy(ut.ut_line,
"console", UT_LINESIZE);
177 write(slave,
"\e[?7h", 5);
179 pedigree_log(LOG_INFO,
"Starting up '" FIRST_PROGRAM
"' on pty %s", slavename);
180 execl(FIRST_PROGRAM, FIRST_PROGRAM, 0);
181 pedigree_log(LOG_ALERT,
182 "Launching " FIRST_PROGRAM
" failed (next line is the error in errno...)");
183 pedigree_log(LOG_ALERT,
"%s", strerror(errno));
188 const size_t maxBuffSize = 32768;
189 char buffer[maxBuffSize];
193 FD_SET(g_MasterPty, &fds);
195 int maxFd = g_MasterPty > tty ? g_MasterPty : tty;
197 FD_SET(serial, &fds);
198 if (serial > maxFd) {
205 struct timeval timeout = {0, 100000};
206 int nReady = select(maxFd + 1, &fds, NULL, NULL, &timeout);
209 if (FD_ISSET(g_MasterPty, &fds)) {
214 Input::inhibitEvents();
215 ssize_t len = read(g_MasterPty, buffer, maxBuffSize);
216 Input::uninhibitEvents();
218 write(tty, buffer, len);
220 write(serial, buffer, len);
226 if (FD_ISSET(tty, &fds)) {
227 ssize_t len = read(tty, buffer, maxBuffSize);
232 Input::inhibitEvents();
234 write(g_MasterPty, buffer, len);
235 Input::uninhibitEvents();
239 if (serial >= 0 && FD_ISSET(serial, &fds)) {
240 ssize_t len = read(serial, buffer, maxBuffSize);
242 Input::inhibitEvents();
244 write(g_MasterPty, buffer, len);
245 Input::uninhibitEvents();
All zeroes = 'revert to text mode'.