broken KProcess in HEAD
Oswald Buddenhagen
ossi at kde.org
Sat Jul 19 15:20:26 BST 2003
On Fri, Jul 18, 2003 at 11:21:05AM +0100, Gav Wood wrote:
> KProcess appears to have been broken in HEAD fairly recently.
>
#define fairly recently
my last changes were several months ago ...
> when built under HEAD, the command often finishes without KProcess
> signalling processExited(...); a quick ps shows that the command is
> zombified.
>
hmm, strange.
please apply the attached patch and report the messages. you may want to
add more qDebug()s if the output is non-conclusive and you want to dive
deeper into it.
> it seems that the longer the process takes to execute the more chance
> of KProcess failing.
>
even stranger ...
fwiw, we're talking about kopete/protocols/sms/services/smsclient.cpp,
right? a few notes then ...
- connecting to processExited for a blocking process is relatively
pointless. you can call the relevant functions after start() returns.
i plan to make kprocess not emit this signal for blocking processes
any more in kde 4.
- the way you collect output is relatively broken. you fromLocal8Bit
every chunk separately - this will break if the program emits lots of
utf8. you have to accumulate first and then do the conversion and split
the lines.
another thing i dislike is the fact, that stdin and stdout are
different handles but are collected into the same buffer. this can
potentially lead to oddly multiplexed contents ... anyway, kprocio
makes the same mistake - i think i'll have to take care of this.
- you are leaking the kprocess
- wth is QString("%1:%2").arg("SMSClient").arg("ProviderName") supposed
to be good for? i can hardly think of a more complicated way to code
it ... ;)
greetings
--
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
--
Chaos, panic, and disorder - my work here is done.
-------------- next part --------------
Index: kprocess.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kprocess.cpp,v
retrieving revision 1.125
diff -u -r1.125 kprocess.cpp
--- kprocess.cpp 16 Jul 2003 20:58:22 -0000 1.125
+++ kprocess.cpp 19 Jul 2003 14:17:49 -0000
@@ -958,7 +958,9 @@
{
closeStdin();
+qDebug("commClose()");
if (pid_) { // detached, failed, and killed processes have no output. basta. :)
+qDebug(" commClose(): need to drain handles");
// 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.
@@ -966,6 +968,7 @@
int notfd = KProcessController::theKProcessController->notifierFd();
while ((communication & (Stdout | Stderr)) || runs) {
+qDebug(" commClose(): draining loop iteration");
fd_set rfds;
FD_ZERO(&rfds);
struct timeval timeout, *p_timeout;
@@ -997,18 +1000,25 @@
int fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout);
if (fds_ready < 0) {
if (errno == EINTR)
+{ qDebug(" commClose(): draining loop interrupted");
continue;
+}
break;
} else if (!fds_ready)
break;
if ((communication & Stdout) && FD_ISSET(out[0], &rfds))
+{ qDebug(" commClose(): stdout");
slotChildOutput(out[0]);
+}
if ((communication & Stderr) && FD_ISSET(err[0], &rfds))
+{ qDebug(" commClose(): stderr");
slotChildError(err[0]);
+}
if (runs && FD_ISSET(notfd, &rfds)) {
+ qDebug(" commClose(): some process exited, returning");
runs = false; // hack: signal potential exit
return; // don't close anything, we will be called again
}
@@ -1019,6 +1029,7 @@
closeStderr();
closePty();
+qDebug("commClose(): normal exit");
}
Index: kprocctrl.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kprocctrl.cpp,v
retrieving revision 1.57
diff -u -r1.57 kprocctrl.cpp
--- kprocctrl.cpp 8 Feb 2003 19:27:12 -0000 1.57
+++ kprocctrl.cpp 19 Jul 2003 14:17:49 -0000
@@ -132,6 +132,7 @@
{
int saved_errno = errno;
+qDebug("kprocctrl: received SIGCHLD");
char dummy = 0;
::write( theKProcessController->fd[1], &dummy, 1 );
@@ -151,7 +152,10 @@
{
char dummy[16]; // somewhat bigger - just in case several have queued up
if( ::read( fd[0], dummy, sizeof(dummy) ) > 0 )
+{ qDebug("kprocctrl: unscheduled check");
needcheck = true;
+} else
+ qDebug("kprocctrl: unscheduling check unnecessary");
}
void
@@ -162,13 +166,17 @@
needcheck = false;
char dummy = 0;
::write( fd[1], &dummy, 1 );
+ qDebug("kprocctrl: rescheduled check");
}
+ else
+ qDebug("kprocctrl: rescheduling check unnecessary");
}
void KProcessController::slotDoHousekeeping()
{
char dummy[16]; // somewhat bigger - just in case several have queued up
::read( fd[0], dummy, sizeof(dummy) );
+ qDebug("kprocctrl: doing housekeeping");
int status;
again:
More information about the kde-core-devel
mailing list