getty.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * runs a proper tty on a serial port
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <pty.h>
  9. #include <sys/wait.h>
  10. #include <sys/fswait.h>
  11. int main(int argc, char * argv[]) {
  12. int fd_master, fd_slave, fd_serial;
  13. char * file = "/dev/ttyS0";
  14. if (getuid() != 0) {
  15. fprintf(stderr, "%s: only root can do that\n", argv[0]);
  16. return 1;
  17. }
  18. if (argc > 1) {
  19. file = argv[1];
  20. }
  21. openpty(&fd_master, &fd_slave, NULL, NULL, NULL);
  22. fd_serial = open(file, O_RDWR);
  23. pid_t child = fork();
  24. if (!child) {
  25. dup2(fd_slave, 0);
  26. dup2(fd_slave, 1);
  27. dup2(fd_slave, 2);
  28. system("ttysize -q");
  29. char * tokens[] = {"/bin/login",NULL};
  30. execvp(tokens[0], tokens);
  31. exit(1);
  32. } else {
  33. int fds[2] = {fd_serial, fd_master};
  34. while (1) {
  35. int index = fswait2(2,fds,200);
  36. char buf[1024];
  37. int r;
  38. switch (index) {
  39. case 0: /* fd_serial */
  40. r = read(fd_serial, buf, 1);
  41. write(fd_master, buf, 1);
  42. break;
  43. case 1: /* fd_master */
  44. r = read(fd_master, buf, 1024);
  45. write(fd_serial, buf, r);
  46. break;
  47. default: /* timeout */
  48. {
  49. int result = waitpid(child, NULL, WNOHANG);
  50. if (result > 0) {
  51. /* Child login shell has returned (session ended) */
  52. return 0;
  53. }
  54. }
  55. break;
  56. }
  57. }
  58. }
  59. return 0;
  60. }