qemu-openpty.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * qemu-openpty.c
  3. *
  4. * Copyright (c) 2003-2008 Fabrice Bellard
  5. * Copyright (c) 2010 Red Hat, Inc.
  6. *
  7. * Wrapper function qemu_openpty() implementation.
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. */
  27. /*
  28. * This is not part of oslib-posix.c because this function
  29. * uses openpty() which often in -lutil, and if we add this
  30. * dependency to oslib-posix.o, every app will have to be
  31. * linked with -lutil.
  32. */
  33. #include "qemu/osdep.h"
  34. #include "qemu-common.h"
  35. #if defined(__GLIBC__)
  36. # include <pty.h>
  37. #elif defined CONFIG_BSD
  38. # include <termios.h>
  39. # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
  40. # include <libutil.h>
  41. # else
  42. # include <util.h>
  43. # endif
  44. #elif defined CONFIG_SOLARIS
  45. # include <termios.h>
  46. # include <stropts.h>
  47. #else
  48. # include <termios.h>
  49. #endif
  50. #ifdef __sun__
  51. /* Once Solaris has openpty(), this is going to be removed. */
  52. static int openpty(int *amaster, int *aslave, char *name,
  53. struct termios *termp, struct winsize *winp)
  54. {
  55. const char *slave;
  56. int mfd = -1, sfd = -1;
  57. *amaster = *aslave = -1;
  58. mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
  59. if (mfd < 0)
  60. goto err;
  61. if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
  62. goto err;
  63. if ((slave = ptsname(mfd)) == NULL)
  64. goto err;
  65. if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
  66. goto err;
  67. if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
  68. (termp != NULL && tcgetattr(sfd, termp) < 0))
  69. goto err;
  70. if (amaster)
  71. *amaster = mfd;
  72. if (aslave)
  73. *aslave = sfd;
  74. if (winp)
  75. ioctl(sfd, TIOCSWINSZ, winp);
  76. return 0;
  77. err:
  78. if (sfd != -1)
  79. close(sfd);
  80. close(mfd);
  81. return -1;
  82. }
  83. static void cfmakeraw (struct termios *termios_p)
  84. {
  85. termios_p->c_iflag &=
  86. ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
  87. termios_p->c_oflag &= ~OPOST;
  88. termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
  89. termios_p->c_cflag &= ~(CSIZE|PARENB);
  90. termios_p->c_cflag |= CS8;
  91. termios_p->c_cc[VMIN] = 0;
  92. termios_p->c_cc[VTIME] = 0;
  93. }
  94. #endif
  95. int qemu_openpty_raw(int *aslave, char *pty_name)
  96. {
  97. int amaster;
  98. struct termios tty;
  99. #if defined(__OpenBSD__) || defined(__DragonFly__)
  100. char pty_buf[PATH_MAX];
  101. #define q_ptsname(x) pty_buf
  102. #else
  103. char *pty_buf = NULL;
  104. #define q_ptsname(x) ptsname(x)
  105. #endif
  106. if (openpty(&amaster, aslave, pty_buf, NULL, NULL) < 0) {
  107. return -1;
  108. }
  109. /* Set raw attributes on the pty. */
  110. tcgetattr(*aslave, &tty);
  111. cfmakeraw(&tty);
  112. tcsetattr(*aslave, TCSAFLUSH, &tty);
  113. if (pty_name) {
  114. strcpy(pty_name, q_ptsname(amaster));
  115. }
  116. return amaster;
  117. }