📄 qappexec.cpp
字号:
/*************************************************************************** * Copyright (C) 2007 by Motorola Commnunity around the World * * lahu3672@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/#include "QAppExec.h"void sigchld_handler(int signum){ int status; wait(&status);}QFdManager::QFdManager(QObject *parent, const char *name):QObject(parent, name){}QFdManager::~QFdManager(){}QFdListener::QFdListener(QFdManager *m): QThread(){ this->m = m; this->started = false;}QFdListener::~QFdListener(){}void QFdListener::stop(){ started = false;}void QFdListener::run(){ if (started || !m) return; QArray<int> fds = *m->fdsToRead(); if (fds.size() == 0) return; started = true; fd_set rd; FD_ZERO(&rd); int maxfd; maxfd = fds[0]; while (started) { FD_ZERO(&rd); for (QArray<int>::ConstIterator it = fds.begin(); it != fds.end(); ++it) { if (*it > maxfd) maxfd = *it; FD_SET(*it, &rd); } if (select(maxfd+1, &rd, (fd_set*)NULL, (fd_set*)NULL, (struct timeval*)NULL)<0) continue; usleep(1000); for (QArray<int>::ConstIterator it = fds.begin(); it != fds.end(); ++it) { if (FD_ISSET(*it, &rd)) m->fdIsReady(*it); } }}QAppExec::QAppExec(const QString &path, char *const *args, QObject *parent, const char *name):QFdManager(parent, name){ struct sigaction sigchld_act; memset(&sigchld_act, 0, sizeof(sigchld_act)); sigchld_act.sa_handler = &sigchld_handler; sigaction(SIGCHLD, &sigchld_act, NULL); this->path = path; this->args = args; this->child_pid = 0; this->fdl = fdl = new QFdListener(this); this->pty = 0; this->rd = new QArray<int>(1);}QAppExec::~QAppExec(){ fdl->stop(); fdl->wait(); data.setAutoDelete(true); data.clear(); delete this->rd; delete this->fdl;}bool QAppExec::running(){ return child_pid != 0;}void QAppExec::stop(){ if (running()) { pid_t np = child_pid; child_pid = 0; fdl->stop(); kill(np, SIGTERM); usleep(100); while (kill(np, SIGKILL) != -1) usleep(100); emit stopped(); }}void QAppExec::start(){ if (running()) return; child_pid = forkpty(&pty, NULL, NULL, NULL); rd->at(0) = pty; if (child_pid == 0) { execv(path.latin1(), args); _exit(1); } else { fdl->start(); }}QArray<int> *QAppExec::fdsToRead(){ return rd;}void QAppExec::fdIsReady(int fd){ QByteArray *buf = new QByteArray(BUFSIZE); int ret = read(fd, buf->data(), BUFSIZE); buf->resize(ret); if (ret>0) { data.enqueue(buf); emit readyRead(); } else { stop(); }}uint QAppExec::size(){ if (!data.isEmpty()) { return data.head()->size(); } else return 0;}void QAppExec::readBlock(QByteArray &arr){ if (!data.isEmpty()) { QByteArray *chunk = data.dequeue(); arr.duplicate(*chunk); delete chunk; }}void QAppExec::writeBlock(const QByteArray &arr){ if (running()) { write(pty, arr.data(), arr.size()); }}void QAppExec::setSize(struct winsize *ws){ ioctl(pty, TIOCSWINSZ, ws);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -