From aa0b92c035cc0b060af4bfa9e512792884ac2dc1 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sat, 6 Apr 2013 16:57:38 -0500 Subject: Use threading and select instead of busywaiting on TDM control socket This partially resolves Bug 690 Clean up TDM logfile --- tdm/kfrontend/kfdialog.cpp | 7 +- tdm/kfrontend/kgreeter.cpp | 204 +++++++++++++++++++++++++++------------------ tdm/kfrontend/kgreeter.h | 41 ++++++++- tdm/kfrontend/sakdlg.cc | 97 ++++----------------- tdm/kfrontend/sakdlg.h | 32 ++++--- 5 files changed, 204 insertions(+), 177 deletions(-) diff --git a/tdm/kfrontend/kfdialog.cpp b/tdm/kfrontend/kfdialog.cpp index ba05b0294..47ae5759c 100644 --- a/tdm/kfrontend/kfdialog.cpp +++ b/tdm/kfrontend/kfdialog.cpp @@ -64,7 +64,12 @@ FDialog::FDialog( TQWidget *parent, bool framed ) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE); if (framed) { - if (m_wmTitle) setFixedSize(sizeHint()); + if (m_wmTitle) { + TQSize sh = sizeHint(); + if ((sh.width() > 0) && (sh.height() > 0)) { + setFixedSize(sh); + } + } } } diff --git a/tdm/kfrontend/kgreeter.cpp b/tdm/kfrontend/kgreeter.cpp index b8e2cd320..c603c54b7 100644 --- a/tdm/kfrontend/kgreeter.cpp +++ b/tdm/kfrontend/kgreeter.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "tdmconfig.h" #include "tdmclock.h" #include "tdm_greet.h" +#include "sakdlg.h" #include "tdmadmindialog.h" #include "themer/tdmthemer.h" #include "themer/tdmitem.h" @@ -180,7 +181,6 @@ KGreeter::KGreeter( bool framed ) , prevValid( true ) , needLoad( false ) , themed( framed ) - , mPipe_fd( -1 ) , closingDown( false ) { stsFile = new KSimpleConfig( _stsFile ); @@ -207,16 +207,22 @@ KGreeter::KGreeter( bool framed ) pluginList = KGVerify::init( _pluginsLogin ); } - TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); + mControlPipeHandlerThread = new TQEventLoopThread(); + mControlPipeHandler = new ControlPipeHandlerObject(); + mControlPipeHandler->mKGreeterParent = this; + mControlPipeHandler->moveToThread(mControlPipeHandlerThread); + TQObject::connect(mControlPipeHandler, SIGNAL(processCommand(TQString)), this, SLOT(processInputPipeCommand(TQString))); + TQTimer::singleShot(0, mControlPipeHandler, SLOT(run())); + mControlPipeHandlerThread->start(); } KGreeter::~KGreeter() { - if (mPipe_fd != -1) { - closingDown = true; - ::close(mPipe_fd); - ::unlink(mPipeFilename.ascii()); - } + mControlPipeHandlerThread->terminate(); + mControlPipeHandlerThread->wait(); + delete mControlPipeHandler; + delete mControlPipeHandlerThread; + hide(); delete userList; delete verify; @@ -228,71 +234,9 @@ void KGreeter::done(int r) { inherited::done(r); } -void KGreeter::handleInputPipe(void) { - if (closingDown) { - ::unlink(mPipeFilename.ascii()); - return; - } - - if (isShown() == false) { - TQTimer::singleShot( 100, this, TQT_SLOT(handleInputPipe()) ); - return; - } - - char readbuf[2048]; - int displayNumber; - TQString currentDisplay; - currentDisplay = TQString(getenv("DISPLAY")); - currentDisplay = currentDisplay.replace(":", ""); - displayNumber = currentDisplay.toInt(); - mPipeFilename = TQString(FIFO_FILE).arg(displayNumber); - ::unlink((TQString(FIFO_SAK_FILE).arg(displayNumber)).ascii()); - - /* Create the FIFOs if they do not exist */ - umask(0); - struct stat buffer; - int status; - char *fifo_parent_dir = strdup(FIFO_DIR); - dirname(fifo_parent_dir); - status = stat(fifo_parent_dir, &buffer); - if (status != 0) { - mkdir(fifo_parent_dir, 0644); - } - free(fifo_parent_dir); - status = stat(FIFO_DIR, &buffer); - if (status == 0) { - int file_mode = ((buffer.st_mode & S_IRWXU) >> 6) * 100; - file_mode = file_mode + ((buffer.st_mode & S_IRWXG) >> 3) * 10; - file_mode = file_mode + ((buffer.st_mode & S_IRWXO) >> 0) * 1; - if ((file_mode != 600) || (buffer.st_uid != 0) || (buffer.st_gid != 0)) { - ::unlink(mPipeFilename.ascii()); - printf("[WARNING] Possible security breach! Please check permissions on " FIFO_DIR " (must be 600 and owned by root/root, got %d %d/%d). Not listening for login credentials on remote control socket.\n", file_mode, buffer.st_uid, buffer.st_gid); fflush(stdout); - return; - } - } - mkdir(FIFO_DIR,0600); - mknod(mPipeFilename.ascii(), S_IFIFO|0600, 0); - chmod(mPipeFilename.ascii(), 0600); - - mPipe_fd = ::open(mPipeFilename.ascii(), O_RDONLY | O_NONBLOCK); - int numread; - TQString inputcommand = ""; - while ((!inputcommand.contains('\n')) && (!closingDown)) { - numread = ::read(mPipe_fd, readbuf, 2048); - readbuf[numread] = 0; - readbuf[2047] = 0; - inputcommand += readbuf; - if (!tqApp->hasPendingEvents()) { - usleep(500); - } - tqApp->processEvents(); - } - if (closingDown) { - ::unlink(mPipeFilename.ascii()); - return; - } - inputcommand = inputcommand.replace('\n', ""); - TQStringList commandList = TQStringList::split('\t', inputcommand, false); +void KGreeter::processInputPipeCommand(TQString command) { + command = command.replace('\n', ""); + TQStringList commandList = TQStringList::split('\t', command, false); if ((*(commandList.at(0))) == "LOGIN") { if (verify) { verify->setUser( (*(commandList.at(1))) ); @@ -300,14 +244,6 @@ void KGreeter::handleInputPipe(void) { accept(); } } - if (!closingDown) { - TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); - ::close(mPipe_fd); - ::unlink(mPipeFilename.ascii()); - } - else { - ::unlink(mPipeFilename.ascii()); - } } void KGreeter::readFacesList() @@ -1300,4 +1236,112 @@ KThemedGreeter::slotAskAdminPassword() } } +//=========================================================================== +// +// TDM control pipe handler +// +ControlPipeHandlerObject::ControlPipeHandlerObject() : TQObject() { + mPipe_fd = -1; + mKGreeterParent = NULL; + mSAKDlgParent = NULL; +} + +ControlPipeHandlerObject::~ControlPipeHandlerObject() { + if (mPipe_fd != -1) { + if (mKGreeterParent) mKGreeterParent->closingDown = true; + if (mSAKDlgParent) mSAKDlgParent->closingDown = true; + ::close(mPipe_fd); + ::unlink(mPipeFilename.ascii()); + } +} + +void ControlPipeHandlerObject::run(void) { + while (1) { + if ((mKGreeterParent && (mKGreeterParent->closingDown)) || (mSAKDlgParent && (mSAKDlgParent->closingDown))) { + ::unlink(mPipeFilename.ascii()); + return; + } + + if ((mKGreeterParent && (mKGreeterParent->isShown())) || (mSAKDlgParent && (mSAKDlgParent->isShown()))) { + char readbuf[2048]; + int displayNumber; + TQString currentDisplay; + currentDisplay = TQString(getenv("DISPLAY")); + currentDisplay = currentDisplay.replace(":", ""); + displayNumber = currentDisplay.toInt(); + if (mKGreeterParent) { + mPipeFilename = TQString(FIFO_FILE).arg(displayNumber); + ::unlink((TQString(FIFO_SAK_FILE).arg(displayNumber)).ascii()); + } + if (mSAKDlgParent) { + mPipeFilename = TQString(FIFO_SAK_FILE).arg(displayNumber); + ::unlink((TQString(FIFO_FILE).arg(displayNumber)).ascii()); + } + + /* Create the FIFOs if they do not exist */ + umask(0); + struct stat buffer; + int status; + char *fifo_parent_dir = strdup(FIFO_DIR); + dirname(fifo_parent_dir); + status = stat(fifo_parent_dir, &buffer); + if (status != 0) { + mkdir(fifo_parent_dir, 0644); + } + free(fifo_parent_dir); + status = stat(FIFO_DIR, &buffer); + if (status == 0) { + int file_mode = ((buffer.st_mode & S_IRWXU) >> 6) * 100; + file_mode = file_mode + ((buffer.st_mode & S_IRWXG) >> 3) * 10; + file_mode = file_mode + ((buffer.st_mode & S_IRWXO) >> 0) * 1; + if ((file_mode != 600) || (buffer.st_uid != 0) || (buffer.st_gid != 0)) { + ::unlink(mPipeFilename.ascii()); + printf("[WARNING] Possible security breach! Please check permissions on " FIFO_DIR " (must be 600 and owned by root/root, got %d %d/%d). Not listening for login credentials on remote control socket.\n", file_mode, buffer.st_uid, buffer.st_gid); fflush(stdout); + return; + } + } + mkdir(FIFO_DIR,0600); + mknod(mPipeFilename.ascii(), S_IFIFO|0600, 0); + chmod(mPipeFilename.ascii(), 0600); + + mPipe_fd = ::open(mPipeFilename.ascii(), O_RDONLY | O_NONBLOCK); + int numread; + int retval; + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(mPipe_fd, &rfds); + TQString inputcommand = ""; + while ((!inputcommand.contains('\n')) && ((mKGreeterParent && (!mKGreeterParent->closingDown)) || (mSAKDlgParent && (!mSAKDlgParent->closingDown)))) { + // Wait for mPipe_fd to receive input + retval = select(mPipe_fd + 1, &rfds, NULL, NULL, NULL); + if (retval < 0) { + // ERROR + } + else if (retval) { + // New data is available + numread = ::read(mPipe_fd, readbuf, 2048); + readbuf[numread] = 0; + readbuf[2047] = 0; + inputcommand += readbuf; + } + } + if ((mKGreeterParent && (mKGreeterParent->closingDown)) || (mSAKDlgParent && (mSAKDlgParent->closingDown))) { + ::unlink(mPipeFilename.ascii()); + return; + } + + emit processCommand(inputcommand); + + if ((mKGreeterParent && (!mKGreeterParent->closingDown)) || (mSAKDlgParent && (!mSAKDlgParent->closingDown))) { + ::close(mPipe_fd); + ::unlink(mPipeFilename.ascii()); + } + else { + ::unlink(mPipeFilename.ascii()); + return; + } + } + } +} + #include "kgreeter.moc" diff --git a/tdm/kfrontend/kgreeter.h b/tdm/kfrontend/kgreeter.h index 951ea7d3a..7d1c1bc6f 100644 --- a/tdm/kfrontend/kgreeter.h +++ b/tdm/kfrontend/kgreeter.h @@ -26,6 +26,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef KGREETER_H #define KGREETER_H +#include + #include "kgverify.h" #include "kgdialog.h" @@ -41,6 +43,8 @@ class TQLabel; class TQPushButton; class TQPopupMenu; class TQListViewItem; +class KGreeter; +class SAKDlg; struct SessType { TQString name, type; @@ -57,6 +61,35 @@ struct SessType { } }; +//=========================================================================== +// +// TDM control pipe handler +// +class ControlPipeHandlerObject : public TQObject +{ + Q_OBJECT + + public: + ControlPipeHandlerObject(); + ~ControlPipeHandlerObject(); + + public slots: + void run(); + + signals: + void processCommand(TQString); + + public: + KGreeter* mKGreeterParent; + SAKDlg* mSAKDlgParent; + TQString mPipeFilename; + int mPipe_fd; +}; + +//=========================================================================== +// +// TDM greeter +// class KGreeter : public KGDialog, public KGVerifyHandler { Q_OBJECT typedef KGDialog inherited; @@ -72,7 +105,7 @@ class KGreeter : public KGDialog, public KGVerifyHandler { void slotUserClicked( TQListViewItem * ); void slotSessionSelected( int ); void slotUserEntered(); - void handleInputPipe(); + void processInputPipeCommand(TQString command); public: TQString curUser, curWMSession, dName; @@ -107,8 +140,8 @@ class KGreeter : public KGDialog, public KGVerifyHandler { void slotLoadPrevWM(); private: - int mPipe_fd; - TQString mPipeFilename; + ControlPipeHandlerObject* mControlPipeHandler; + TQEventLoopThread* mControlPipeHandlerThread; protected: bool closingDown; @@ -120,6 +153,8 @@ class KGreeter : public KGDialog, public KGVerifyHandler { virtual void verifyFailed(); // virtual void verifyRetry(); virtual void verifySetUser( const TQString &user ); + + friend class ControlPipeHandlerObject; }; class KStdGreeter : public KGreeter { diff --git a/tdm/kfrontend/sakdlg.cc b/tdm/kfrontend/sakdlg.cc index b68418e15..4818c1cdd 100644 --- a/tdm/kfrontend/sakdlg.cc +++ b/tdm/kfrontend/sakdlg.cc @@ -87,7 +87,7 @@ extern bool trinity_desktop_lock_use_sak; // SAKDlg::SAKDlg(TQWidget *parent) : TQDialog(parent, "information dialog", true, (trinity_desktop_lock_use_system_modal_dialogs?((WFlags)WStyle_StaysOnTop):((WFlags)WX11BypassWM))), - mUnlockingFailed(false), mPipe_fd(-1), closingDown(false) + mUnlockingFailed(false), closingDown(false) { if (trinity_desktop_lock_use_system_modal_dialogs) { // Signal that we do not want any window controls to be shown at all @@ -130,7 +130,13 @@ SAKDlg::SAKDlg(TQWidget *parent) connect(mSAKProcess, TQT_SIGNAL(processExited(TDEProcess*)), this, TQT_SLOT(slotSAKProcessExited())); mSAKProcess->start(); - TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); + mControlPipeHandlerThread = new TQEventLoopThread(); + mControlPipeHandler = new ControlPipeHandlerObject(); + mControlPipeHandler->mSAKDlgParent = this; + mControlPipeHandler->moveToThread(mControlPipeHandlerThread); + TQObject::connect(mControlPipeHandler, SIGNAL(processCommand(TQString)), this, SLOT(processInputPipeCommand(TQString))); + TQTimer::singleShot(0, mControlPipeHandler, SLOT(run())); + mControlPipeHandlerThread->start(); } void SAKDlg::slotSAKProcessExited() @@ -141,82 +147,12 @@ void SAKDlg::slotSAKProcessExited() hide(); } -void SAKDlg::handleInputPipe(void) { - if (closingDown) { - ::unlink(mPipeFilename.ascii()); - return; - } - - if (isShown() == false) { - TQTimer::singleShot( 100, this, TQT_SLOT(handleInputPipe()) ); - return; - } - - char readbuf[2048]; - int displayNumber; - TQString currentDisplay; - currentDisplay = TQString(getenv("DISPLAY")); - currentDisplay = currentDisplay.replace(":", ""); - displayNumber = currentDisplay.toInt(); - mPipeFilename = TQString(FIFO_SAK_FILE).arg(displayNumber); - ::unlink((TQString(FIFO_FILE).arg(displayNumber)).ascii()); - - /* Create the FIFOs if they do not exist */ - umask(0); - struct stat buffer; - int status; - char *fifo_parent_dir = strdup(FIFO_DIR); - dirname(fifo_parent_dir); - status = stat(fifo_parent_dir, &buffer); - if (status != 0) { - mkdir(fifo_parent_dir, 0644); - } - free(fifo_parent_dir); - status = stat(FIFO_DIR, &buffer); - if (status == 0) { - int file_mode = ((buffer.st_mode & S_IRWXU) >> 6) * 100; - file_mode = file_mode + ((buffer.st_mode & S_IRWXG) >> 3) * 10; - file_mode = file_mode + ((buffer.st_mode & S_IRWXO) >> 0) * 1; - if ((file_mode != 600) || (buffer.st_uid != 0) || (buffer.st_gid != 0)) { - ::unlink(mPipeFilename.ascii()); - printf("[WARNING] Possible security breach! Please check permissions on " FIFO_DIR " (must be 600 and owned by root/root, got %d %d/%d). Not listening for login credentials on remote control socket.\n", file_mode, buffer.st_uid, buffer.st_gid); fflush(stdout); - return; - } - } - mkdir(FIFO_DIR,0600); - mknod(mPipeFilename.ascii(), S_IFIFO|0600, 0); - chmod(mPipeFilename.ascii(), 0600); - - mPipe_fd = ::open(mPipeFilename.ascii(), O_RDONLY | O_NONBLOCK); - int numread; - TQString inputcommand = ""; - while ((!inputcommand.contains('\n')) && (!closingDown)) { - numread = ::read(mPipe_fd, readbuf, 2048); - readbuf[numread] = 0; - readbuf[2047] = 0; - inputcommand += readbuf; - if (!tqApp->hasPendingEvents()) { - usleep(500); - } - tqApp->processEvents(); - } - if (closingDown) { - ::unlink(mPipeFilename.ascii()); - return; - } - inputcommand = inputcommand.replace('\n', ""); - TQStringList commandList = TQStringList::split('\t', inputcommand, false); +void SAKDlg::processInputPipeCommand(TQString command) { + command = command.replace('\n', ""); + TQStringList commandList = TQStringList::split('\t', command, false); if ((*(commandList.at(0))) == "CLOSE") { mSAKProcess->kill(); } - if (!closingDown) { - TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); - ::close(mPipe_fd); - ::unlink(mPipeFilename.ascii()); - } - else { - ::unlink(mPipeFilename.ascii()); - } } SAKDlg::~SAKDlg() @@ -225,11 +161,12 @@ SAKDlg::~SAKDlg() mSAKProcess->kill(SIGTERM); delete mSAKProcess; } - if (mPipe_fd != -1) { - closingDown = true; - ::close(mPipe_fd); - ::unlink(mPipeFilename.ascii()); - } + + mControlPipeHandlerThread->terminate(); + mControlPipeHandlerThread->wait(); + delete mControlPipeHandler; + delete mControlPipeHandlerThread; + hide(); } diff --git a/tdm/kfrontend/sakdlg.h b/tdm/kfrontend/sakdlg.h index cb4dcec05..22d5ec869 100644 --- a/tdm/kfrontend/sakdlg.h +++ b/tdm/kfrontend/sakdlg.h @@ -8,16 +8,20 @@ #ifndef __SAKDLG_H__ #define __SAKDLG_H__ +#include #include #include #include +#include "kgreeter.h" + class TQFrame; class TQGridLayout; class TQLabel; class KPushButton; class TQListView; +class SAKDlg; //=========================================================================== // @@ -38,26 +42,28 @@ public: private slots: void slotSAKProcessExited(); - void handleInputPipe(); + void processInputPipeCommand(TQString command); protected slots: virtual void reject(); private: - TQFrame *frame; - TQGridLayout *frameLayout; - TQLabel *mStatusLabel; - int mCapsLocked; - bool mUnlockingFailed; - TQStringList layoutsList; - TQStringList::iterator currLayout; - int sPid, sFd; - TDEProcess* mSAKProcess; - int mPipe_fd; - TQString mPipeFilename; + TQFrame *frame; + TQGridLayout *frameLayout; + TQLabel *mStatusLabel; + int mCapsLocked; + bool mUnlockingFailed; + TQStringList layoutsList; + TQStringList::iterator currLayout; + int sPid, sFd; + TDEProcess* mSAKProcess; + ControlPipeHandlerObject* mControlPipeHandler; + TQEventLoopThread* mControlPipeHandlerThread; protected: - bool closingDown; + bool closingDown; + + friend class ControlPipeHandlerObject; }; #endif -- cgit v1.2.3