File indexing completed on 2024-04-14 03:54:25

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2003, 2007 Oswald Buddenhagen <ossi@kde.org>
0004     SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef kpty_h
0010 #define kpty_h
0011 
0012 #include "kpty_export.h"
0013 
0014 #include <qglobal.h>
0015 
0016 #include <memory>
0017 
0018 class KPtyPrivate;
0019 struct termios;
0020 
0021 /**
0022  * Provides primitives for opening & closing a pseudo TTY pair, assigning the
0023  * controlling TTY, utmp registration and setting various terminal attributes.
0024  */
0025 class KPTY_EXPORT KPty
0026 {
0027     Q_DECLARE_PRIVATE(KPty)
0028 
0029 public:
0030     /**
0031      * Constructor
0032      */
0033     KPty();
0034 
0035     /**
0036      * Destructor:
0037      *
0038      *  If the pty is still open, it will be closed. Note, however, that
0039      *  an utmp registration is @em not undone.
0040      */
0041     ~KPty();
0042 
0043     KPty(const KPty &) = delete;
0044     KPty &operator=(const KPty &) = delete;
0045 
0046     /**
0047      * Create a pty master/slave pair.
0048      *
0049      * @return true if a pty pair was successfully opened
0050      */
0051     bool open();
0052 
0053     /**
0054      * Open using an existing pty master.
0055      *
0056      * @param fd an open pty master file descriptor.
0057      *   The ownership of the fd remains with the caller;
0058      *   it will not be automatically closed at any point.
0059      * @return true if a pty pair was successfully opened
0060      */
0061     bool open(int fd);
0062 
0063     /**
0064      * Close the pty master/slave pair.
0065      */
0066     void close();
0067 
0068     /**
0069      * Close the pty slave descriptor.
0070      *
0071      * When creating the pty, KPty also opens the slave and keeps it open.
0072      * Consequently the master will never receive an EOF notification.
0073      * Usually this is the desired behavior, as a closed pty slave can be
0074      * reopened any time - unlike a pipe or socket. However, in some cases
0075      * pipe-alike behavior might be desired.
0076      *
0077      * After this function was called, slaveFd() and setCTty() cannot be
0078      * used.
0079      */
0080     void closeSlave();
0081 
0082     /**
0083      * Open the pty slave descriptor.
0084      *
0085      * This undoes the effect of closeSlave().
0086      *
0087      * @return true if the pty slave was successfully opened
0088      */
0089     bool openSlave();
0090 
0091     /**
0092      * @brief Whether this will be a controlling terminal
0093      *
0094      * This is on by default.
0095      * Disabling the controllig aspect only makes sense if another process will
0096      * take over control or there is nothing to control or for technical reasons
0097      * control cannot be set (this notably is the case with flatpak-spawn when
0098      * used inside a sandbox).
0099      *
0100      * @param enable whether to enable ctty set up
0101      */
0102     void setCTtyEnabled(bool enable);
0103 
0104     /**
0105      * Creates a new session and process group and makes this pty the
0106      * controlling tty.
0107      */
0108     void setCTty();
0109 
0110     /**
0111      * Creates an utmp entry for the tty.
0112      * This function must be called after calling setCTty and
0113      * making this pty the stdin.
0114      * @param user the user to be logged on
0115      * @param remotehost the host from which the login is coming. This is
0116      *  @em not the local host. For remote logins it should be the hostname
0117      *  of the client. For local logins from inside an X session it should
0118      *  be the name of the X display. Otherwise it should be empty.
0119      */
0120     void login(const char *user = nullptr, const char *remotehost = nullptr);
0121 
0122     /**
0123      * Removes the utmp entry for this tty.
0124      */
0125     void logout();
0126 
0127     /**
0128      * Wrapper around tcgetattr(3).
0129      *
0130      * This function can be used only while the PTY is open.
0131      * You will need an #include &lt;termios.h&gt; to do anything useful
0132      * with it.
0133      *
0134      * @param ttmode a pointer to a termios structure.
0135      *  Note: when declaring ttmode, @c struct @c ::termios must be used -
0136      *  without the '::' some version of HP-UX thinks, this declares
0137      *  the struct in your class, in your method.
0138      * @return @c true on success, false otherwise
0139      */
0140     bool tcGetAttr(struct ::termios *ttmode) const;
0141 
0142     /**
0143      * Wrapper around tcsetattr(3) with mode TCSANOW.
0144      *
0145      * This function can be used only while the PTY is open.
0146      *
0147      * @param ttmode a pointer to a termios structure.
0148      * @return @c true on success, false otherwise. Note that success means
0149      *  that @em at @em least @em one attribute could be set.
0150      */
0151     bool tcSetAttr(struct ::termios *ttmode);
0152 
0153     /**
0154      * Change the logical (screen) size of the pty.
0155      * The default is 24 lines by 80 columns in characters, and zero pixels.
0156      *
0157      * This function can be used only while the PTY is open.
0158      *
0159      * @param lines the number of character rows
0160      * @param columns the number of character columns
0161      * @param height the view height in pixels
0162      * @param width the view width in pixels
0163      * @return @c true on success, false otherwise
0164      *
0165      * @since 5.93
0166      */
0167     bool setWinSize(int lines, int columns, int height, int width);
0168 
0169     /**
0170      * @overload
0171      * Change the logical (screen) size of the pty.
0172      * The pixel size is set to zero.
0173      */
0174     bool setWinSize(int lines, int columns);
0175 
0176     /**
0177      * Set whether the pty should echo input.
0178      *
0179      * Echo is on by default.
0180      * If the output of automatically fed (non-interactive) PTY clients
0181      * needs to be parsed, disabling echo often makes it much simpler.
0182      *
0183      * This function can be used only while the PTY is open.
0184      *
0185      * @param echo true if input should be echoed.
0186      * @return @c true on success, false otherwise
0187      */
0188     bool setEcho(bool echo);
0189 
0190     /**
0191      * @return the name of the slave pty device.
0192      *
0193      * This function should be called only while the pty is open.
0194      */
0195     const char *ttyName() const;
0196 
0197     /**
0198      * @return the file descriptor of the master pty
0199      *
0200      * This function should be called only while the pty is open.
0201      */
0202     int masterFd() const;
0203 
0204     /**
0205      * @return the file descriptor of the slave pty
0206      *
0207      * This function should be called only while the pty slave is open.
0208      */
0209     int slaveFd() const;
0210 
0211 protected:
0212     /**
0213      * @internal
0214      */
0215     KPTY_NO_EXPORT explicit KPty(KPtyPrivate *d);
0216 
0217     /**
0218      * @internal
0219      */
0220     std::unique_ptr<KPtyPrivate> const d_ptr;
0221 };
0222 
0223 #endif