314 lines
5.9 KiB
Plaintext
314 lines
5.9 KiB
Plaintext
From ee5472d2a9dd38215d4d2349e95c07e92be9b063 Mon Sep 17 00:00:00 2001
|
|
From: Gerasim Troeglazov <3dEyes@gmail.com>
|
|
Date: Mon, 1 Nov 2021 09:20:04 +1000
|
|
Subject: Use bsd openpty for haiku
|
|
|
|
|
|
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
|
index d18c70f..2bfa926 100644
|
|
--- a/src/CMakeLists.txt
|
|
+++ b/src/CMakeLists.txt
|
|
@@ -2,7 +2,7 @@ add_library(KF5Pty)
|
|
add_library(KF5::Pty ALIAS KF5Pty)
|
|
|
|
target_sources(KF5Pty PRIVATE
|
|
- kpty.cpp
|
|
+ kpty_haiku.cpp
|
|
kptydevice.cpp
|
|
kptyprocess.cpp
|
|
)
|
|
@@ -26,7 +26,8 @@ target_link_libraries(KF5Pty PUBLIC Qt5::Core
|
|
KF5::CoreAddons # KProcess
|
|
PRIVATE
|
|
${UTIL_LIBRARY}
|
|
- KF5::I18n)
|
|
+ KF5::I18n
|
|
+ bsd)
|
|
|
|
target_include_directories(KF5Pty PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..)
|
|
|
|
@@ -80,7 +81,7 @@ endif()
|
|
|
|
########### next target ###############
|
|
|
|
-if (NOT HAVE_OPENPTY)
|
|
+if (NOT HAVE_OPENPTY AND NOT HAIKU)
|
|
add_executable(kgrantpty kgrantpty.c)
|
|
ecm_mark_nongui_executable(kgrantpty)
|
|
install(TARGETS kgrantpty DESTINATION ${KDE_INSTALL_LIBEXECDIR_KF5})
|
|
diff --git a/src/kpty_haiku.cpp b/src/kpty_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..7acd36d
|
|
--- /dev/null
|
|
+++ b/src/kpty_haiku.cpp
|
|
@@ -0,0 +1,266 @@
|
|
+#include "kpty_p.h"
|
|
+
|
|
+#include <kpty_debug.h>
|
|
+#include <QProcess>
|
|
+
|
|
+#include <sys/types.h>
|
|
+#include <sys/ioctl.h>
|
|
+#include <sys/time.h>
|
|
+#include <sys/resource.h>
|
|
+#include <sys/stat.h>
|
|
+#include <sys/param.h>
|
|
+
|
|
+#include <errno.h>
|
|
+#include <fcntl.h>
|
|
+#include <time.h>
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
+#include <unistd.h>
|
|
+#include <grp.h>
|
|
+
|
|
+#if HAVE_PTY_H
|
|
+# include <pty.h>
|
|
+#endif
|
|
+
|
|
+#if HAVE_LIBUTIL_H
|
|
+# include <libutil.h>
|
|
+#elif HAVE_UTIL_H
|
|
+# include <util.h>
|
|
+#endif
|
|
+
|
|
+extern "C" {
|
|
+#include <termios.h>
|
|
+#if HAVE_TERMIO_H
|
|
+# include <termio.h>
|
|
+#endif
|
|
+}
|
|
+
|
|
+#if HAVE_TCGETATTR
|
|
+# define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode)
|
|
+#endif
|
|
+
|
|
+#if HAVE_TCSETATTR
|
|
+# define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode)
|
|
+#endif
|
|
+
|
|
+#include <qplatformdefs.h>
|
|
+
|
|
+#include <Q_PID>
|
|
+
|
|
+#ifndef PATH_MAX
|
|
+# ifdef MAXPATHLEN
|
|
+# define PATH_MAX MAXPATHLEN
|
|
+# else
|
|
+# define PATH_MAX 1024
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+KPtyPrivate::KPtyPrivate(KPty *parent) :
|
|
+ masterFd(-1), slaveFd(-1), ownMaster(true), q_ptr(parent)
|
|
+{
|
|
+}
|
|
+
|
|
+KPtyPrivate::~KPtyPrivate()
|
|
+{
|
|
+}
|
|
+
|
|
+KPty::KPty() :
|
|
+ d_ptr(new KPtyPrivate(this))
|
|
+{
|
|
+}
|
|
+
|
|
+KPty::KPty(KPtyPrivate *d) :
|
|
+ d_ptr(d)
|
|
+{
|
|
+ d_ptr->q_ptr = this;
|
|
+}
|
|
+
|
|
+KPty::~KPty()
|
|
+{
|
|
+ close();
|
|
+}
|
|
+
|
|
+bool KPty::open()
|
|
+{
|
|
+ Q_D(KPty);
|
|
+
|
|
+ if (d->masterFd >= 0) {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ d->ownMaster = true;
|
|
+
|
|
+ QByteArray ptyName;
|
|
+
|
|
+ char ptsn[PATH_MAX];
|
|
+ if (::openpty(&d->masterFd, &d->slaveFd, ptsn, nullptr, nullptr)) {
|
|
+ d->masterFd = -1;
|
|
+ d->slaveFd = -1;
|
|
+ qCWarning(KPTY_LOG) << "Can't open a pseudo teletype";
|
|
+ return false;
|
|
+ }
|
|
+ d->ttyName = ptsn;
|
|
+
|
|
+ fcntl(d->masterFd, F_SETFD, FD_CLOEXEC);
|
|
+ fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);
|
|
+
|
|
+ setEcho(true);
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool KPty::open(int fd)
|
|
+{
|
|
+ Q_D(KPty);
|
|
+
|
|
+ if (d->masterFd >= 0) {
|
|
+ qCWarning(KPTY_LOG) << "Attempting to open an already open pty";
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ d->ownMaster = false;
|
|
+
|
|
+ char *ptsn = ptsname(fd);
|
|
+ if (ptsn) {
|
|
+ d->ttyName = ptsn;
|
|
+ } else {
|
|
+ qCWarning(KPTY_LOG) << "Failed to determine pty slave device for fd" << fd;
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ d->masterFd = fd;
|
|
+ if (!openSlave()) {
|
|
+ d->masterFd = -1;
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ setEcho(true);
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void KPty::closeSlave()
|
|
+{
|
|
+ Q_D(KPty);
|
|
+
|
|
+ if (d->slaveFd < 0) {
|
|
+ return;
|
|
+ }
|
|
+ ::close(d->slaveFd);
|
|
+ d->slaveFd = -1;
|
|
+}
|
|
+
|
|
+bool KPty::openSlave()
|
|
+{
|
|
+ Q_D(KPty);
|
|
+
|
|
+ if (d->slaveFd >= 0) {
|
|
+ return true;
|
|
+ }
|
|
+ if (d->masterFd < 0) {
|
|
+ qCWarning(KPTY_LOG) << "Attempting to open pty slave while master is closed";
|
|
+ return false;
|
|
+ }
|
|
+ d->slaveFd = QT_OPEN(d->ttyName.data(), QT_OPEN_RDWR | O_NOCTTY);
|
|
+ if (d->slaveFd < 0) {
|
|
+ qCWarning(KPTY_LOG) << "Can't open slave pseudo teletype";
|
|
+ return false;
|
|
+ }
|
|
+ fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void KPty::close()
|
|
+{
|
|
+ Q_D(KPty);
|
|
+
|
|
+ if (d->masterFd < 0) {
|
|
+ return;
|
|
+ }
|
|
+ closeSlave();
|
|
+ if (d->ownMaster) {
|
|
+ ::close(d->masterFd);
|
|
+ }
|
|
+ d->masterFd = -1;
|
|
+}
|
|
+
|
|
+void KPty::setCTty()
|
|
+{
|
|
+ Q_D(KPty);
|
|
+
|
|
+ setsid();
|
|
+
|
|
+ ioctl(d->slaveFd, TIOCSCTTY, 0);
|
|
+
|
|
+ int pgrp = getpid();
|
|
+ tcsetpgrp(d->slaveFd, pgrp);
|
|
+}
|
|
+
|
|
+void KPty::login(const char *user, const char *remotehost)
|
|
+{
|
|
+}
|
|
+
|
|
+void KPty::logout()
|
|
+{
|
|
+}
|
|
+
|
|
+bool KPty::tcGetAttr(struct ::termios *ttmode) const
|
|
+{
|
|
+ Q_D(const KPty);
|
|
+
|
|
+ return _tcgetattr(d->masterFd, ttmode) == 0;
|
|
+}
|
|
+
|
|
+bool KPty::tcSetAttr(struct ::termios *ttmode)
|
|
+{
|
|
+ Q_D(KPty);
|
|
+
|
|
+ return _tcsetattr(d->masterFd, ttmode) == 0;
|
|
+}
|
|
+
|
|
+bool KPty::setWinSize(int lines, int columns)
|
|
+{
|
|
+ Q_D(KPty);
|
|
+
|
|
+ struct winsize winSize;
|
|
+ memset(&winSize, 0, sizeof(winSize));
|
|
+ winSize.ws_row = (unsigned short)lines;
|
|
+ winSize.ws_col = (unsigned short)columns;
|
|
+ return ioctl(d->masterFd, TIOCSWINSZ, (char *)&winSize) == 0;
|
|
+}
|
|
+
|
|
+bool KPty::setEcho(bool echo)
|
|
+{
|
|
+ struct ::termios ttmode;
|
|
+ if (!tcGetAttr(&ttmode)) {
|
|
+ return false;
|
|
+ }
|
|
+ if (!echo) {
|
|
+ ttmode.c_lflag &= ~ECHO;
|
|
+ } else {
|
|
+ ttmode.c_lflag |= ECHO;
|
|
+ }
|
|
+ return tcSetAttr(&ttmode);
|
|
+}
|
|
+
|
|
+const char *KPty::ttyName() const
|
|
+{
|
|
+ Q_D(const KPty);
|
|
+
|
|
+ return d->ttyName.data();
|
|
+}
|
|
+
|
|
+int KPty::masterFd() const
|
|
+{
|
|
+ Q_D(const KPty);
|
|
+
|
|
+ return d->masterFd;
|
|
+}
|
|
+
|
|
+int KPty::slaveFd() const
|
|
+{
|
|
+ Q_D(const KPty);
|
|
+
|
|
+ return d->slaveFd;
|
|
+}
|
|
--
|
|
2.30.2
|
|
|