summaryrefslogtreecommitdiffstats
path: root/tdesu/process.h
blob: ae7741a2ab7011df806c2cdfaa1162bfe47a5ed4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
 *
 * $Id$
 *
 * This file is part of the KDE project, module tdesu.
 * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
 * 
 * This is free software; you can use this library under the GNU Library 
 * General Public License, version 2. See the file "COPYING.LIB" for the 
 * exact licensing terms.
 */

#ifndef __Process_h_Included__
#define __Process_h_Included__

#include <sys/types.h>

#include <tqcstring.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqvaluelist.h>

#include <tdelibs_export.h>

class PTY;
typedef TQValueList<TQCString> QCStringList;

/**
 * Synchronous communication with tty programs.
 *
 * PtyProcess provides synchronous communication with tty based programs. 
 * The communications channel used is a pseudo tty (as opposed to a pipe) 
 * This means that programs which require a terminal will work.
 */

class TDESU_EXPORT PtyProcess
{
public:
    PtyProcess();
    virtual ~PtyProcess();

    /**
     * Forks off and execute a command. The command's standard in and output 
     * are connected to the pseudo tty. They are accessible with readLine 
     * and writeLine.
     * @param command The command to execute.
     * @param args The arguments to the command.
     */
    int exec(const TQCString &command, const QCStringList &args);

    /**
     * Reads a line from the program's standard out. Depending on the @em block 
     * parameter, this call blocks until a single, full line is read. 
     * @param block Block until a full line is read?
     * @return The output string.
     */
    TQCString readLine(bool block=true);
    /**
     * Read all available output from the program's standard out.
     * @param block If no output is in the buffer, should the function block
     * @return The output.
     */
    TQCString readAll(bool block=true);

    /**
     * Writes a line of text to the program's standard in.
     * @param line The text to write.
     * @param addNewline Adds a '\n' to the line.
     */
    void writeLine(const TQCString &line, bool addNewline=true);

    /**
     * Puts back a line of input.
     * @param line The line to put back.
     * @param addNewline Adds a '\n' to the line.
     */
    void unreadLine(const TQCString &line, bool addNewline=true);

    /**
     * Sets the exit string. If a line of program output matches this,
     * waitForChild() will terminate the program and return.
     */
    void setExitString(const TQCString &exit) { m_Exit = exit; }

    /**
     * Waits for the child to exit. See also setExitString.
     */
    int waitForChild();

    /**
     * Waits until the pty has cleared the ECHO flag. This is useful 
     * when programs write a password prompt before they disable ECHO.
     * Disabling it might flush any input that was written.
     */
    int WaitSlave();

    /**
     * Enables/disables local echo on the pseudo tty.
     */
    int enableLocalEcho(bool enable=true);

    /**
     * Enables/disables terminal output. Relevant only to some subclasses.
     */
    void setTerminal(bool terminal) { m_bTerminal = terminal; }

    /**
     * Overwrites the password as soon as it is used. Relevant only to
     * some subclasses.
     */
    void setErase(bool erase) { m_bErase = erase; }

    /**
     * Set additinal environment variables.
     */
    void setEnvironment( const QCStringList &env );

    /**
     * Returns the filedescriptor of the process.
     */
    int fd() {return m_Fd;}

    /**
     * Returns the pid of the process.
     */
    int pid() {return m_Pid;}

public: /* static */
    /*
    ** This is a collection of static functions that can be
    ** used for process control inside tdesu. I'd suggest 
    ** against using this publicly. There are probably 
    ** nicer Qt based ways to do what you want.
    */

    /**
    ** Wait @p ms miliseconds (ie. 1/10th of a second is 100ms),
    ** using @p fd as a filedescriptor to wait on. Returns
    ** select(2)'s result, which is -1 on error, 0 on timeout,
    ** or positive if there is data on one of the selected fd's.
    **
    ** @p ms must be in the range 0..999 (ie. the maximum wait
    ** duration is 999ms, almost one second).
    */
    static int waitMS(int fd,int ms);


    /**
    ** Basic check for the existence of @p pid.
    ** Returns true iff @p pid is an extant process,
    ** (one you could kill - see man kill(2) for signal 0).
    */
    static bool checkPid(pid_t pid);

    /**
    ** Check process exit status for process @p pid.
    ** On error (no child, no exit), return -1.
    ** If child @p pid has exited, return its exit status,
    ** (which may be zero).
    ** If child @p has not exited, return -2.
    */
    enum checkPidStatus { Error=-1, NotExited=-2, Killed=-3 } ;
    static int checkPidExited(pid_t pid);


protected:
    const QCStringList& environment() const;

    bool m_bErase, m_bTerminal;
    int m_Pid, m_Fd;
    TQCString m_Command, m_Exit;

private:
    int init();
    int SetupTTY(int fd);

    PTY *m_pPTY;
    TQCString m_Inbuf, m_TTY;

protected:
    virtual void virtual_hook( int id, void* data );
private:
    class PtyProcessPrivate;
    PtyProcessPrivate *d;
};


#endif