summaryrefslogtreecommitdiff
path: root/noncore/net/networksetup/kprocess.h
Unidiff
Diffstat (limited to 'noncore/net/networksetup/kprocess.h') (more/less context) (show whitespace changes)
-rw-r--r--noncore/net/networksetup/kprocess.h804
1 files changed, 0 insertions, 804 deletions
diff --git a/noncore/net/networksetup/kprocess.h b/noncore/net/networksetup/kprocess.h
deleted file mode 100644
index e70f7e7..0000000
--- a/noncore/net/networksetup/kprocess.h
+++ b/dev/null
@@ -1,804 +0,0 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19//
20// KPROCESS -- A class for handling child processes in KDE without
21// having to take care of Un*x specific implementation details
22//
23// version 0.3.1, Jan 8th 1998
24//
25// (C) Christian Czezatke
26// e9025461@student.tuwien.ac.at
27//
28
29#ifndef __kprocess_h__
30#define __kprocess_h__
31
32#include <sys/types.h> // for pid_t
33#include <sys/wait.h>
34#include <signal.h>
35#include <unistd.h>
36#include <qvaluelist.h>
37#include <qcstring.h>
38#include <qobject.h>
39
40class QSocketNotifier;
41class KProcessPrivate;
42
43/**
44 * Child process invocation, monitoring and control.
45 *
46 * @sect General usage and features
47 *
48 *This class allows a KDE application to start child processes without having
49 *to worry about UN*X signal handling issues and zombie process reaping.
50 *
51 *@see KProcIO
52 *
53 *Basically, this class distinguishes three different ways of running
54 *child processes:
55 *
56 *@li KProcess::DontCare -- The child process is invoked and both the child
57 *process and the parent process continue concurrently.
58 *
59 *Starting a DontCare child process means that the application is
60 *not interested in any notification to determine whether the
61 *child process has already exited or not.
62 *
63 *@li KProcess::NotifyOnExit -- The child process is invoked and both the
64 *child and the parent process run concurrently.
65 *
66 *When the child process exits, the KProcess instance
67 *corresponding to it emits the Qt signal @ref processExited().
68 *
69 *Since this signal is @em not emitted from within a UN*X
70 *signal handler, arbitrary function calls can be made.
71 *
72 *Be aware: When the KProcess objects gets destructed, the child
73 *process will be killed if it is still running!
74 *This means in particular, that you cannot use a KProcess on the stack
75 *with KProcess::NotifyOnExit.
76 *
77 *@li KProcess::Block -- The child process starts and the parent process
78 *is suspended until the child process exits. (@em Really not recommended
79 *for programs with a GUI.)
80 *
81 *KProcess also provides several functions for determining the exit status
82 *and the pid of the child process it represents.
83 *
84 *Furthermore it is possible to supply command-line arguments to the process
85 *in a clean fashion (no null -- terminated stringlists and such...)
86 *
87 *A small usage example:
88 *<pre>
89 *KProcess *proc = new KProcess;
90 *
91 **proc << "my_executable";
92 **proc << "These" << "are" << "the" << "command" << "line" << "args";
93 *QApplication::connect(proc, SIGNAL(processExited(KProcess *)),
94 * pointer_to_my_object, SLOT(my_objects_slot(KProcess *)));
95 *proc->start();
96 *</pre>
97 *
98 *This will start "my_executable" with the commandline arguments "These"...
99 *
100 *When the child process exits, the respective Qt signal will be emitted.
101 *
102 *@sect Communication with the child process
103 *
104 *KProcess supports communication with the child process through
105 *stdin/stdout/stderr.
106 *
107 *The following functions are provided for getting data from the child
108 *process or sending data to the child's stdin (For more information,
109 *have a look at the documentation of each function):
110 *
111 *@li bool @ref writeStdin(char *buffer, int buflen);
112 *@li -- Transmit data to the child process's stdin.
113 *
114 *@li bool @ref closeStdin();
115 *@li -- Closes the child process's stdin (which causes it to see an feof(stdin)).
116 *Returns false if you try to close stdin for a process that has been started
117 *without a communication channel to stdin.
118 *
119 *@li bool @ref closeStdout();
120 *@li -- Closes the child process's stdout.
121 *Returns false if you try to close stdout for a process that has been started
122 *without a communication channel to stdout.
123 *
124 *@li bool @ref closeStderr();
125 *@li -- Closes the child process's stderr.
126 *Returns false if you try to close stderr for a process that has been started
127 *without a communication channel to stderr.
128 *
129 *
130 *@sect QT signals:
131 *
132 *@li void @ref receivedStdout(KProcess *proc, char *buffer, int buflen);
133 *@li void @ref receivedStderr(KProcess *proc, char *buffer, int buflen);
134 *@li -- Indicates that new data has arrived from either the
135 *child process's stdout or stderr.
136 *
137 *@li void @ref wroteStdin(KProcess *proc);
138 *@li -- Indicates that all data that has been sent to the child process
139 *by a prior call to @ref writeStdin() has actually been transmitted to the
140 *client .
141 *
142 *@author Christian Czezakte e9025461@student.tuwien.ac.at
143 *
144 *
145 **/
146class KProcess : public QObject
147{
148 Q_OBJECT
149
150public:
151
152 /**
153 * Modes in which the communication channel can be opened.
154 *
155 * If communication for more than one channel is required,
156 * the values have to be or'ed together, for example to get
157 * communication with stdout as well as with stdin, you would
158 * specify @p Stdin @p | @p Stdout
159 *
160 * If @p NoRead is specified in conjunction with @p Stdout,
161 * no data is actually read from @p Stdout but only
162 * the signal @ref childOutput(int fd) is emitted.
163 */
164 enum Communication { NoCommunication = 0, Stdin = 1, Stdout = 2, Stderr = 4,
165 AllOutput = 6, All = 7,
166 NoRead };
167
168 /**
169 * Run-modes for a child process.
170 */
171 enum RunMode {
172 /**
173 * The application does not receive notifications from the subprocess when
174 * it is finished or aborted.
175 */
176 DontCare,
177 /**
178 * The application is notified when the subprocess dies.
179 */
180 NotifyOnExit,
181 /**
182 * The application is suspended until the started process is finished.
183 */
184 Block };
185
186 /**
187 * Constructor
188 */
189 KProcess();
190
191 /**
192 *Destructor:
193 *
194 * If the process is running when the destructor for this class
195 * is called, the child process is killed with a SIGKILL, but
196 * only if the run mode is not of type @p DontCare.
197 * Processes started as @p DontCare keep running anyway.
198 */
199 virtual ~KProcess();
200
201 /**
202 @deprecated
203
204 The use of this function is now deprecated. -- Please use the
205 "operator<<" instead of "setExecutable".
206
207 Sets the executable to be started with this KProcess object.
208 Returns false if the process is currently running (in that
209 case the executable remains unchanged.)
210
211 @see operator<<
212
213 */
214 bool setExecutable(const QString& proc);
215
216
217 /**
218 * Sets the executable and the command line argument list for this process.
219 *
220 * For example, doing an "ls -l /usr/local/bin" can be achieved by:
221 * <pre>
222 * KProcess p;
223 * ...
224 * p << "ls" << "-l" << "/usr/local/bin"
225 * </pre>
226 *
227 **/
228 KProcess &operator<<(const QString& arg);
229 /**
230 * Similar to previous method, takes a char *, supposed to be in locale 8 bit already.
231 */
232 KProcess &operator<<(const char * arg);
233 /**
234 * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already.
235 */
236 KProcess &operator<<(const QCString & arg);
237
238 /**
239 * Sets the executable and the command line argument list for this process,
240 * in a single method call, or add a list of arguments.
241 **/
242 KProcess &operator<<(const QStringList& args);
243
244 /**
245 * Clear a command line argument list that has been set by using
246 * the "operator<<".
247 */
248 void clearArguments();
249
250 /**
251 * Starts the process.
252 * For a detailed description of the
253 * various run modes and communication semantics, have a look at the
254 * general description of the KProcess class.
255 *
256 * The following problems could cause this function to
257 * return false:
258 *
259 * @li The process is already running.
260 * @li The command line argument list is empty.
261 * @li The starting of the process failed (could not fork).
262 * @li The executable was not found.
263 *
264 * @param comm Specifies which communication links should be
265 * established to the child process (stdin/stdout/stderr). By default,
266 * no communication takes place and the respective communication
267 * signals will never get emitted.
268 *
269 * @return true on success, false on error
270 * (see above for error conditions)
271 **/
272 virtual bool start(RunMode runmode = NotifyOnExit,
273 Communication comm = NoCommunication);
274
275 /**
276 * Stop the process (by sending it a signal).
277 *
278 * @param signoThe signal to send. The default is SIGTERM.
279 * @return @p true if the signal was delivered successfully.
280 */
281 virtual bool kill(int signo = SIGTERM);
282
283 /**
284 @return @p true if the process is (still) considered to be running
285 */
286 bool isRunning() const;
287
288 /** Returns the process id of the process.
289 *
290 * If it is called after
291 * the process has exited, it returns the process id of the last
292 * child process that was created by this instance of KProcess.
293 *
294 * Calling it before any child process has been started by this
295 * KProcess instance causes pid() to return 0.
296 **/
297 pid_t pid() const;
298
299 /**
300 * Use pid().
301 * @deprecated
302 */
303 pid_t getPid() const { return pid(); }
304
305 /**
306 * Suspend processing of data from stdout of the child process.
307 */
308 void suspend();
309
310 /**
311 * Resume processing of data from stdout of the child process.
312 */
313 void resume();
314
315 /**
316 * @return @p true if the process has already finished and has exited
317 * "voluntarily", ie: it has not been killed by a signal.
318 *
319 * Note that you should check @ref KProcess::exitStatus() to determine
320 * whether the process completed its task successful or not.
321 */
322 bool normalExit() const;
323
324 /**
325 * Returns the exit status of the process.
326 *
327 * Please use
328 * @ref KProcess::normalExit() to check whether the process has exited
329 * cleanly (i.e., @ref KProcess::normalExit() returns @p true) before calling
330 * this function because if the process did not exit normally,
331 * it does not have a valid exit status.
332 */
333 int exitStatus() const;
334
335
336 /**
337 * Transmit data to the child process's stdin.
338 *
339 * KProcess::writeStdin may return false in the following cases:
340 *
341 * @li The process is not currently running.
342 *
343 * @li Communication to stdin has not been requested in the @ref start() call.
344 *
345 * @li Transmission of data to the child process by a previous call to
346 * @ref writeStdin() is still in progress.
347 *
348 * Please note that the data is sent to the client asynchronously,
349 * so when this function returns, the data might not have been
350 * processed by the child process.
351 *
352 * If all the data has been sent to the client, the signal
353 * @ref wroteStdin() will be emitted.
354 *
355 * Please note that you must not free "buffer" or call @ref writeStdin()
356 * again until either a @ref wroteStdin() signal indicates that the
357 * data has been sent or a @ref processHasExited() signal shows that
358 * the child process is no longer alive...
359 **/
360 bool writeStdin(const char *buffer, int buflen);
361
362 /**
363 * This causes the stdin file descriptor of the child process to be
364 * closed indicating an "EOF" to the child.
365 *
366 * @return @p false if no communication to the process's stdin
367 * had been specified in the call to @ref start().
368 */
369 bool closeStdin();
370
371 /**
372 * This causes the stdout file descriptor of the child process to be
373 * closed.
374 *
375 * @return @p false if no communication to the process's stdout
376 * had been specified in the call to @ref start().
377 */
378 bool closeStdout();
379
380 /**
381 * This causes the stderr file descriptor of the child process to be
382 * closed.
383 *
384 * @return @p false if no communication to the process's stderr
385 * had been specified in the call to @ref start().
386 */
387 bool closeStderr();
388
389 /**
390 * Lets you see what your arguments are for debugging.
391 */
392
393 const QValueList<QCString> &args() { return arguments; }
394
395 /**
396 * Controls whether the started process should drop any
397 * setuid/segid privileges or whether it should keep them
398 *
399 * The default is @p false : drop privileges
400 */
401 void setRunPrivileged(bool keepPrivileges);
402
403 /**
404 * Returns whether the started process will drop any
405 * setuid/segid privileges or whether it will keep them
406 */
407 bool runPrivileged() const;
408
409 /**
410 * Modifies the environment of the process to be started.
411 * This function must be called before starting the process.
412 */
413 void setEnvironment(const QString &name, const QString &value);
414
415 /**
416 * Changes the current working directory (CWD) of the process
417 * to be started.
418 * This function must be called before starting the process.
419 */
420 void setWorkingDirectory(const QString &dir);
421
422 /**
423 * Specify whether to start the command via a shell or directly.
424 * The default is to start the command directly.
425 * If @p useShell is true @p shell will be used as shell, or
426 * if shell is empty, the standard shell is used.
427 * @p quote A flag indicating whether to quote the arguments.
428 *
429 * When using a shell, the caller should make sure that all filenames etc.
430 * are properly quoted when passed as argument.
431 * @see quote()
432 */
433 void setUseShell(bool useShell, const char *shell = 0);
434
435 /**
436 * This function can be used to quote an argument string such that
437 * the shell processes it properly. This is e. g. necessary for
438 * user-provided file names which may contain spaces or quotes.
439 * It also prevents expansion of wild cards and environment variables.
440 */
441 static QString quote(const QString &arg);
442
443 /**
444 * Detaches KProcess from child process. All communication is closed.
445 * No exit notification is emitted any more for the child process.
446 * Deleting the KProcess will no longer kill the child process.
447 * Note that the current process remains the parent process of the
448 * child process.
449 */
450 void detach();
451
452
453
454signals:
455
456 /**
457 * Emitted after the process has terminated when
458 * the process was run in the @p NotifyOnExit (==default option to
459 * @ref start()) or the @ref Block mode.
460 **/
461 void processExited(KProcess *proc);
462
463
464 /**
465 * Emitted, when output from the child process has
466 * been received on stdout.
467 *
468 * To actually get
469 * these signals, the respective communication link (stdout/stderr)
470 * has to be turned on in @ref start().
471 *
472 * @param buffer The data received.
473 * @param buflen The number of bytes that are available.
474 *
475 * You should copy the information contained in @p buffer to your private
476 * data structures before returning from this slot.
477 **/
478 void receivedStdout(KProcess *proc, char *buffer, int buflen);
479
480 /**
481 * Emitted when output from the child process has
482 * been received on stdout.
483 *
484 * To actually get these signals, the respective communications link
485 * (stdout/stderr) has to be turned on in @ref start() and the
486 * @p NoRead flag should have been passed.
487 *
488 * You will need to explicitly call resume() after your call to start()
489 * to begin processing data from the child process's stdout. This is
490 * to ensure that this signal is not emitted when no one is connected
491 * to it, otherwise this signal will not be emitted.
492 *
493 * The data still has to be read from file descriptor @p fd.
494 **/
495 void receivedStdout(int fd, int &len);
496
497
498 /**
499 * Emitted, when output from the child process has
500 * been received on stderr.
501 * To actually get
502 * these signals, the respective communication link (stdout/stderr)
503 * has to be turned on in @ref start().
504 *
505 * @param buffer The data received.
506 * @param buflen The number of bytes that are available.
507 *
508 * You should copy the information contained in @p buffer to your private
509 * data structures before returning from this slot.
510 */
511 void receivedStderr(KProcess *proc, char *buffer, int buflen);
512
513 /**
514 * Emitted after all the data that has been
515 * specified by a prior call to @ref writeStdin() has actually been
516 * written to the child process.
517 **/
518 void wroteStdin(KProcess *proc);
519
520
521protected slots:
522
523 /**
524 * This slot gets activated when data from the child's stdout arrives.
525 * It usually calls "childOutput"
526 */
527 void slotChildOutput(int fdno);
528
529 /**
530 * This slot gets activated when data from the child's stderr arrives.
531 * It usually calls "childError"
532 */
533 void slotChildError(int fdno);
534 /*
535 Slot functions for capturing stdout and stderr of the child
536 */
537
538 /**
539 * Called when another bulk of data can be sent to the child's
540 * stdin. If there is no more data to be sent to stdin currently
541 * available, this function must disable the QSocketNotifier "innot".
542 */
543 void slotSendData(int dummy);
544
545protected:
546
547 /**
548 * Sets up the environment according to the data passed via
549 * setEnvironment(...)
550 */
551 void setupEnvironment();
552
553 /**
554 * The list of the process' command line arguments. The first entry
555 * in this list is the executable itself.
556 */
557 QValueList<QCString> arguments;
558 /**
559 * How to run the process (Block, NotifyOnExit, DontCare). You should
560 * not modify this data member directly from derived classes.
561 */
562 RunMode run_mode;
563 /**
564 * true if the process is currently running. You should not
565 * modify this data member directly from derived classes. For
566 * reading the value of this data member, please use "isRunning()"
567 * since "runs" will probably be made private in later versions
568 * of KProcess.
569 */
570 bool runs;
571
572 /**
573 * The PID of the currently running process (see "getPid()").
574 * You should not modify this data member in derived classes.
575 * Please use "getPid()" instead of directly accessing this
576 * member function since it will probably be made private in
577 * later versions of KProcess.
578 */
579 pid_t pid_;
580
581 /**
582 * The process' exit status as returned by "waitpid". You should not
583 * modify the value of this data member from derived classes. You should
584 * rather use @ref exitStatus than accessing this data member directly
585 * since it will probably be made private in further versions of
586 * KProcess.
587 */
588 int status;
589
590
591 /**
592 * See setRunPrivileged()
593 */
594 bool keepPrivs;
595
596 /*
597 Functions for setting up the sockets for communication.
598 setupCommunication
599 -- is called from "start" before "fork"ing.
600 commSetupDoneP
601 -- completes communication socket setup in the parent
602 commSetupDoneC
603 -- completes communication setup in the child process
604 commClose
605 -- frees all allocated communication resources in the parent
606 after the process has exited
607 */
608
609 /**
610 * This function is called from "KProcess::start" right before a "fork" takes
611 * place. According to
612 * the "comm" parameter this function has to initialize the "in", "out" and
613 * "err" data member of KProcess.
614 *
615 * This function should return 0 if setting the needed communication channels
616 * was successful.
617 *
618 * The default implementation is to create UNIX STREAM sockets for the communication,
619 * but you could overload this function and establish a TCP/IP communication for
620 * network communication, for example.
621 */
622 virtual int setupCommunication(Communication comm);
623
624 /**
625 * Called right after a (successful) fork on the parent side. This function
626 * will usually do some communications cleanup, like closing the reading end
627 * of the "stdin" communication channel.
628 *
629 * Furthermore, it must also create the QSocketNotifiers "innot", "outnot" and
630 * "errnot" and connect their Qt slots to the respective KProcess member functions.
631 *
632 * For a more detailed explanation, it is best to have a look at the default
633 * implementation of "setupCommunication" in kprocess.cpp.
634 */
635 virtual int commSetupDoneP();
636
637 /**
638 * Called right after a (successful) fork, but before an "exec" on the child
639 * process' side. It usually just closes the unused communication ends of
640 * "in", "out" and "err" (like the writing end of the "in" communication
641 * channel.
642 */
643 virtual int commSetupDoneC();
644
645
646 /**
647 * Immediately called after a process has exited. This function normally
648 * calls commClose to close all open communication channels to this
649 * process and emits the "processExited" signal (if the process was
650 * not running in the "DontCare" mode).
651 */
652 virtual void processHasExited(int state);
653
654 /**
655 * Should clean up the communication links to the child after it has
656 * exited. Should be called from "processHasExited".
657 */
658 virtual void commClose();
659
660
661 /**
662 * the socket descriptors for stdin/stdout/stderr.
663 */
664 int out[2];
665 int in[2];
666 int err[2];
667
668 /**
669 * The socket notifiers for the above socket descriptors.
670 */
671 QSocketNotifier *innot;
672 QSocketNotifier *outnot;
673 QSocketNotifier *errnot;
674
675 /**
676 * Lists the communication links that are activated for the child
677 * process. Should not be modified from derived classes.
678 */
679 Communication communication;
680
681 /**
682 * Called by "slotChildOutput" this function copies data arriving from the
683 * child process's stdout to the respective buffer and emits the signal
684 * "@ref receivedStderr".
685 */
686 int childOutput(int fdno);
687
688 /**
689 * Called by "slotChildOutput" this function copies data arriving from the
690 * child process's stdout to the respective buffer and emits the signal
691 * "@ref receivedStderr"
692 */
693 int childError(int fdno);
694
695 // information about the data that has to be sent to the child:
696
697 const char *input_data; // the buffer holding the data
698 int input_sent; // # of bytes already transmitted
699 int input_total; // total length of input_data
700
701 /**
702 * @ref KProcessController is a friend of KProcess because it has to have
703 * access to various data members.
704 */
705 friend class KProcessController;
706
707
708private:
709 /**
710 * Searches for a valid shell.
711 * Here is the algorithm used for finding an executable shell:
712 *
713 * @li Try the executable pointed to by the "SHELL" environment
714 * variable with white spaces stripped off
715 *
716 * @li If your process runs with uid != euid or gid != egid, a shell
717 * not listed in /etc/shells will not used.
718 *
719 * @li If no valid shell could be found, "/bin/sh" is used as a last resort.
720 */
721 QCString searchShell();
722
723 /**
724 * Used by @ref searchShell in order to find out whether the shell found
725 * is actually executable at all.
726 */
727 bool isExecutable(const QCString &filename);
728
729 // Disallow assignment and copy-construction
730 KProcess( const KProcess& );
731 KProcess& operator= ( const KProcess& );
732
733protected:
734 virtual void virtual_hook( int id, void* data );
735private:
736 KProcessPrivate *d;
737};
738
739class KShellProcessPrivate;
740
741/**
742* @obsolete
743*
744* This class is obsolete. Use KProcess and KProcess::setUseShell(true)
745* instead.
746*
747* @short A class derived from @ref KProcess to start child
748 * processes through a shell.
749* @author Christian Czezakte <e9025461@student.tuwien.ac.at>
750* @version $Id$
751*/
752class KShellProcess: public KProcess
753{
754 Q_OBJECT
755
756public:
757
758 /**
759 * Constructor
760 *
761 * By specifying the name of a shell (like "/bin/bash") you can override
762 * the mechanism for finding a valid shell as described in KProcess::searchShell()
763 */
764 KShellProcess(const char *shellname=0);
765
766 /**
767 * Destructor.
768 */
769 ~KShellProcess();
770
771 /**
772 * Starts up the process. -- For a detailed description
773 * have a look at the "start" member function and the detailed
774 * description of @ref KProcess .
775 */
776 virtual bool start(RunMode runmode = NotifyOnExit,
777 Communication comm = NoCommunication);
778
779 /**
780 * This function can be used to quote an argument string such that
781 * the shell processes it properly. This is e. g. necessary for
782 * user-provided file names which may contain spaces or quotes.
783 * It also prevents expansion of wild cards and environment variables.
784 */
785 static QString quote(const QString &arg);
786
787private:
788
789 QCString shell;
790
791 // Disallow assignment and copy-construction
792 KShellProcess( const KShellProcess& );
793 KShellProcess& operator= ( const KShellProcess& );
794
795protected:
796 virtual void virtual_hook( int id, void* data );
797private:
798 KShellProcessPrivate *d;
799};
800
801
802
803#endif
804