28#include <QtCore/QFile>
29#include <QtCore/QSocketNotifier>
38int KfsProcessController::s_refCount = 0;
40void KfsProcessController::ref()
49void KfsProcessController::deref()
64KfsProcessController::KfsProcessController()
72 fcntl( m_fd[0], F_SETFL, O_NONBLOCK );
73 fcntl( m_fd[1], F_SETFL, O_NONBLOCK );
74 fcntl( m_fd[0], F_SETFD, FD_CLOEXEC );
75 fcntl( m_fd[1], F_SETFD, FD_CLOEXEC );
77 m_notifier =
new QSocketNotifier( m_fd[0], QSocketNotifier::Read );
78 m_notifier->setEnabled(
true );
79 QObject::connect( m_notifier, SIGNAL(activated(
int)),
80 SLOT(slotDoHousekeeping()));
83KfsProcessController::~KfsProcessController()
90#warning FIXME: why does close() freeze up destruction?
103bool KfsProcessController::s_handlerSet = false;
105void KfsProcessController::setupHandlers()
111 struct sigaction act;
112 sigemptyset( &act.sa_mask );
114 act.sa_handler = SIG_IGN;
116 sigaction( SIGPIPE, &act, 0L );
119 act.sa_flags = SA_NOCLDSTOP;
123 act.sa_flags |= SA_RESTART;
125 sigaction( SIGCHLD, &act, &s_oldChildHandlerData );
127 sigaddset( &act.sa_mask, SIGCHLD );
129 sigprocmask( SIG_UNBLOCK, &act.sa_mask, 0 );
132void KfsProcessController::resetHandlers()
136 s_handlerSet =
false;
138 sigset_t
mask, omask;
139 sigemptyset( &mask );
140 sigaddset( &mask, SIGCHLD );
141 sigprocmask( SIG_BLOCK, &mask, &omask );
143 struct sigaction act;
144 sigaction( SIGCHLD, &s_oldChildHandlerData, &act );
146 sigaction( SIGCHLD, &act, 0 );
150 sigprocmask( SIG_SETMASK, &omask, 0 );
159 int saved_errno = errno;
162 ::write( instance()->m_fd[1], &dummy, 1 );
164 if ( s_oldChildHandlerData.sa_handler != SIG_IGN &&
165 s_oldChildHandlerData.sa_handler != SIG_DFL ) {
166 s_oldChildHandlerData.sa_handler( arg );
172void KfsProcessController::slotDoHousekeeping()
175 ::read( m_fd[0], dummy,
sizeof(dummy) );
183 if( prc->runs && waitpid( prc->pid_, 0, WNOHANG ) > 0 )
185 prc->processHasExited();
197 if( waitpid( *uit, 0, WNOHANG ) > 0 )
199 uit = m_unixProcessList.erase( uit );
206void KfsProcessController::addKProcess(
KfsProcess* p )
208 m_kProcessList.append( p );
211void KfsProcessController::removeKProcess(
KfsProcess* p )
213 m_kProcessList.removeAll( p );
216void KfsProcessController::addProcess(
int pid )
218 m_unixProcessList.append( pid );
231 KfsProcessController::ref();
232 KfsProcessController::instance()->addKProcess(
this);
237 KfsProcessController::instance()->removeKProcess(
this);
238 KfsProcessController::deref();
244 KfsProcessController::instance()->addProcess(pid_);
252 arguments.append(QByteArray(arg));
258 arguments.append(QFile::encodeName(arg));
265 kDebug(175) <<
"Attempted to start an already running process";
269 uint n = arguments.count();
271 kDebug(175) <<
"Attempted to start a process without arguments";
274 char **arglist =
static_cast<char **
>(malloc( (n + 1) *
sizeof(
char *)));
275 for (uint i = 0; i < n; i++)
276 arglist[i] = arguments[i].data();
289 fcntl(fd[1], F_SETFD, FD_CLOEXEC);
292 struct sigaction act;
293 sigemptyset(&act.sa_mask);
294 act.sa_handler = SIG_DFL;
296 for (
int sig = 1; sig < NSIG; sig++)
297 sigaction(sig, &act, 0L);
300 execvp(arglist[0], arglist);
303 write(fd[1], &resultByte, 1);
305 }
else if (pid_ == -1) {
320 int n = ::read(fd[0], &resultByte, 1);
342void KfsProcess::processHasExited()
349#include "kfsprocess.moc"
static void theSigCHLDHandler(int signal)
KfsProcess & operator<<(const QString &arg)
KfsProcess(QObject *parent=0L)
QDebug perror(QDebug s, KDebugTag)
static void theReaper(int num)
KAction * close(const QObject *recvr, const char *slot, QObject *parent)