aboutsummaryrefslogtreecommitdiff
path: root/chardev
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2022-03-23 19:57:16 +0400
committerPaolo Bonzini <pbonzini@redhat.com>2022-04-06 10:50:37 +0200
commit3f6c2e8b79504e20bec8628f0f1accf3bc6d85b6 (patch)
tree42121b5df6b2d63eaa12b9259c6d39ee1e0e62f0 /chardev
parent9d587100ff115c05da188e524d70a6a782a5d80c (diff)
char: move qemu_openpty_raw from util/ to char/
It is only needed by char-pty. Fix the code style while at it. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20220323155743.1585078-6-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'chardev')
-rw-r--r--chardev/char-pty.c111
-rw-r--r--chardev/meson.build4
2 files changed, 113 insertions, 2 deletions
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index a2d1e7c985..d73d8b2390 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -197,6 +197,117 @@ static void char_pty_finalize(Object *obj)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
+#if defined HAVE_PTY_H
+# include <pty.h>
+#elif defined CONFIG_BSD
+# include <termios.h>
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+# include <libutil.h>
+# else
+# include <util.h>
+# endif
+#elif defined CONFIG_SOLARIS
+# include <termios.h>
+# include <stropts.h>
+#else
+# include <termios.h>
+#endif
+
+#ifdef __sun__
+
+#if !defined(HAVE_OPENPTY)
+/* Once illumos has openpty(), this is going to be removed. */
+static int openpty(int *amaster, int *aslave, char *name,
+ struct termios *termp, struct winsize *winp)
+{
+ const char *slave;
+ int mfd = -1, sfd = -1;
+
+ *amaster = *aslave = -1;
+
+ mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
+ if (mfd < 0) {
+ goto err;
+ }
+
+ if (grantpt(mfd) == -1 || unlockpt(mfd) == -1) {
+ goto err;
+ }
+
+ if ((slave = ptsname(mfd)) == NULL) {
+ goto err;
+ }
+
+ if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1) {
+ goto err;
+ }
+
+ if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
+ (termp != NULL && tcgetattr(sfd, termp) < 0)) {
+ goto err;
+ }
+
+ *amaster = mfd;
+ *aslave = sfd;
+
+ if (winp) {
+ ioctl(sfd, TIOCSWINSZ, winp);
+ }
+
+ return 0;
+
+err:
+ if (sfd != -1) {
+ close(sfd);
+ }
+ close(mfd);
+ return -1;
+}
+#endif
+
+static void cfmakeraw (struct termios *termios_p)
+{
+ termios_p->c_iflag &=
+ ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
+ termios_p->c_oflag &= ~OPOST;
+ termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ termios_p->c_cflag &= ~(CSIZE | PARENB);
+ termios_p->c_cflag |= CS8;
+
+ termios_p->c_cc[VMIN] = 0;
+ termios_p->c_cc[VTIME] = 0;
+}
+#endif
+
+/* like openpty() but also makes it raw; return master fd */
+static int qemu_openpty_raw(int *aslave, char *pty_name)
+{
+ int amaster;
+ struct termios tty;
+#if defined(__OpenBSD__) || defined(__DragonFly__)
+ char pty_buf[PATH_MAX];
+#define q_ptsname(x) pty_buf
+#else
+ char *pty_buf = NULL;
+#define q_ptsname(x) ptsname(x)
+#endif
+
+ if (openpty(&amaster, aslave, pty_buf, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ /* Set raw attributes on the pty. */
+ tcgetattr(*aslave, &tty);
+ cfmakeraw(&tty);
+ tcsetattr(*aslave, TCSAFLUSH, &tty);
+
+ if (pty_name) {
+ strcpy(pty_name, q_ptsname(amaster));
+ }
+
+ return amaster;
+}
+
static void char_pty_open(Chardev *chr,
ChardevBackend *backend,
bool *be_opened,
diff --git a/chardev/meson.build b/chardev/meson.build
index 325ba2bdb9..664f77b887 100644
--- a/chardev/meson.build
+++ b/chardev/meson.build
@@ -12,11 +12,11 @@ chardev_ss.add(files(
'char-udp.c',
'char.c',
))
-chardev_ss.add(when: 'CONFIG_POSIX', if_true: files(
+chardev_ss.add(when: 'CONFIG_POSIX', if_true: [files(
'char-fd.c',
'char-parallel.c',
'char-pty.c',
-))
+), util])
chardev_ss.add(when: 'CONFIG_WIN32', if_true: files(
'char-console.c',
'char-win-stdio.c',