Add virFDStreamOpenPTY() function which is a wrapper around
virFDStreamOpenFileInternal() with putting the device it opens into a
raw mode.
Make virChrdevOpen() use virFDStreamOpenPTY() for
VIR_DOMAIN_CHR_TYPE_PTY devices.
This fixes mangled console output when libvirt runs on FreeBSD as it
requires device it opens to be placed into a raw mode explicitly.
---
src/conf/virchrdev.c | 2 +-
src/fdstream.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/fdstream.h | 5 +++++
3 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/src/conf/virchrdev.c b/src/conf/virchrdev.c
index 3e6beaa..2fd9a6c 100644
--- a/src/conf/virchrdev.c
+++ b/src/conf/virchrdev.c
@@ -408,7 +408,7 @@ int virChrdevOpen(virChrdevsPtr devs,
/* open the character device */
switch (source->type) {
case VIR_DOMAIN_CHR_TYPE_PTY:
- if (virFDStreamOpenFile(st, path, 0, 0, O_RDWR) < 0)
+ if (virFDStreamOpenPTY(st, path, 0, 0, O_RDWR) < 0)
goto error;
break;
case VIR_DOMAIN_CHR_TYPE_UNIX:
diff --git a/src/fdstream.c b/src/fdstream.c
index 04d62b8..39d58e0 100644
--- a/src/fdstream.c
+++ b/src/fdstream.c
@@ -31,6 +31,7 @@
# include <sys/un.h>
#endif
#include <netinet/in.h>
+#include <termios.h>
#include "fdstream.h"
#include "virerror.h"
@@ -714,6 +715,58 @@ int virFDStreamCreateFile(virStreamPtr st,
oflags | O_CREAT, mode);
}
+#ifdef HAVE_CFMAKERAW
+int virFDStreamOpenPTY(virStreamPtr st,
+ const char *path,
+ unsigned long long offset,
+ unsigned long long length,
+ int oflags)
+{
+ struct virFDStreamData *fdst = NULL;
+ struct termios rawattr;
+
+ if (virFDStreamOpenFileInternal(st, path,
+ offset, length,
+ oflags | O_CREAT, 0) < 0)
+ return -1;
+
+ fdst = st->privateData;
+
+ if (tcgetattr(fdst->fd, &rawattr) < 0) {
+ virReportSystemError(errno,
+ _("unable to get tty attributes: %s"),
+ path);
+ goto cleanup;
+ }
+
+ cfmakeraw(&rawattr);
+
+ if (tcsetattr(fdst->fd, TCSANOW, &rawattr) < 0) {
+ virReportSystemError(errno,
+ _("unable to set tty attributes: %s"),
+ path);
+ goto cleanup;
+ }
+
+ return 0;
+
+cleanup:
+ virFDStreamClose(st);
+ return -1;
+}
+#else /* !HAVE_CFMAKERAW */
+int virFDStreamOpenPTY(virStreamPtr st,
+ const char *path,
+ unsigned long long offset,
+ unsigned long long length,
+ int oflags)
+{
+ return virFDStreamOpenFileInternal(st, path,
+ offset, length,
+ oflags | O_CREAT, 0);
+}
+#endif /* !HAVE_CFMAKERAW */
+
int virFDStreamSetInternalCloseCb(virStreamPtr st,
virFDStreamInternalCloseCb cb,
void *opaque,
diff --git a/src/fdstream.h b/src/fdstream.h
index 3ca6256..9c7295d 100644
--- a/src/fdstream.h
+++ b/src/fdstream.h
@@ -54,6 +54,11 @@ int virFDStreamCreateFile(virStreamPtr st,
unsigned long long length,
int oflags,
mode_t mode);
+int virFDStreamOpenPTY(virStreamPtr st,
+ const char *path,
+ unsigned long long offset,
+ unsigned long long length,
+ int oflags);
int virFDStreamSetInternalCloseCb(virStreamPtr st,
virFDStreamInternalCloseCb cb,
--
1.8.4.2