ptty.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <sys/wait.h>
  2. #include <errno.h>
  3. #include <inttypes.h>
  4. #include <limits.h>
  5. #include <stdarg.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <termios.h>
  10. #include <unistd.h>
  11. #if defined(__linux)
  12. #include <pty.h>
  13. #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
  14. #include <util.h>
  15. #elif defined(__FreeBSD__) || defined(__DragonFly__)
  16. #include <libutil.h>
  17. #endif
  18. void
  19. die(const char *fmt, ...)
  20. {
  21. va_list ap;
  22. va_start(ap, fmt);
  23. vfprintf(stderr, fmt, ap);
  24. va_end(ap);
  25. if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
  26. fputc(' ', stderr);
  27. perror(NULL);
  28. } else {
  29. fputc('\n', stderr);
  30. }
  31. exit(EXIT_FAILURE);
  32. }
  33. void
  34. usage(void)
  35. {
  36. fputs("ptty cmd\n", stderr);
  37. exit(EXIT_FAILURE);
  38. }
  39. int
  40. main(int argc, char *argv[])
  41. {
  42. struct winsize ws = {.ws_row = 25, .ws_col = 80, 0, 0};
  43. int ch;
  44. while ((ch = getopt(argc, argv, "c:r:h")) != -1) {
  45. switch (ch) {
  46. case 'c': /* cols */
  47. ws.ws_col = strtoimax(optarg, NULL, 10);
  48. if (errno != 0)
  49. die("strtoimax: %s", optarg);
  50. break;
  51. case 'r': /* lines */
  52. ws.ws_row = strtoimax(optarg, NULL, 10);
  53. if (errno != 0)
  54. die("strtoimax: %s", optarg);
  55. break;
  56. case 'h':
  57. default:
  58. usage();
  59. }
  60. }
  61. argc -= optind;
  62. argv += optind;
  63. if (argc < 1)
  64. usage();
  65. int mfd;
  66. pid_t pid = forkpty(&mfd, NULL, NULL, &ws);
  67. switch (pid) {
  68. case -1:
  69. die("forkpty");
  70. case 0: /* child */
  71. execvp(argv[0], argv);
  72. die("exec");
  73. }
  74. /* parent */
  75. FILE *fh = fdopen(mfd, "rw");
  76. if (fh == NULL)
  77. die("fdopen");
  78. if (close(mfd) == -1)
  79. die("close:");
  80. // char buf[BUFSIZ];
  81. // while (fgets(buf, sizeof buf, fh) != NULL);
  82. int status;
  83. waitpid(pid, &status, 0);
  84. return WEXITSTATUS(status);
  85. }