diff options
author | Ramón M. Gómez <ramongomez@us.es> | 2020-05-19 14:53:27 +0200 |
---|---|---|
committer | Ramón M. Gómez <ramongomez@us.es> | 2020-05-19 14:53:27 +0200 |
commit | 4f9978aea3a93f3069a47c31bf5649835e8ba2c3 (patch) | |
tree | 08f5e8f0cd6843bfb9ee1c54f909f0608c941a61 /client/browser/qtermwidget/src/k3process.cpp | |
parent | a0868b7012b2a8aba33b34b0cf08741ea2b97725 (diff) |
#959: Delete dirs moved to other repositories.
OGAgent code, browser code and the ogLive builder scrips are moved to new Git repositories.
Diffstat (limited to 'client/browser/qtermwidget/src/k3process.cpp')
-rw-r--r-- | client/browser/qtermwidget/src/k3process.cpp | 1054 |
1 files changed, 0 insertions, 1054 deletions
diff --git a/client/browser/qtermwidget/src/k3process.cpp b/client/browser/qtermwidget/src/k3process.cpp deleted file mode 100644 index 0f36a70c..00000000 --- a/client/browser/qtermwidget/src/k3process.cpp +++ /dev/null @@ -1,1054 +0,0 @@ -/* - This file is part of the KDE libraries - Copyright (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at) - - Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - - -#include "k3process.h" -//#include <config.h> - -#include "k3processcontroller.h" -#include "kpty.h" - -#ifdef __osf__ -#define _OSF_SOURCE -#include <float.h> -#endif - -#ifdef _AIX -#define _ALL_SOURCE -#endif - -#include <sys/socket.h> -#include <sys/ioctl.h> - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/wait.h> - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#include <errno.h> -#include <assert.h> -#include <fcntl.h> -#include <time.h> -#include <stdlib.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <pwd.h> -#include <grp.h> - -#include <QtCore/QMap> -#include <QtCore/QFile> -#include <QtCore/QSocketNotifier> - -//#include <kdebug.h> -//#include <kstandarddirs.h> -//#include <kuser.h> - - - -////////////////// -// private data // -////////////////// - -class K3ProcessPrivate { -public: - K3ProcessPrivate() : - usePty(K3Process::NoCommunication), - addUtmp(false), useShell(false), - pty(0), - priority(0) - { - } - - K3Process::Communication usePty; - bool addUtmp : 1; - bool useShell : 1; - - KPty *pty; - - int priority; - - QMap<QString,QString> env; - QString wd; - QByteArray shell; - QByteArray executable; -}; - -///////////////////////////// -// public member functions // -///////////////////////////// - -K3Process::K3Process( QObject* parent ) - : QObject( parent ), - run_mode(NotifyOnExit), - runs(false), - pid_(0), - status(0), - keepPrivs(false), - innot(0), - outnot(0), - errnot(0), - communication(NoCommunication), - input_data(0), - input_sent(0), - input_total(0), - d(new K3ProcessPrivate) -{ - K3ProcessController::ref(); - K3ProcessController::instance()->addKProcess(this); - - - out[0] = out[1] = -1; - in[0] = in[1] = -1; - err[0] = err[1] = -1; -} - -void -K3Process::setEnvironment(const QString &name, const QString &value) -{ - d->env.insert(name, value); -} - -void -K3Process::setWorkingDirectory(const QString &dir) -{ - d->wd = dir; -} - -void -K3Process::setupEnvironment() -{ - QMap<QString,QString>::Iterator it; - for(it = d->env.begin(); it != d->env.end(); ++it) - { - setenv(QFile::encodeName(it.key()).data(), - QFile::encodeName(it.value()).data(), 1); - } - if (!d->wd.isEmpty()) - { - chdir(QFile::encodeName(d->wd).data()); - } -} - -void -K3Process::setRunPrivileged(bool keepPrivileges) -{ - keepPrivs = keepPrivileges; -} - -bool -K3Process::runPrivileged() const -{ - return keepPrivs; -} - -bool -K3Process::setPriority(int prio) -{ - if (runs) { - if (setpriority(PRIO_PROCESS, pid_, prio)) - return false; - } else { - if (prio > 19 || prio < (geteuid() ? getpriority(PRIO_PROCESS, 0) : -20)) - return false; - } - d->priority = prio; - return true; -} - -K3Process::~K3Process() -{ - if (run_mode != DontCare) - kill(SIGKILL); - detach(); - - delete d->pty; - delete d; - - K3ProcessController::instance()->removeKProcess(this); - K3ProcessController::deref(); -} - -void K3Process::detach() -{ - if (runs) { - K3ProcessController::instance()->addProcess(pid_); - runs = false; - pid_ = 0; // close without draining - commClose(); // Clean up open fd's and socket notifiers. - } -} - -void K3Process::setBinaryExecutable(const char *filename) -{ - d->executable = filename; -} - -K3Process &K3Process::operator<<(const QStringList& args) -{ - QStringList::ConstIterator it = args.begin(); - for ( ; it != args.end() ; ++it ) - arguments.append(QFile::encodeName(*it)); - return *this; -} - -K3Process &K3Process::operator<<(const QByteArray& arg) -{ - return operator<< (arg.data()); -} - -K3Process &K3Process::operator<<(const char* arg) -{ - arguments.append(arg); - return *this; -} - -K3Process &K3Process::operator<<(const QString& arg) -{ - arguments.append(QFile::encodeName(arg)); - return *this; -} - -void K3Process::clearArguments() -{ - arguments.clear(); -} - -bool K3Process::start(RunMode runmode, Communication comm) -{ - if (runs) { - qDebug() << "Attempted to start an already running process" << endl; - return false; - } - - uint n = arguments.count(); - if (n == 0) { - qDebug() << "Attempted to start a process without arguments" << endl; - return false; - } - char **arglist; - QByteArray shellCmd; - if (d->useShell) - { - if (d->shell.isEmpty()) { - qDebug() << "Invalid shell specified" << endl; - return false; - } - - for (uint i = 0; i < n; i++) { - shellCmd += arguments[i]; - shellCmd += ' '; // CC: to separate the arguments - } - - arglist = static_cast<char **>(malloc( 4 * sizeof(char *))); - arglist[0] = d->shell.data(); - arglist[1] = (char *) "-c"; - arglist[2] = shellCmd.data(); - arglist[3] = 0; - } - else - { - arglist = static_cast<char **>(malloc( (n + 1) * sizeof(char *))); - for (uint i = 0; i < n; i++) - arglist[i] = arguments[i].data(); - arglist[n] = 0; - } - - run_mode = runmode; - - if (!setupCommunication(comm)) - { - qDebug() << "Could not setup Communication!" << endl; - free(arglist); - return false; - } - - // We do this in the parent because if we do it in the child process - // gdb gets confused when the application runs from gdb. -#ifdef HAVE_INITGROUPS - struct passwd *pw = geteuid() ? 0 : getpwuid(getuid()); -#endif - - int fd[2]; - if (pipe(fd)) - fd[0] = fd[1] = -1; // Pipe failed.. continue - - // we don't use vfork() because - // - it has unclear semantics and is not standardized - // - we do way too much magic in the child - pid_ = fork(); - if (pid_ == 0) { - // The child process - - close(fd[0]); - // Closing of fd[1] indicates that the execvp() succeeded! - fcntl(fd[1], F_SETFD, FD_CLOEXEC); - - if (!commSetupDoneC()) - qDebug() << "Could not finish comm setup in child!" << endl; - - // reset all signal handlers - struct sigaction act; - sigemptyset(&act.sa_mask); - act.sa_handler = SIG_DFL; - act.sa_flags = 0; - for (int sig = 1; sig < NSIG; sig++) - sigaction(sig, &act, 0L); - - if (d->priority) - setpriority(PRIO_PROCESS, 0, d->priority); - - if (!runPrivileged()) - { - setgid(getgid()); -#ifdef HAVE_INITGROUPS - if (pw) - initgroups(pw->pw_name, pw->pw_gid); -#endif - if (geteuid() != getuid()) - setuid(getuid()); - if (geteuid() != getuid()) - _exit(1); - } - - setupEnvironment(); - - if (runmode == DontCare || runmode == OwnGroup) - setsid(); - - const char *executable = arglist[0]; - if (!d->executable.isEmpty()) - executable = d->executable.data(); - execvp(executable, arglist); - - char resultByte = 1; - write(fd[1], &resultByte, 1); - _exit(-1); - } else if (pid_ == -1) { - // forking failed - - // commAbort(); - pid_ = 0; - free(arglist); - return false; - } - // the parent continues here - free(arglist); - - if (!commSetupDoneP()) - qDebug() << "Could not finish comm setup in parent!" << endl; - - // Check whether client could be started. - close(fd[1]); - for(;;) - { - char resultByte; - int n = ::read(fd[0], &resultByte, 1); - if (n == 1) - { - // exec() failed - close(fd[0]); - waitpid(pid_, 0, 0); - pid_ = 0; - commClose(); - return false; - } - if (n == -1) - { - if (errno == EINTR) - continue; // Ignore - } - break; // success - } - close(fd[0]); - - runs = true; - switch (runmode) - { - case Block: - for (;;) - { - commClose(); // drain only, unless obsolete reimplementation - if (!runs) - { - // commClose detected data on the process exit notifification pipe - K3ProcessController::instance()->unscheduleCheck(); - if (waitpid(pid_, &status, WNOHANG) != 0) // error finishes, too - { - commClose(); // this time for real (runs is false) - K3ProcessController::instance()->rescheduleCheck(); - break; - } - runs = true; // for next commClose() iteration - } - else - { - // commClose is an obsolete reimplementation and waited until - // all output channels were closed (or it was interrupted). - // there is a chance that it never gets here ... - waitpid(pid_, &status, 0); - runs = false; - break; - } - } - // why do we do this? i think this signal should be emitted _only_ - // after the process has successfully run _asynchronously_ --ossi - emit processExited(this); - break; - default: // NotifyOnExit & OwnGroup - input_data = 0; // Discard any data for stdin that might still be there - break; - } - return true; -} - - - -bool K3Process::kill(int signo) -{ - if (runs && pid_ > 0 && !::kill(run_mode == OwnGroup ? -pid_ : pid_, signo)) - return true; - return false; -} - - - -bool K3Process::isRunning() const -{ - return runs; -} - - - -pid_t K3Process::pid() const -{ - return pid_; -} - -#ifndef timersub -# define timersub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) -#endif - -bool K3Process::wait(int timeout) -{ - if (!runs) - return true; - -#ifndef __linux__ - struct timeval etv; -#endif - struct timeval tv, *tvp; - if (timeout < 0) - tvp = 0; - else - { -#ifndef __linux__ - gettimeofday(&etv, 0); - etv.tv_sec += timeout; -#else - tv.tv_sec = timeout; - tv.tv_usec = 0; -#endif - tvp = &tv; - } - - int fd = K3ProcessController::instance()->notifierFd(); - for(;;) - { - fd_set fds; - FD_ZERO( &fds ); - FD_SET( fd, &fds ); - -#ifndef __linux__ - if (tvp) - { - gettimeofday(&tv, 0); - timersub(&etv, &tv, &tv); - if (tv.tv_sec < 0) - tv.tv_sec = tv.tv_usec = 0; - } -#endif - - switch( select( fd+1, &fds, 0, 0, tvp ) ) - { - case -1: - if( errno == EINTR ) - break; - // fall through; should happen if tvp->tv_sec < 0 - case 0: - K3ProcessController::instance()->rescheduleCheck(); - return false; - default: - K3ProcessController::instance()->unscheduleCheck(); - if (waitpid(pid_, &status, WNOHANG) != 0) // error finishes, too - { - processHasExited(status); - K3ProcessController::instance()->rescheduleCheck(); - return true; - } - } - } - return false; -} - - - -bool K3Process::normalExit() const -{ - return (pid_ != 0) && !runs && WIFEXITED(status); -} - - -bool K3Process::signalled() const -{ - return (pid_ != 0) && !runs && WIFSIGNALED(status); -} - - -bool K3Process::coreDumped() const -{ -#ifdef WCOREDUMP - return signalled() && WCOREDUMP(status); -#else - return false; -#endif -} - - -int K3Process::exitStatus() const -{ - return WEXITSTATUS(status); -} - - -int K3Process::exitSignal() const -{ - return WTERMSIG(status); -} - - -bool K3Process::writeStdin(const char *buffer, int buflen) -{ - // if there is still data pending, writing new data - // to stdout is not allowed (since it could also confuse - // kprocess ...) - if (input_data != 0) - return false; - - if (communication & Stdin) { - input_data = buffer; - input_sent = 0; - input_total = buflen; - innot->setEnabled(true); - if (input_total) - slotSendData(0); - return true; - } else - return false; -} - -void K3Process::suspend() -{ - if (outnot) - outnot->setEnabled(false); -} - -void K3Process::resume() -{ - if (outnot) - outnot->setEnabled(true); -} - -bool K3Process::closeStdin() -{ - if (communication & Stdin) { - communication = communication & ~Stdin; - delete innot; - innot = 0; - if (!(d->usePty & Stdin)) - close(in[1]); - in[1] = -1; - return true; - } else - return false; -} - -bool K3Process::closeStdout() -{ - if (communication & Stdout) { - communication = communication & ~Stdout; - delete outnot; - outnot = 0; - if (!(d->usePty & Stdout)) - close(out[0]); - out[0] = -1; - return true; - } else - return false; -} - -bool K3Process::closeStderr() -{ - if (communication & Stderr) { - communication = communication & ~Stderr; - delete errnot; - errnot = 0; - if (!(d->usePty & Stderr)) - close(err[0]); - err[0] = -1; - return true; - } else - return false; -} - -bool K3Process::closePty() -{ - if (d->pty && d->pty->masterFd() >= 0) { - if (d->addUtmp) - d->pty->logout(); - d->pty->close(); - return true; - } else - return false; -} - -void K3Process::closeAll() -{ - closeStdin(); - closeStdout(); - closeStderr(); - closePty(); -} - -///////////////////////////// -// protected slots // -///////////////////////////// - - - -void K3Process::slotChildOutput(int fdno) -{ - if (!childOutput(fdno)) - closeStdout(); -} - - -void K3Process::slotChildError(int fdno) -{ - if (!childError(fdno)) - closeStderr(); -} - - -void K3Process::slotSendData(int) -{ - if (input_sent == input_total) { - innot->setEnabled(false); - input_data = 0; - emit wroteStdin(this); - } else { - int result = ::write(in[1], input_data+input_sent, input_total-input_sent); - if (result >= 0) - { - input_sent += result; - } - else if ((errno != EAGAIN) && (errno != EINTR)) - { - qDebug() << "Error writing to stdin of child process" << endl; - closeStdin(); - } - } -} - -void K3Process::setUseShell(bool useShell, const char *shell) -{ - d->useShell = useShell; - if (shell && *shell) - d->shell = shell; - else -// #ifdef NON_FREE // ... as they ship non-POSIX /bin/sh -#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__GNU__) && !defined(__DragonFly__) - // Solaris POSIX ... - if (!access( "/usr/xpg4/bin/sh", X_OK )) - d->shell = "/usr/xpg4/bin/sh"; - else - // ... which links here anyway - if (!access( "/bin/ksh", X_OK )) - d->shell = "/bin/ksh"; - else - // dunno, maybe superfluous? - if (!access( "/usr/ucb/sh", X_OK )) - d->shell = "/usr/ucb/sh"; - else -#endif - d->shell = "/bin/sh"; -} - -void K3Process::setUsePty(Communication usePty, bool addUtmp) -{ - d->usePty = usePty; - d->addUtmp = addUtmp; - if (usePty) { - if (!d->pty) - d->pty = new KPty; - } else { - delete d->pty; - d->pty = 0; - } -} - -KPty *K3Process::pty() const -{ - return d->pty; -} - -QString K3Process::quote(const QString &arg) -{ - QChar q('\''); - return QString(arg).replace(q, "'\\''").prepend(q).append(q); -} - - -////////////////////////////// -// private member functions // -////////////////////////////// - - -void K3Process::processHasExited(int state) -{ - // only successfully run NotifyOnExit processes ever get here - - status = state; - runs = false; // do this before commClose, so it knows we're dead - - commClose(); // cleanup communication sockets - - if (run_mode != DontCare) - emit processExited(this); -} - - - -int K3Process::childOutput(int fdno) -{ - if (communication & NoRead) { - int len = -1; - emit receivedStdout(fdno, len); - errno = 0; // Make sure errno doesn't read "EAGAIN" - return len; - } - else - { - char buffer[1025]; - int len; - - len = ::read(fdno, buffer, 1024); - - if (len > 0) { - buffer[len] = 0; // Just in case. - emit receivedStdout(this, buffer, len); - } - return len; - } -} - -int K3Process::childError(int fdno) -{ - char buffer[1025]; - int len; - - len = ::read(fdno, buffer, 1024); - - if (len > 0) { - buffer[len] = 0; // Just in case. - emit receivedStderr(this, buffer, len); - } - return len; -} - - -int K3Process::setupCommunication(Communication comm) -{ - // PTY stuff // - if (d->usePty) - { - // cannot communicate on both stderr and stdout if they are both on the pty - if (!(~(comm & d->usePty) & (Stdout | Stderr))) { - qWarning() << "Invalid usePty/communication combination (" << d->usePty << "/" << comm << ")" << endl; - return 0; - } - if (!d->pty->open()) - return 0; - - int rcomm = comm & d->usePty; - int mfd = d->pty->masterFd(); - if (rcomm & Stdin) - in[1] = mfd; - if (rcomm & Stdout) - out[0] = mfd; - if (rcomm & Stderr) - err[0] = mfd; - } - - communication = comm; - - comm = comm & ~d->usePty; - if (comm & Stdin) { - if (socketpair(AF_UNIX, SOCK_STREAM, 0, in)) - goto fail0; - fcntl(in[0], F_SETFD, FD_CLOEXEC); - fcntl(in[1], F_SETFD, FD_CLOEXEC); - } - if (comm & Stdout) { - if (socketpair(AF_UNIX, SOCK_STREAM, 0, out)) - goto fail1; - fcntl(out[0], F_SETFD, FD_CLOEXEC); - fcntl(out[1], F_SETFD, FD_CLOEXEC); - } - if (comm & Stderr) { - if (socketpair(AF_UNIX, SOCK_STREAM, 0, err)) - goto fail2; - fcntl(err[0], F_SETFD, FD_CLOEXEC); - fcntl(err[1], F_SETFD, FD_CLOEXEC); - } - return 1; // Ok - fail2: - if (comm & Stdout) - { - close(out[0]); - close(out[1]); - out[0] = out[1] = -1; - } - fail1: - if (comm & Stdin) - { - close(in[0]); - close(in[1]); - in[0] = in[1] = -1; - } - fail0: - communication = NoCommunication; - return 0; // Error -} - - - -int K3Process::commSetupDoneP() -{ - int rcomm = communication & ~d->usePty; - if (rcomm & Stdin) - close(in[0]); - if (rcomm & Stdout) - close(out[1]); - if (rcomm & Stderr) - close(err[1]); - in[0] = out[1] = err[1] = -1; - - // Don't create socket notifiers if no interactive comm is to be expected - if (run_mode != NotifyOnExit && run_mode != OwnGroup) - return 1; - - if (communication & Stdin) { - fcntl(in[1], F_SETFL, O_NONBLOCK | fcntl(in[1], F_GETFL)); - innot = new QSocketNotifier(in[1], QSocketNotifier::Write, this); - Q_CHECK_PTR(innot); - innot->setEnabled(false); // will be enabled when data has to be sent - QObject::connect(innot, SIGNAL(activated(int)), - this, SLOT(slotSendData(int))); - } - - if (communication & Stdout) { - outnot = new QSocketNotifier(out[0], QSocketNotifier::Read, this); - Q_CHECK_PTR(outnot); - QObject::connect(outnot, SIGNAL(activated(int)), - this, SLOT(slotChildOutput(int))); - if (communication & NoRead) - suspend(); - } - - if (communication & Stderr) { - errnot = new QSocketNotifier(err[0], QSocketNotifier::Read, this ); - Q_CHECK_PTR(errnot); - QObject::connect(errnot, SIGNAL(activated(int)), - this, SLOT(slotChildError(int))); - } - - return 1; -} - - - -int K3Process::commSetupDoneC() -{ - int ok = 1; - if (d->usePty & Stdin) { - if (dup2(d->pty->slaveFd(), STDIN_FILENO) < 0) ok = 0; - } else if (communication & Stdin) { - if (dup2(in[0], STDIN_FILENO) < 0) ok = 0; - } else { - int null_fd = open( "/dev/null", O_RDONLY ); - if (dup2( null_fd, STDIN_FILENO ) < 0) ok = 0; - close( null_fd ); - } - struct linger so; - memset(&so, 0, sizeof(so)); - if (d->usePty & Stdout) { - if (dup2(d->pty->slaveFd(), STDOUT_FILENO) < 0) ok = 0; - } else if (communication & Stdout) { - if (dup2(out[1], STDOUT_FILENO) < 0 || - setsockopt(out[1], SOL_SOCKET, SO_LINGER, (char *)&so, sizeof(so))) - ok = 0; - if (communication & MergedStderr) { - if (dup2(out[1], STDERR_FILENO) < 0) - ok = 0; - } - } - if (d->usePty & Stderr) { - if (dup2(d->pty->slaveFd(), STDERR_FILENO) < 0) ok = 0; - } else if (communication & Stderr) { - if (dup2(err[1], STDERR_FILENO) < 0 || - setsockopt(err[1], SOL_SOCKET, SO_LINGER, (char *)&so, sizeof(so))) - ok = 0; - } - - // don't even think about closing all open fds here or anywhere else - - // PTY stuff // - if (d->usePty) { - d->pty->setCTty(); - if (d->addUtmp) - d->pty->login(getenv("USER"), getenv("DISPLAY")); - } - - return ok; -} - - - -void K3Process::commClose() -{ - closeStdin(); - - if (pid_) { // detached, failed, and killed processes have no output. basta. :) - // If both channels are being read we need to make sure that one socket - // buffer doesn't fill up whilst we are waiting for data on the other - // (causing a deadlock). Hence we need to use select. - - int notfd = K3ProcessController::instance()->notifierFd(); - - while ((communication & (Stdout | Stderr)) || runs) { - fd_set rfds; - FD_ZERO(&rfds); - struct timeval timeout, *p_timeout; - - int max_fd = 0; - if (communication & Stdout) { - FD_SET(out[0], &rfds); - max_fd = out[0]; - } - if (communication & Stderr) { - FD_SET(err[0], &rfds); - if (err[0] > max_fd) - max_fd = err[0]; - } - if (runs) { - FD_SET(notfd, &rfds); - if (notfd > max_fd) - max_fd = notfd; - // If the process is still running we block until we - // receive data or the process exits. - p_timeout = 0; // no timeout - } else { - // If the process has already exited, we only check - // the available data, we don't wait for more. - timeout.tv_sec = timeout.tv_usec = 0; // timeout immediately - p_timeout = &timeout; - } - - int fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout); - if (fds_ready < 0) { - if (errno == EINTR) - continue; - break; - } else if (!fds_ready) - break; - - if ((communication & Stdout) && FD_ISSET(out[0], &rfds)) - slotChildOutput(out[0]); - - if ((communication & Stderr) && FD_ISSET(err[0], &rfds)) - slotChildError(err[0]); - - if (runs && FD_ISSET(notfd, &rfds)) { - runs = false; // hack: signal potential exit - return; // don't close anything, we will be called again - } - } - } - - closeStdout(); - closeStderr(); - - closePty(); -} - - - -/////////////////////////// -// CC: Class K3ShellProcess -/////////////////////////// - -K3ShellProcess::K3ShellProcess(const char *shellname): - K3Process(), d(0) -{ - setUseShell( true, shellname ? shellname : getenv("SHELL") ); -} - -K3ShellProcess::~K3ShellProcess() { -} - -QString K3ShellProcess::quote(const QString &arg) -{ - return K3Process::quote(arg); -} - -bool K3ShellProcess::start(RunMode runmode, Communication comm) -{ - return K3Process::start(runmode, comm); -} - - -//#include "moc_k3process.cpp" |