qemu-openpty.c (3877B)
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/* 29 * This is not part of oslib-posix.c because this function 30 * uses openpty() which often in -lutil, and if we add this 31 * dependency to oslib-posix.o, every app will have to be 32 * linked with -lutil. 33 */ 34 35#include "qemu/osdep.h" 36#include "qemu-common.h" 37 38#if defined HAVE_PTY_H 39# include <pty.h> 40#elif defined CONFIG_BSD 41# include <termios.h> 42# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 43# include <libutil.h> 44# else 45# include <util.h> 46# endif 47#elif defined CONFIG_SOLARIS 48# include <termios.h> 49# include <stropts.h> 50#else 51# include <termios.h> 52#endif 53 54#ifdef __sun__ 55 56#if !defined(HAVE_OPENPTY) 57/* Once illumos has openpty(), this is going to be removed. */ 58static int openpty(int *amaster, int *aslave, char *name, 59 struct termios *termp, struct winsize *winp) 60{ 61 const char *slave; 62 int mfd = -1, sfd = -1; 63 64 *amaster = *aslave = -1; 65 66 mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY); 67 if (mfd < 0) 68 goto err; 69 70 if (grantpt(mfd) == -1 || unlockpt(mfd) == -1) 71 goto err; 72 73 if ((slave = ptsname(mfd)) == NULL) 74 goto err; 75 76 if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1) 77 goto err; 78 79 if (ioctl(sfd, I_PUSH, "ptem") == -1 || 80 (termp != NULL && tcgetattr(sfd, termp) < 0)) 81 goto err; 82 83 *amaster = mfd; 84 *aslave = sfd; 85 86 if (winp) 87 ioctl(sfd, TIOCSWINSZ, winp); 88 89 return 0; 90 91err: 92 if (sfd != -1) 93 close(sfd); 94 close(mfd); 95 return -1; 96} 97#endif 98 99static void cfmakeraw (struct termios *termios_p) 100{ 101 termios_p->c_iflag &= 102 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 103 termios_p->c_oflag &= ~OPOST; 104 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 105 termios_p->c_cflag &= ~(CSIZE|PARENB); 106 termios_p->c_cflag |= CS8; 107 108 termios_p->c_cc[VMIN] = 0; 109 termios_p->c_cc[VTIME] = 0; 110} 111#endif 112 113int qemu_openpty_raw(int *aslave, char *pty_name) 114{ 115 int amaster; 116 struct termios tty; 117#if defined(__OpenBSD__) || defined(__DragonFly__) 118 char pty_buf[PATH_MAX]; 119#define q_ptsname(x) pty_buf 120#else 121 char *pty_buf = NULL; 122#define q_ptsname(x) ptsname(x) 123#endif 124 125 if (openpty(&amaster, aslave, pty_buf, NULL, NULL) < 0) { 126 return -1; 127 } 128 129 /* Set raw attributes on the pty. */ 130 tcgetattr(*aslave, &tty); 131 cfmakeraw(&tty); 132 tcsetattr(*aslave, TCSAFLUSH, &tty); 133 134 if (pty_name) { 135 strcpy(pty_name, q_ptsname(amaster)); 136 } 137 138 return amaster; 139}